存在問題
?
主從復制架構多次出現復制停滯問題如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)!