想要了解這個問題的緣由在於有一次面試的時候,面試官問我一個問題,就是MySQL的雙主複製的時候是如何避免迴環複製這個問題的,說老實話在基於GTID複製的時候我仍是比較瞭解的,由於GTID複製是MySQL自己是不會執行已經執行過的GTID事務,即便MySQL自己並不會執行已經執行過的GTID事務,可是仍是會造成一個迴環複製。那麼MySQL究竟是如何解決迴環複製的呢?mysql
A. 搭建雙主。非gtid模式(具體過程不在描述)
master 1面試
........ ........ Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 2175 Relay_Log_File: rep_relay_log.000004 Relay_Log_Pos: 283 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes ........
master 2sql
Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 3385 Relay_Log_File: rep_relay_log.000004 Relay_Log_Pos: 1235 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
B . master 1 上面執行建立表語句ide
mysql> show create table test \G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `class_num` int(11) NOT NULL AUTO_INCREMENT, `class_name` varchar(25) DEFAULT NULL, PRIMARY KEY (`class_num`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec)
C. master 1和2上面分別插入部分數據進行驗證。ui
+-----------+------------+ | class_num | class_name | +-----------+------------+ | 4 | 物理 | | 5 | 化學 | | 6 | 生物 | | 7 | 體育 | | 8 | 123 | +-----------+------------+
D. master 1 上面執行日誌
mysql> stop slave; mysql> set global server_id=3306; mysql> start slave;
E. master 2上面執行code
mysql> stop slave; mysql> set global server_id=3307; mysql> start slave;
F. master 1 上面執行server
mysql> insert into test(class_name) values('321');
G. master 1上面觀察事務
mysql > show slave status; ...... Last_SQL_Error: Error 'Duplicate entry '9' for key 'PRIMARY'' on query. Default database: 'test'. Query: 'insert into test(class_name) values('321')' Replicate_Ignore_Server_Ids: ......
H. master 1上面執行下面命令,你會發現仍是會有這個錯誤。it
mysql> delete from test where class_num=9; mysql> start slave; mysql> show slave status; ...... Last_SQL_Error: Error 'Duplicate entry '9' for key 'PRIMARY'' on query. Default database: 'test'. Query: 'insert into test(class_name) values('321')' ......
I. 解析binlog日誌信息:
#181204 16:15:00 server id 3306 end_log_pos 2762 CRC32 0xad6f9e83 Intvar SET INSERT_ID=9/*!*/; #181204 16:15:00 server id 3306 end_log_pos 2878 CRC32 0x5cf6d5f2 Query thread _id=54 exec_time=124 error_code=0 SET TIMESTAMP=1543911300/*!*/; insert into test(class_name) values('321') /*!*/; # at 2878 #181204 16:15:00 server id 3306 end_log_pos 2909 CRC32 0x9ccd43ee Xid = 139 COMMIT/*!*/; # at 2909 #181204 16:30:52 server id 52213306 end_log_pos 2988 CRC32 0xc9831ff7 Query thread _id=54 exec_time=0 error_code=0 SET TIMESTAMP=1543912252/*!*/; BEGIN /*!*/; # at 2988 #181204 16:30:52 server id 52213306 end_log_pos 3096 CRC32 0x37f9c65e Query thread _id=54 exec_time=0 error_code=0 SET TIMESTAMP=1543912252/*!*/; delete from test where class_num=9 /*!*/; # at 3096 #181204 16:30:52 server id 52213306 end_log_pos 3127 CRC32 0xc68f6eae Xid = 151 COMMIT/*!*/; # at 3127 #181204 16:15:00 server id 3306 end_log_pos 3206 CRC32 0xd5fc40b3 Query thread _id=54 exec_time=959 error_code=0 SET TIMESTAMP=1543911300/*!*/; BEGIN /*!*/; # at 3206 # at 3238 #181204 16:15:00 server id 3306 end_log_pos 3238 CRC32 0x52663932 Intvar SET INSERT_ID=9/*!*/; #181204 16:15:00 server id 3306 end_log_pos 3354 CRC32 0xc642ad10 Query thread _id=54 exec_time=959 error_code=0 SET TIMESTAMP=1543911300/*!*/; insert into test(class_name) values('321') /*!*/; # at 3354 #181204 16:15:00 server id 3306 end_log_pos 3385 CRC32 0xd5e2ad2a Xid = 155 COMMIT/*!*/; DELIMITER ; # End of log file
能夠明顯得看獲得 insert into test(class_name) values('321');
這條SQL執行了好屢次,這個時候明顯能夠驗證在非GTID複製得狀況下面是因爲server_id才避免了迴環複製。
在進行修改uuid得時候發現這是一個只讀參數,不能在修改。而且uuid是MySQL初始化得時候先去auto.cnf文件裏面查找,若不存在則會隨機生成一串隨機碼,因此能夠直接去除這個。再上面得實驗中能夠獲取獲得MySQL再非GTID下面是由server_id得緣由才避免了迴環複製的,可是GTID環境下面會不會也是由於server_id的緣由呢,暫時就沒有去驗證了。不過我仍是認爲gtid下面也是由於GTID的緣由。