一、傳統複製切換爲GTID複製
主/從庫執行
1.SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
持續觀察MySQL錯誤日誌一段時間,看是否有違反gtid 一致性的報錯,像create table ... select 的語句是不支持的。這個時候只能做業務上的調整來滿足gtid 一致性的要求,只有語句都滿足了,才能繼續進行一下步。
主/從庫執行
2.SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
主/從庫執行
3.SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
新產生是匿名事務,slave可以識別匿名事務和gtid事務
主/從庫執行
4.SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
新產生是gtid事務,slave可以識別匿名事務和gtid事務,到這一步要確保沒有匿名事務產生了再進行下一步的操作,查看方法爲:
SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
當值爲0就表示可以進行一下操作了。
主/從庫執行
5.SET @@GLOBAL.GTID_MODE = ON;
新產生是gtid事務,slave只識別gtid事務,這一步執行完主/從就都開啓了gtid了。要想配置重啓繼續生效,將兩個參數寫入MySQL的配置文件中:
enforce_gtid_consistency=on
gtid_mode=on
從庫執行
STOP SLAVE [FOR CHANNEL 'channel'];
CHANGE MASTER TO MASTER_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
START SLAVE [FOR CHANNEL 'channel'];
二、GTID複製切換爲傳統複製
從庫執行
1. STOP SLAVE [FOR CHANNEL 'channel'];
等待完這步後,需要查看當前slave讀取的文件及位置,傳統複製需要基於這兩個值繼續同步。查看方法就是查看show slave status\G中的兩個參數:
Relay_Master_Log_File:file #表示 sql_thread已經應用到了哪個文件
Exec_Master_Log_Pos:position #表示 sql_thread已經執行到了文件的哪個位置
2.CHANGE MASTER TO MASTER_AUTO_POSITION = 0, MASTER_LOG_FILE = file, \
MASTER_LOG_POS = position [FOR CHANNEL 'channel'];
3.START SLAVE [FOR CHANNEL 'channel'];
主從庫執行
4.SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;.
主從庫執行
5.SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
執行完這步後需要確認沒有新gtid事務產生
官方文檔上的方法:SELECT @@GLOBAL.GTID_OWNED;只要確保主從上有一個值爲空就行。
另外也可以根據從上的兩個參數是否不再更新來判斷:
Retrieved_Gtid_Set: #已經獲取到的gtid集合
Executed_Gtid_Set: #已經執行了的gtid集合
主從庫執行
6.SET @@GLOBAL.GTID_MODE = OFF;
主從庫執行
7.將配置寫入配置文件
enforce_gtid_consistency=off
gtid_mode=off
三、基於GTID複製怎麼跳過一個事務
基於GTID的複製無法使用sql_slave_skip_counter跳過錯誤,可以利用替換空事務的方法來處理。
從庫執行:
1.停止slave,並注入空事務
STOP SLAVE [FOR CHANNEL 'channel'];
SET GTID_NEXT='aaa-bbb-ccc-ddd:N'; #需要跳過的事務的gtid
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';
START SLAVE [FOR CHANNEL 'channel'];
從庫執行
2.刷新並清理binlog文件
FLUSH LOGS; #會生成一個新的binlog文件
PURGE BINARY LOGS TO 'master-bin.00000N'; #N表是最新的binlog文件
這麼做的用意在於防止將來slave提升爲master的時候這個問題事務繼續傳播。
四、基於GTID複製,將slave切換爲Master
1.確保主上不再有數據更新
flush table with read lock; #會話級的,斷開會話就失效了。
或
set global read_only=1; #重啓失效
set global super_read_only=1
2.檢查主從是否完全同步了
Master:show master status\G;
Slave:show slave status\G;
3.從庫(新的主庫)
STOP SLAVE;
RESET SLAVE ALL;
4.主庫(新的從庫)
CHANGE MASTER TO MASTER_AUTO_POSITION = 0, MASTER_LOG_FILE = file, \
MASTER_LOG_POS = position [FOR CHANNEL 'channel'];
寫在最後:
本文只是基於官方文檔及自己在用的過程的一些總結,英文好的可以直接去看官方文檔。如果寫的有錯的地方也歡迎吐槽。基於Gtid的複製維護起來還是很方便的,不再需要關心binlog file及position了。slave會向Master上報它已經執行的gtid,Master會將剩餘的gtid發給Slave去執行。爲了防止在從上誤操作導致主從的數據不一致,從最好還是設置爲只讀,在Slave的配置文件中加入兩個參數:
super_read_only=1
read_only=1