Intro
這篇原是寫在Percona XtraDB Cluster的情境,但大多數情況可以套用在MySQL+Galera組合,不管來自Codership, MariaDB Galera Cluster或你自己的build。目前經過筆者的測試,在MariaDB Galera Cluster是符合的。
假設cluster中,有節點A, B, C。模擬在不同節點停止的情境下,如何修復正常。(圖片請參閱原文)
情境1
節點A正常停止。
像是為了系統維護或是更改環境設定等等,此時正常關掉節點A。在這情況下,其他節點會收到通知,因此會自動更新設定值,如cluster大 小,quorum的計算方式等等。一旦我們重啟節點A, 就會自動加入回cluster。這新加入的節點會等資料都同步完成後才開始服務。
同步方式:由writeset cache(gcache.size)資料決定,若要同步的資料都在此cache中,則會執行IST(Incremental State Transfers),較輕量且快速。若不是,則會執行SST(State Snapshot Transfer),將完整的binary data snapshot複製到節點A。
情境2
節點A, B正常停止。
此時cluster大小為1。此時節點C為primary component,可以正常服務。要將其他節點加入回cluster,就只要重啟即可。
同步方式:
節點C切換至 "Donor/Desynced" 模式,提供最後的狀態給第一個加入節點 (State Transfer)。有些負載平衡器 (Load Balancer) 會移除Donor模式的節點,所以應避免一個節點的情況。
重啟A, B節點時,由於gcache可能還存在該機器中,為了避免節點B使用到節點A的gcache,需設定這兩台的Donor為節點C
service mysql start --wsrep_sst_donor=nodeC
情境3
節點A, B, C正常停止。
這時候Cluster已經失效,所有節點已經停止,需要重新啟動Cluster。重新啟動需要由最後關機的機器開始,確保資料的完整性。從grastate.dat檔案可以得知,比較seqno,最大者的為最後關機的機器。
使用下列指令啟動Cluster
service mysql start --wsrep_new_cluster
或是
service mysql start --wsrep-cluster-address="gcomm://"
當第一台開啟完成,新的Cluster已經產生,其他機器便可直接啟動,只要確定wsrep-cluster-address含有第一台或是已經加入Cluster的機器位址,即可加入。
情境4
節點A消失。(這裏指的可能是停電,硬體損毀,mysqld掛點,系統Kernel掛點等可能性)
此情況下,節點B與C會試著與A連線,經過一小段時間發生timout,確定節點A已經消失,即將它移除Cluster。
同時更新Quorum,剩下兩個點2/3 > 1/2,所以系統正常運作。
節點A重開後即可自行加入Cluster。
情境5
節點A與B消失。
由於只剩下節點C還活著,Quorum計算 1/3 < 1/2,所以節點C會進入 non-primary 狀態,會停止系統服務。一旦節點進去 non-primary 狀態,所有 SQL Query 都無法執行。
修復方式:
有兩種。
-
第一種較為簡單,即是等待其他節點恢復運作,此情況下,恢復運作的節點將加入節點C,Cluster將自動重新形成,節點C也回到 primary 狀態。
-
第二種方式,若要捨去節點A, B(可能因為損毀無法立刻回來),單獨使節點C運作,進去MySQL Prompt輸入下列指令。此方法必須確認其他節點並沒有同時在服務,否則會造成資料不同步。
SET GLOBAL wsrep_provider_options='pc.bootstrap=true';
情境6
節點皆消失。
在這情況下,要找出最後消失的節點,從該節點啟動Cluster,確保資料的完整性。Galera versions (3.6+?) 之後會自動透過gvwstate.dat,找到最後消失的節點,並且做完修復 primary component 的動作。
同步方式:
正常重啟Cluster即可。
情境7
最後一個情境是偶數數量的節點,分成兩部分彼此無法連線。
像是三個節點在本地端另外三個在資料中心,當其中的Switch停電失去作用的話,當導致彼此都進入大腦分離的狀態,類似情境5的情況 3/6 = 1/2 無法決定 primary component ,因此兩邊都為 non-primary ,設定 bootstrap 可解決
SET GLOBAL wsrep_provider_options='pc.bootstrap=true';
注意:此設定不可以同時在兩邊 non-primary ,會造成兩邊各自形成一個新的Cluster,即使中間連線恢復了也不會重新合併一個。此情況會持續到一邊關機重啟根據設定檔 gcomm 加入另一邊的Cluster為止。
本篇參考來源: 原文