GTID復制原理:
基於GTID的復制是MySQL 5.6后新增的復制方式.
GTID (global transaction identifier) 即全局事務ID, 保證了在每個在主庫上提交的事務在集群中有一個唯一的ID.
在原來基於日志的復制中, 從庫需要告知主庫要從哪個偏移量進行增量同步, 如果指定錯誤會造成數據的遺漏, 從而造成數據的不一致.
而基於GTID的復制中, 從庫會告知主庫已經執行的事務的GTID的值, 然后主庫會將所有未執行的事務的GTID的列表返回給從庫. 並且可以保證同一個事務只在指定的從庫執行一次.
GTID是由server_uuid和事物id組成,格式為:GTID=server_uuid:transaction_id。server_uuid是在數據庫啟動過程中自動生成,每台機器的server-uuid不一樣。uuid存放在數據目錄的auto.conf文件中,而transaction_id就是事務提交時系統順序分配的一個不會重復的序列號。
GTID的好處:
(1)GTID使用master_auto_position=1代替了binlog和position號的主從復制搭建方式,相比binlog和position方式更容易搭建主從復制。
(2)GTID方便實現主從之間的failover,不用一步一步的去查找position和binlog文件。
GTID模式復制搭建過程中注意事項:
主從需要設置如下參數(一般直接在配置文件/etc/my.cnf下直接添加):
a、主庫配置:
gtid_mode=on
enforce_gtid_consistency=on
log_bin=on
server-id=33062200(主從不能相同)
binlog_format=row
b、從庫配置:
gtid_mode=on
enforce_gtid_consistency=on
log_slave_updates=1
server-id=33062211(主從不能相同)
主庫上操作:
root@db 15:10: [mysql]>create user 'repluser'@'192.168.112.%' identified by 'repluser123'; root@db 15:10: [mysql]> grant replication slave on *.* to 'repluser'@'192.168.112.%';
主庫導出數據庫腳本all.sql
mysqldump -uroot -hlocalhost -p --single-transaction --master-data=2 -A >all.sql
從庫上操作:
將主庫上導出的all.sql腳本上傳到從庫,然后導入從庫
mysql -uroot -hlocalhost -p <all.sql
如果出現如下錯誤:
ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
則在從庫命令行下執行:reset master
root@db 15:20: [mysql]> reset master;
跟普通模式一樣,執行change master語句,只不過其中的binlog和position換成master_auto_position=1
CHANGE MASTER TO MASTER_HOST='192.168.112.220', MASTER_USER='repluser', MASTER_PASSWORD='repluser123', MASTER_PORT=3306, MASTER_AUTO_POSITION=1;
啟動slave復制服務
start slave;
查看主從復制狀態:

