mysql auto position_MHA-Failover(GTID,Auto_Position=0)
最近一位同學遇到的案例:凌晨數據庫意外宕機,要求在一主兩從的基礎上,搭建MHA做故障切換。在部署測試中遇到一些問題找到我,交流的過程挖出一些之前忽略的坑,感謝這位同學無私分享!
? GTID環境,KILL主庫,新主庫和從庫丟失數據(之前已知)
? 在數據庫進程掛掉、數據庫服務器關機或重啟、開啟防火墻、關閉網絡服務等狀況下,測試MHA是否正常切換(之前沒考慮腦裂問題)
? 線上部分環境GTID,Auto_Position=0,故障切換會變成GTID,Auto_Position=1(之前沒考慮)
? 梳理故障切換流程(之前梳理)
一、GTID環境,KILL主庫,新主庫和從庫丟失數據
需在配置文件將Master/Binlog Server配置到[binlogN],才能補全Dead Master上的差異數據,否則只應用到Latest Slave
發散:[binlogN]指定到Binlog Server,kill -9 master_mysqld,MHA是從Binlog Server上獲取還是從Dead Master上獲取差異binlog?
指定到Binlog Server就從Binlog Server上獲取,指定到Dead Master就到Dead Master獲取;如果沒有指定,就不會補全差異數據
二、MHA切換測試
在數據庫進程掛掉,數據庫服務器關機或重啟、開啟防火墻、關閉網絡服務等狀況下,測試MHA是否正常切換
MySQL5.7.21,基于Row+Gtid搭建的一主兩從復制結構:Master132->{Slave133、Slave134};VIP在132上,mha-manager 0.56在134上
測試場景
XX.132
XX.133
XX.134
說明
132:kill -9 mysqld
不可用
主
從
MHA正常切換,數據不丟失
132:關閉或重啟132服務器
不可用
主
從
MHA正常切換,數據可能丟失
134:iptables -I INPUT -s XX.132 -j DROP
可用
主
從
MHA正常切換,原主庫正常訪問,133成為新主庫,132和133同時存在VIP
132:service network stop/ifconfig eth0 down
不可用
主
從
MHA正常切換,數據可能丟失
注:上述表格是配置[binlogN]指定到Binlog Server,沒有指定secondary_check_script的測試結果
關閉數據庫服務器,數據可能丟失的原因:Binlog Server是異步,高并發下binlog延遲可以理解
開啟防火墻,模擬主庫與mha-manager不通訊,出現腦裂。配置文件添加"secondary_check_script=masterha_secondary_check -s remote_host1 -s remote_host2",remote_host1、remote_host2盡量與mha-manager、MySQL Server處于不同網段
三、GTID,Auto_Position=0,故障切換變成GTID,Auto_Position=1
3.1、Auto_Position
線上部分環境GTID,Auto_Position=0,故障切換會變成GTID,Auto_Position=1
? 有何風險
如果S1從庫的GTIDs存在空洞,S2從庫的GTIDs正常,隨著時間推移,S2將S1上GTIDs空洞對應的binlog刪除。此時發生故障切換,且選擇S2做為新Master,在S1 change master to S2 master_auto_position=1會報錯
Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
View Code
從庫存在GTIDs空洞可能會導致切換異常:VIP正常切換,新主可用,新從到新主之間的復制報錯,只有修復主從報錯,才會做后續操作(new master cleanup、Failover Report、send mail)
? 為何不直接修改為GTID,Auto_Position=1
Slave GTIDs
Slave GTIDs>Master GTIDs,5.7下主從直接報錯
? 如何解決
修改源碼~~~
shell> vim /usr/share/perl5/vendor_perl/MHA/ServerManager.pm1550 return 1 if ( $_->{use_gtid_auto_pos} );-->修改為1550 #return 1 if ( $_->{use_gtid_auto_pos} );
shell> vim /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm367 if ( !$_server_manager->is_gtid_auto_pos_enabled() ) {368 $log->info("GTID (with auto-pos) is not supported");-->修改為367 if ( $_server_manager->is_gtid_auto_pos_enabled() !=1) {368 $log->info("GTID (with auto-pos) is not supported");
View Code
為啥這樣修改表示看不懂,感謝順子(另一位同學)分享~
注意:傳統復制(gtid_mode=off),MHA不會利用Binlog Server補全差異數據(又是一個坑●-●)
Binlog Server
Starting from MHA version 0.56, MHA supports new section [binlogN]. In binlog section, you can define mysqlbinlog streaming servers. When MHA does GTID based failover, MHA checks binlog servers, and if binlog servers are ahead of other slaves, MHA applies differential binlog events to the new master before recovery. When MHA does non-GTID based (traditional) failover, MHA ignores binlog servers.
3.2、什么情況會出現GTID空洞
1、從庫暫停Slave Thread->主庫寫數據->主庫flush log、purge log->從庫啟動Slave Thread->報錯,缺失binary log
手工執行change master_auto_position=0;change binlog file & pos;
2、搭建復制時change master_auto_position=0;->復制過程暫停Slave Thread->change new_file & new_pos->從庫啟動Slave Thread
master_auto_position=1,Slave連接Master時,會把Executed_Gtid_Set中的GTIDs發給Master,Master會跳過Executed_Gtid_Set,把沒有執行過的GTIDs發送給Slave
情況1:再次change master_auto_position=1;它依舊會去查找那些被purge的binlog,然后拋出錯誤
情況2:再次change master_auto_position=1;只要主上對應binlog沒被purge,它能自動將空洞GTID補全
前提:Master沒有對GTIDs空洞相應的記錄進行DML操作,不然復制早就報錯了,可能就錯過這個坑~不過仔細想想,從庫本來就有空洞,復制也沒報錯,側面反映Master沒有對GTIDs空洞相應的記錄進行DML操作
擴展閱讀:[MySQL FAQ]系列 — 5.6版本GTID復制異常處理一例
3.3、relay-log是如何獲取及應用
Slave GTIDs>Master GTIDs,relay-log是如何獲取及應用
? GTID,auto_position=0Master
Executed_Gtid_Set:90b30799-9215-11e7-8645-000c29c1025c:1-14Slave
set global Gtid_Purged='90b30799-9215-11e7-8645-000c29c1025c:1-6:8-24';-->Master寫入一條數據
Master
Executed_Gtid_Set:90b30799-9215-11e7-8645-000c29c1025c:1-15Slave
Retrieved_Gtid_Set: 90b30799-9215-11e7-8645-000c29c1025c:15Executed_Gtid_Set: 90b30799-9215-11e7-8645-000c29c1025c:1-6:8-24
View Code
新寫入的binlog會寫到從庫的relay-log,但是不會應用(可以通過查看數據、解析日志確認)!
? GTID,auto_position=1change master to master_auto_position=1;
啟動復制報錯
Last_IO_Error: Got fatal error1236 from master when reading data from binary log: Slave has more GTIDs than the master has, using the master`s SERVER_UUID. This may indicate that the end of the binary log was truncated or that the last binary log file was lost, e.g., after a power or disk failure when sync_binlog != 1. The master may or may not have rolled back transactions that were already replica
View Code
relay-log獲取
Auto_Position=0,如果開啟relay-log自動修復機制,發生crash時根據relay_log_info中記錄的已執行的binlog位置從master上重新獲取寫入relay-log
Auto_Position=1,Slave連接Master時,會把Executed_Gtid_Set中的GTIDs發給Master,Master會跳過Executed_Gtid_Set,把沒有執行過的GTIDs發送給Slave。如果Slave上的GTIDs大于Master上的GTIDs,5.7下直接報錯,5.6下不會報錯(有環境的自行驗證,順便看看relay-log會不會有記錄寫入)
relay-log應用
如果relay-log中的GTIDs包含在Executed_Gtid_Set里,則不會apply-log
四、故障切換流程
MHA在傳統復制和GTID復制下,主庫發生故障,如何選舉New Master,如何修復差異數據
詳細流程請參考:MHA-手動Failover流程(傳統復制>ID復制)
總結
以上是生活随笔為你收集整理的mysql auto position_MHA-Failover(GTID,Auto_Position=0)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hibernate mysql 映射_H
- 下一篇: mysql freebuf_浅析mysq