存在問題
主從複製架構多次出現複製停滯問題如1032錯誤和1062錯誤,其中,1032錯誤是在主庫成功執行後在從庫update或delete時發現從庫上找不到這筆記錄,1062錯誤是在主庫insert完成後在從庫執行時出現主鍵衝突無法成功insert,這些問題可透過跳過錯誤和前面的複製資料校驗修復來解決,但是這些問題產生的直接原因是主從庫資料不一致。這種不一致除了邏輯複製本身可能出現的資料不一致,還有個原因是業務側或開發人員違規在備庫上直接進行增刪改操作導致的。
在主從複製架構中,主從庫透過VIP綁定實現指定庫作為主庫,提供讀寫,從庫起backup的作用,當主庫出現問題時,VIP切換到從庫,從庫提供讀寫,否則從庫只是backup。正常情況下,我們不允許開發人員直接透過固定IP登入從庫操作,但實際工作中往往又難以規避,那麼如何從技術角度去避免開發人員在備庫操作呢?又如何在避免的同時不影響高可用架構的正常運作和故障切換呢?
2.架構配置最佳化
(1)直接解決方法
解決上述問題的直接方法是考慮進行架構配置最佳化,即將從庫可讀寫的狀態配置為唯讀狀態。
MySQL官網關於只讀有下列描述:
1.Whenthe read_only system variable is enabled, the server permits no client updatesexcept from users who have the SUPER privilege. 只读情况下,super权限可读写。 2.Updates performed by slave threads, if theserver is a replication slave. In replication setups, it can be useful toenable read_only on slave servers to ensure that slaves accept updates only from themaster server and not from clients. 不影响主从复制线程的读写。
開啟只讀後,除了super權限帳戶和複製執行緒等不受影響外,業務側開發人員和其它人員即使登入備庫也無法操作備庫資料。
MySQL [db1]> show global variables like'read_only%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | read_only | ON | +---------------+-------+ 1 row in set (0.00 sec) MySQL [test]> insert child values('1','12'); ERROR 1290 (HY000): The MySQL server is running withthe --read-only option so it cannot execute thisstatement
(2)設定為只讀後如何進行完美故障切換?
從庫只讀可避免違規操作,但面臨的問題是如果主庫發生問題,VIP要切換到從庫上,但那時從庫只讀會導致資料庫對外服務不可用,因此在切換時需要實現取消從庫只讀同時設定主庫只讀的功能。
以Keepalived+MySQL雙主(主從)架構為例,正常運作時,VIP在Master1上,Master1為可讀寫狀態,Master2為readonly狀態,一旦Master1發生問題,VIP要自動切換至Master2,切換前要完成兩個步驟:1.將Master1置為readonly;2.取消Master2的readonly。
3.自動化實現思路
對於一主一從架構,故障切換需要手工進行,因此上述兩步也可以手工操作;但Keepalived+MySQL雙主(主從)架構中,已實現故障的自動監測操作和VIP自動切換,上述兩個步驟也應該植入腳本中自動化。
我們主要需在自動監控和切換腳本中植入對資料庫開啟readonly和關閉readonly的函數,主要寫入語句“set global read_only=ON”和“set globalread_only=OFF”,同時注意在設定狀態之前先判斷現有狀態,shell呼叫語句「show variables like 'read_only';」得到讀寫狀態,確認讀寫狀態後再設定readonly參數為所需狀態即可,注意這些狀態設定的觸發自訂在監控到故障並執行切換之前。
上述思路現已完成自動化轉換,親測成功,說明思路正確。
以上就是主從複製問題引起的架構優化思考的內容,更多相關內容請關注PHP中文網(www.php.cn)!