1、介绍ide
做为pg_rewind报错章节补充一个用例,说明其用法。工具
2、实例指针
一、history文件code
--新主 $ cat 00000004.history 1 0/140000C8 no recovery target specified 2 0/19000060 no recovery target specified 3 0/1F000090 no recovery target specified --老主 $ cat 00000003.history 1 0/140000C8 no recovery target specified 2 0/19000060 no recovery target specified
二、查找分叉点
说明:findCommonAncestorTimeline:
1)比较sourceHistory[0]、targetHistory[0]的时间线和begin的值,能够得出二者相等,则转到第2个条目的比较
2)比较sourceHistory[1]、targetHistory[1]的时间线和begin的值,能够得出二者相等,则转到第3个条目的比较
3)比较sourceHistory[2]、targetHistory[2]的时间线和begin的值,能够得出二者相等,此时比较结束
4)取第3个条目进行返回:MinXLogRecPtr(sourceHistory[i].end, targetHistory[i].end),此时返回的是sourceHistory[i].end的值做为分叉点,即 0/1F000090blog
三、此时ControlFile_target.checkPoint < divergerec && target的chkptendrec!=divergerec,因此能够进行pg_rewindci
四、findLastCheckpoint查找分叉点divergerec以前最近的checkpoint做为rewind起点。
1)首先须要定位到分叉点divergerec开始的记录,而后根据该记录的xl_prev指针定位前一个wal记录
2)判断第1)步获得的wal记录是不是checkpoint,若是不是则从新返回到第1),直到找到checkpoint点
3)这里就有个问题,若是获得的分叉点正好是老主结束位置,即本例:1F000090为分叉点,其实是老主和新主没有发生数据分叉,能够认为是没有做为备没有接收完新主数据呢
4)target从1F000090这个位置开始获取prev指针向前找checkpoint时,由于这个位置后都是0了,因此不能继续向下遍历找了,报错:could not find previous WAL record at %X/%Xget
3、小结it
这里pg_rewind执行时,判断不出来没有分叉的情景,即本文的场景。此时执行pg_rewind会报错,让用户还觉得WAL文件由损坏致使执行pg_rewind失败。这个工具若是可以将这种场景识别出来,报不须要rewind是否是更好?io
4、pg_rewind原理及报错流程分析参考ast
http://www.javashuo.com/article/p-ptcsdjjs-hn.html
http://www.javashuo.com/article/p-flgmqpqr-cs.html