一、介紹
作爲pg_rewind報錯章節補充一個用例,說明其用法。
二、實例
1、history文件
--新主
$ 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
2、查找分叉點
說明: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/1F000090
3、此時ControlFile_target.checkPoint < divergerec && target的chkptendrec!=divergerec,所以可以進行pg_rewind
4、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/%X
三、小結
這裏pg_rewind執行時,判斷不出來沒有分叉的情景,即本文的場景。此時執行pg_rewind會報錯,讓用戶還以爲WAL文件由損壞導致執行pg_rewind失敗。這個工具如果能夠將這種場景識別出來,報不需要rewind是不是更好?
四、pg_rewind原理及報錯流程分析參考
https://blog.51cto.com/yanzongshuai/2368285
https://blog.51cto.com/yanzongshuai/2334303