最近也做了很多關於集羣方面的測試,但是公司又有這樣一個需求:
當集羣搭建好後,如果主節點意外死亡,我們希望從節點能夠當做主節點重新啓動,這樣不影響客戶端的操作,或者只受短時間影響。
此時的我,有種蛋蛋的憂傷,“對於程序員,需求神馬的最討厭了”。無奈之下看了原理,並做了基礎測試。
本文來自:http://blog.csdn.net/lengzijian/article/details/7736961
在之前我們模擬過集羣遇到的幾種狀況,其中有一種,當客戶端發送數據時,強行kill掉主庫所有進程,導致主庫和從庫的數據不同步,但是當重啓主庫後,從庫會拉數據回來,之後同步數據。(http://blog.csdn.net/lengzijian/article/details/7729380)
問題就在於如果主庫不啓動,我們如何同步數據?
在分析了原理後,發現主庫進程中有這樣一個進程
wal sender process postgres192.168.30.199(33121) streaming 0/424993E0
聽名字就像是專門服務發送wal日誌的進程,並且後面寫出了從庫的ip,這使得我非常確認它是負責主庫和從庫的數據同步的。
之後我冒出了一個想法:自己傳輸wal日誌。查看是否能夠達到預期的效果。
1. 先搭建hotstandy集羣,這次只用一主一從;
2. 運行插入數據庫腳本:1個線程100000數據;
腳本和用法在http://blog.csdn.net/lengzijian/article/details/7729465中提供
3. kill-9掉主庫所有postgress進程;
查看插入腳本報錯信息:
文中16586爲插入失敗的位置;
查看從庫數據量:
關鍵時刻開始
4. 查看從庫xlog文件夾
5. 查看主庫xlog文件夾
6. 查看主庫xlog/archive_status文件夾
7. 發現xxx41號文件已經處理完成,xxx42號文件還未處理完成,那麼我們對比從庫xlog文件可以認爲42號尚在傳輸過程中被終端,再看從庫的43和44的時間不符和邏輯可以直接刪除。我們可以直接把主庫的42號文件複製到從庫裏。
刪除從庫無用數據
複製主庫42號文件到從庫
8. 查看從庫數據量:
9. 可以看到與之前的錯誤日誌數字相符(可能有同學會注意到,相差1個數,主要原因可能是插入成功後,斷開連接報錯,這裏本人做了不下3次的試驗,結果均正常)
10. 啓動主庫查看數據是否同步:主庫的數據量如下
11. 可以看到與之前回復的數據總量一樣,oh~~~~~開心,有些人可能要噴本人了,因爲懂原理之後,這些都是正常情況!!本人的態度正如本片文章標題一樣,寧可去做十幾遍的嘗試,要不想要小概率的時間發生在我的服務器上(簡稱:“蛋疼”)。
這裏需要注意的是:
如何判斷那些xlog文檔是已經同步過的,那些事沒有同步的?
這裏寫下我多次測試後的經驗,在主庫的xlog/archive_status中,帶.done後綴的文件僅表示主庫中已經歸檔完成的,不代表已經發送給從庫的;在從庫中存在一些混淆的日誌文件,例如之前我們刪掉的43和44,判斷無效的依據是根據時間和文件名,有些文件明顯不是剛剛操作過的。刪掉了混淆的文件後便可以恢復編號最大的文件了(如果怕錯誤,也可以多恢復一些文件)。如果實在不懂,可以聯繫本人
有了如上經驗,我們可以自己寫腳本拉數據,並且啓動從節點爲主節點方式(目前是本人推測,還未真實實驗),如果有任何疑問或者本文中存在錯誤,可以隨時聯繫本人O(∩_∩)O哈哈~。