#################################################
聲明:在線開啟gtid是有掛庫風險的:因為我和同事均遇到過。
#################################################
主庫:192.168.225.128:3307
從庫1:192.168.225.129:3307
Gtid作為5.6版本以來的殺手級特性,卻因為不支持拓撲結構內開關而飽受詬病。如果你需要從未開啟GTID的環境升級到開啟GTID,需要把這個復制結構里的實例shutdown后,再重啟。相信這對於任何24小時服務的互聯網應用都是不可接受的。
https://blog.csdn.net/wanbin6470398/article/details/83068044#15__88
master_auto_position=0 表示禁用master_auto_position

SET @@global.enforce_gtid_consistency=warn; SET @@global.enforce_gtid_consistency=ON; SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE; SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; SELECT MASTER_POS_WAIT('mysql-bin6.000006', 154); SET @@GLOBAL.GTID_MODE = ON; STOP SLAVE; CHANGE MASTER TO master_auto_position=1; START SLAVE;
OFF
|
徹底關閉GTID,如果關閉狀態的備庫接受到帶GTID的事務,則復制中斷
|
OFF_PERMISSIVE
|
可以認為是關閉GTID前的過渡階段,主庫在設置成該值后不再生成GTID,備庫在接受到帶GTID 和不帶GTID的事務都可以容忍
主庫在關閉GTID時,執行事務會產生一個Anonymous_Gtid事件,會在備庫執行:
SET @@SESSION.GTID_NEXT= ‘ANONYMOUS’
備庫在執行匿名事務時,就不會去嘗試生成本地GTID了
|
ON_PERMISSIVE
|
可以認為是打開GTID前的過渡階段,主庫在設置成該值后會產生GTID,同時備庫依然容忍帶GTID和不帶GTID的事務
|
ON
|
完全打開GTID,如果打開狀態的備庫接受到不帶GTID的事務,則復制中斷
|
主從復制傳統復制已配置完畢
一、前提:
1.要求所有的mysql版本5.7.6或更高的版本。 2.目前拓撲結構中所有的mysql的gtid_mode的值為off狀態。 3.如下的操作步驟都是有序的,不要跳躍着進行。
補充一下全局系統變量GTID_MODE變量值說明:
OFF 新事務是非GTID, Slave只接受不帶GTID的事務,傳送來GTID的事務會報錯 OFF_PERMISSIVE 新事務是非GTID, Slave即接受不帶GTID的事務也接受帶GTID的事務 ON_PERMISSIVE 新事務是GTID, Slave即接受不帶GTID的事務也接受帶GTID的事務 ON 新事務是GTID, Slave只接受帶GTID的事務
需要注意的是,這幾個值的改變是有順序的,即
off<--->OFF_PERMISSIVE<--->ON_PERMISSIVE<--->ON
不能跳躍執行,會報錯。
二、傳統復制切換為GTID復制
前提:測試步驟中S1默認都是打開log-bin選項的,
操作步驟
1. 在M、S實例上,將ENFORCE_GTID_CONSISTENCY設置為warning,哪台先執行不影響結果
M:mysql> set @@global.enforce_gtid_consistency=warn; S:mysql> set @@global.enforce_gtid_consistency=warn;
注意:執行完這條語句后,如果出現GTID不兼容的語句用法,在錯誤日志會記錄相關信息,那么需要調整應該程序避免不兼容的寫法,直到完全沒有產生不兼容的語句,可以通過應該程序去排查所有的sql,也可以設置后觀察錯誤日志一段時間,這一步非常重要。
2. 在M、S上,設置ENFORCE_GTID_CONSISTENCY為ON,哪台先執行不影響結果
M:mysql> set @@global.enforce_gtid_consistency=on; S:mysql> set @@global.enforce_gtid_consistency=on;
3. 在M、S實例上,設置GTID_MODE為off_permissiv;哪台先執行不影響結果
M:mysql> SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; S:mysql> SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
4. 在M、S實例上,設置GTID_MODE為on_permissiv;哪台先執行不影響結果
M: Mysql> SET @@GLOBAL.GTID_MODE = on_permissive; S: Mysql> SET @@GLOBAL.GTID_MODE = on_permissive;
5. 在M、S上檢查變量ONGOING_ANONYMOUS_TRANSACTION_COUNT,需要等到此變量為0
Mysql> SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT'; Mysql> SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
6. 確保所有的匿名事務(非GTID事務)已經被完全復制到所有的server上。
M:show master status; S:show slave status\G 或者或者slave直接用函數: SELECT MASTER_POS_WAIT('mysql-binlog.000005',154);
返回結果大於等於0就說明匿名事務已經全部復制完成
7. 確認整個拓撲結構中已經沒有匿名事務的存在,
如之前產生的所有匿名事務已經全部被執行完畢,甚至二進制日志中也不要有匿名事務,可以通過flush logs,並讓mysql來自動清理舊的二進制日志文件。
8. 在每個mysql實例上,設置GTID_MODE為on
M: mysql> SET @@GLOBAL.GTID_MODE = ON; S: mysql> SET @@GLOBAL.GTID_MODE = ON;
9. 在每個mysql實例的配置文件my.cnf上,
增加: SHOW VARIABLES LIKE '%gtid%';
gtid_mode=ON enforce_gtid_consistency=on
10. 每個從庫開啟master_auto_position
這個步驟需要特別注意,對比下從庫的Retrieved_Gtid_Set與Executed_Gtid_Set的並集和主庫的Executed_Gtid_Set。
2.9 change master root@localhost [(none)] 11:37:17>STOP slave; Query OK, 0 rows affected (0.00 sec) root@localhost [(none)] 11:37:24>change master to master_auto_position=1; Query OK, 0 rows affected (0.00 sec) root@localhost [(none)] 11:37:52>start slave; Query OK, 0 rows affected (0.00 sec)
##############################################
如果報錯,請按照下面執行:
stop slave;
reset slave;
reset master;
該值=從庫接受到的gtid集合 Retrieved_Gtid_Set+主庫產生Executed_Gtid_Set的但從庫沒有的,
# 從庫的Retrieved_Gtid_Set往往和Executed_Gtid_Set的值是一樣的。取兩者的並集:Retrieved_Gtid_Set U Executed_Gtid_Set
SET @@GLOBAL.GTID_PURGED='12a62f29-e0dc-11e9-9d20-00163e00248a:1-22470,
947b2801-e0ed-11e9-aefb-00163e00248a:1
'; # 該內容需要根據自己的備份文件中獲得
#####主庫:
master@10.10.10.10((none)) > show master status\G; *************************** 1. row *************************** File: mysql-bin.005702 Position: 900958585 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 12a62f29-e0dc-11e9-9d20-00163e00248a:1-22047, 947b2801-e0ed-11e9-aefb-00163e00248a:1 1 row in set (0.07 sec) ERROR: No query specified Mon May 11 16:00:51 2020 ###########從庫: slave@10.10.10.11 ((none)) > show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.10.10.10 Master_User: mysqlsync Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.005703 Read_Master_Log_Pos: 140353981 Relay_Log_File: relay-bin.000004 Relay_Log_Pos: 140354146 Relay_Master_Log_File: mysql-bin.005703 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 140353981 Relay_Log_Space: 140354422 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 171574486 Master_UUID: 12a62f29-e0dc-11e9-9d20-00163e00248a Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 12a62f29-e0dc-11e9-9d20-00163e00248a:21547-22470 Executed_Gtid_Set: 12a62f29-e0dc-11e9-9d20-00163e00248a:1-22470, 947b2801-e0ed-11e9-aefb-00163e00248a:1 Auto_Position: 1 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.07 sec) ERROR: No query specified
my.cnf 配置:
log_bin = mysql-bin
bin_log = /usr/local/mysql/log/mysql-bin binlog_format = ROW //建議row log-slave-updates=true //在從服務器進入主服務器傳入過來的修改日志所使用,在Mysql5.7之前主從架構上使用gtid模式的話,必須使用此選項,在Mysql5.7取消了,會增加系統負載。 enforce-gtid-consistency=true // 強制gtid一直性,用於保證啟動gitd后事務的安全; gtid-mode=on //開啟gtid模式 master_info_repository=TABLE relay_log_info_repository=TABLE //指定中繼日志的存儲方式,默認是文件,這樣配置是使用了 兩個表,是INNODB存儲引擎,好處是當出現數據庫崩潰時,利用INNODE事務引擎的特點,對這兩個表進行恢復,以保證從服務器可以從正確位置恢復數據。 sync-master-info=1 //同步master_info,任何事物提交以后都必須要把事務提交以后的二進制日志事件的位置對應的文件名稱,記錄到master_info中,下次啟動自動讀取,保證數據無丟失 slave-parallel-workers=2 //設定從服務器的啟動線程數,0表示不啟動 binlog-checksum=CRC32 //主服務端在啟動的時候要不要校驗bin-log本身的校驗碼 master-verify-checksum=1 //都是在服務器出現故障情況下,讀取對服務器有用的數據 slave-sql-verify-checksum=1 binlog-rows-query-log_events=1 //啟用后,可用於在二進制日志記錄事件相關信息,可降低故障排除復雜度(並非強制啟動)
使用基於GTID的復制時(MASTER_AUTO_POSITION = 1),首先要開啟gtid_mode(在my.cnf中設置gtid-mode = ON),MASTER_LOG_FILE 與 MASTER_LOG_POS也不能使用,否則會報錯。 使用GTID后想要恢復到老的基於文件的復制協議,在change master to時需要指定MASTER_AUTO_POSITION = 0以及MASTER_LOG_FILE 或 MASTER_LOG_POSITION中至少一項。