參考: https://www.cnblogs.com/leohahah/p/11533952.html
GTID生命週期:
1, 如果實例啓用了GTID,當提交事物的時候,系統自動分配一個GITD,
GTID = uuid:transaction_id
uuid:每個實例都有一個唯一的uuid,查看方法: select uuid();
transaction_id: 通常爲自增序列,第一個是1,往後遞增;如:bb08f12d-b9c4-11e9-8916-fa162e6b02e2:405832
a23c850c-b9c7-11e9-b8e0-fa16f381d97a:1-1975,這種表示1-1975這個範圍內的這麼多GTID;
2, 當事物提交後,它會被加入到@@GLOBAL.gtid_executed參數中; @@GLOBAL.gtid_executed表示該實例執行過的所有GTID記錄範圍;
mysql> select @@global.gtid_executed\G
*************************** 1. row ***************************
@@global.gtid_executed: 70a76530-b9d3-11e9-8d38-fa16bae5f8ca:1-1070,
a23c850c-b9c7-11e9-b8e0-fa16f381d97a:1-1975,
bb08f12d-b9c4-11e9-8916-fa162e6b02e2:1-405834
1 row in set (0.00 sec)
當主從首次同步的時候(master_auto_position=1),從庫將@@GLOBAL.gtid_executed列表發送給主庫,主庫覈對GTID列表,並從首個未執行的BINLOG發送給從庫執行同步任務;
3, 當BINLOG被髮送給SALVE, SLAVE的IO線程會把該會話的gtid_next參數設置爲該GTID, 注意這裏的gtid_next是複製線程的session中設置的, 而用戶查看的時候查看的是用戶會話的gtid_next; 看到的結果是默認的AUTOMATIC;
4, 如果開啓了並行複製,SALVE會讀取並檢查GTID,對比@@GLOBAL.gtid_executed確保該GTID未被執行過; 如果有並行複製進程在應用該事物,那麼SLAVE直運行一個進程繼續執行; @@GLOBAL.gtid_owned 展示了哪個並行進程在執行什麼事物;
5, 如果SLAVE開啓了BINLOG,從庫也會記錄該事物的GTID(同MASTER的GTID);且實例重啓後會同樣被同步到mysql.gtid_executed中;
mysql.gtid_executed表主從可能會不一致,都是記錄本實例已執行過的GTID列表;
番外:
a, 當實例重啓或者切換的時候,GTID信息會被更新到mysql.gtid_executed表中,用於持久化;
如:
mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 70a76530-b9d3-11e9-8d38-fa16bae5f8ca | 1 | 1070 |
| a23c850c-b9c7-11e9-b8e0-fa16f381d97a | 1 | 1975 |
| bb08f12d-b9c4-11e9-8916-fa162e6b02e2 | 1 | 405833 |
+--------------------------------------+----------------+--------------+
b, 如果BINLOG被刪除,則刪除部分的GTID信息會被更新到@@GLOBAL.GTID_PURGED中;
mysql> select @@global.gtid_purged\G
*************************** 1. row ***************************
@@global.gtid_purged: 70a76530-b9d3-11e9-8d38-fa16bae5f8ca:1-1070,
a23c850c-b9c7-11e9-b8e0-fa16f381d97a:1-1975,
bb08f12d-b9c4-11e9-8916-fa162e6b02e2:1-405831
1 row in set (0.00 sec)
注意:1, @@GLOBAL.GTID_PURGED是 @@GLOBAL.gtid_executed的子集;
2,如果SLAVE上未啓用BINLOG,則@@GLOBAL.GTID_PURGED == @@GLOBAL.gtid_executed
3, 如果要手動SET @@GLOBAL.GTID_PURGED,前提是@@GLOBAL.gtid_executed爲空; 要@@GLOBAL.gtid_executed爲空命令爲:reset master;
4, 如果主從異常,且主庫的BINLOG已經丟失,可以修改@@GLOBAL.GTID_PURGED到有BINLOG的位置,待主從同步後再進行數據校驗來修復數據;
c, gtid跳過事物的方法:
stop slave;set gtid_next='要跳過的事務GTID';begin;commit;set gtid_next=AUTOMATIC;start slave;
d, GTID並非只會被分配給事務,一個事務也可能會被分配多個GTID。
e, MySQL5.7.7版本之前 gtid_executed和gtid_purged的值可能會錯誤的生成,此時需要將 binlog_gtid_simple_recovery 設爲FALSE,然後重啓實例,它會在遍歷BINLOG重新計算生成GTID;因此推薦在mysql5.7.8之後的版本上啓用GTID複製
f, reset master會清除: @@global.gtid_purged, @@global.gtid_executed, mysql.gtid_executed, 清理binlog;
g, reset slave和reset slave all; 都會清理掉@@global.gtid_executed和@@global.gtid_purged