1 root@db 15:23: [mysql]> show slave status\G; 2 *************************** 1. row *************************** 3 Slave_IO_State: Waiting for master to send event 4 Master_Host: 192.168.112.220 5 Master_User: repluser 6 Master_Port: 3306 7 Connect_Retry: 60 8 Master_Log_File: on.000002 9 Read_Master_Log_Pos: 2538363 10 Relay_Log_File: localhost-relay-bin.000004 11 Relay_Log_Pos: 2031371 12 Relay_Master_Log_File: on.000002 13 Slave_IO_Running: Yes 14 Slave_SQL_Running: Yes 15 Replicate_Do_DB: 16 Replicate_Ignore_DB: 17 Replicate_Do_Table: 18 Replicate_Ignore_Table: 19 Replicate_Wild_Do_Table: 20 Replicate_Wild_Ignore_Table: 21 Last_Errno: 0 22 Last_Error: 23 Skip_Counter: 0 24 Exec_Master_Log_Pos: 2538363 25 Relay_Log_Space: 2031582 26 Until_Condition: None 27 Until_Log_File: 28 Until_Log_Pos: 0 29 Master_SSL_Allowed: No 30 Master_SSL_CA_File: 31 Master_SSL_CA_Path: 32 Master_SSL_Cert: 33 Master_SSL_Cipher: 34 Master_SSL_Key: 35 Seconds_Behind_Master: 0 36 Master_SSL_Verify_Server_Cert: No 37 Last_IO_Errno: 0 38 Last_IO_Error: 39 Last_SQL_Errno: 0 40 Last_SQL_Error: 41 Replicate_Ignore_Server_Ids: 42 Master_Server_Id: 33060220 43 Master_UUID: 763c7ef3-5977-11e8-ae7a-000c2936b80f 44 Master_Info_File: mysql.slave_master_info 45 SQL_Delay: 0 46 SQL_Remaining_Delay: NULL 47 Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates 48 Master_Retry_Count: 86400 49 Master_Bind: 50 Last_IO_Error_Timestamp: 51 Last_SQL_Error_Timestamp: 52 Master_SSL_Crl: 53 Master_SSL_Crlpath: 54 Retrieved_Gtid_Set: 763c7ef3-5977-11e8-ae7a-000c2936b80f:1393-6926 55 Executed_Gtid_Set: 763c7ef3-5977-11e8-ae7a-000c2936b80f:1-6926 56 Auto_Position: 1 57 Replicate_Rewrite_DB: 58 Channel_Name: 59 Master_TLS_Version: 60 1 row in set (0.00 sec) 61 62 root@db 15:23: [mysql]>
由上圖可知:
Slave_IO_Running: YesS
lave_SQL_Running: Yes
復制主從復制狀態OK,進一步查看通過Executed_Gtid_Set查看執行過的GTID:
root@db 15:38: [mysql]> show master status; +-----------+----------+--------------+------------------+---------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-----------+----------+--------------+------------------+---------------------------------------------+ | on.000002 | 3200431 | | | 763c7ef3-5977-11e8-ae7a-000c2936b80f:1-8730 | +-----------+----------+--------------+------------------+---------------------------------------------+ 1 row in set (0.00 sec) root@db 15:38: [mysql]>
在MySQL5.7版本之后,gtid_executed這個值持久化了,在MySQL庫下新增了一張表gtid_executed
root@db 15:38: [mysql]> desc gtid_executed; +----------------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+------------+------+-----+---------+-------+ | source_uuid | char(36) | NO | PRI | NULL | | | interval_start | bigint(20) | NO | PRI | NULL | | | interval_end | bigint(20) | NO | | NULL | | +----------------+------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) root@db 15:40: [mysql]> root@db 15:41: [mysql]> select * from gtid_executed; +--------------------------------------+----------------+--------------+ | source_uuid | interval_start | interval_end | +--------------------------------------+----------------+--------------+ | 763c7ef3-5977-11e8-ae7a-000c2936b80f | 1 | 6 | +--------------------------------------+----------------+--------------+ 1 row in set (0.00 sec) root@db 15:42: [mysql]>
該表會記錄執行的GTID集合信息,因為有了該表,就不用再像MySQL 5.6版本時,必須開啟log_slave_updates參數,從庫才可以進行賦值。GTID信息會保存在gtid_executed表中,可以關閉從庫的binlog,節約binlog的記錄開銷。在執行reset master時,會清空表內所有的數據。而MySQL 5.7還有一個參數gtid_executed_compresssion_period參數,用來控制gtid_executed表的壓縮,該參數默認值為1000,意思是表壓縮在執行完1000個事務之后開始。
root@db 15:47: [mysql]> show variables like '%gtid_executed%'; +----------------------------------+-------+ | Variable_name | Value | +----------------------------------+-------+ | gtid_executed_compression_period | 1000 | +----------------------------------+-------+ 1 row in set (0.00 sec) root@db 15:47: [mysql]>
從MySQL5.7.6開始,gid_mode支持動態修改,gtid_mode可取值為:
OFF-------不支持GTID事務
OFF_PERMISSIVE----新的事務是匿名的,同時允許復制的事務可以是GTID,也可以是匿名的
ON_PERMISSIVE---- 新的事務使用GTID,同時允許復制的事務可以是GTID,也可以是匿名的
ON------支持GITD的事務
在線上環境中,有可能把傳統復制改為GTID的復制模式的需求,這里特意強調一點,gtid_mode雖然支持動態修改,但不支持跳躍式修改。從ON_PERMISSIVE直接修改為OFF是不可以的,我們可以通過實驗來展示傳統復制與GTID復制之間的切換過程。見(《MySQL主從復制之傳統復制與GTID模式之間切換》)
另外在從庫上可以執行show slave status命令來獲取接收的gtid(retrieve_gtid_set)和執行的gtid(execute_gtid_set)
[root@localhost mysql]# mysql -uroot -hlocalhost -proot@123 -e "use mysql;show slave status\G;"|grep "Gtid_Set" Retrieved_Gtid_Set: 763c7ef3-5977-11e8-ae7a-000c2936b80f:1393-10758 Executed_Gtid_Set: 763c7ef3-5977-11e8-ae7a-000c2936b80f:1-10758 [root@localhost mysql]#
GTID模式復制局限性:
(1)不能使用create table table_name select * from table_name模式的語句
(2)在一個事務中既包含事務表的操作又包含非事務表
(3)不支持CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE語句操作
(4)使用GTID復制從庫跳過錯誤時,不支持sql_slave_skip_counter參數的語法