GTID是什麼
GTID(Global Transaction Identifier)是事務在第一次提交時獲取到的唯一標識,該標識在整個的複製拓撲中具有唯一性。
GTID組成
GTID = source_id:transaction_id(c4e5d4a0-a9be-11e9-b444-080027f22add:7)
直觀看,GTID有兩部分組成,source_id和transaction_id。source_id代表事務提交時所在的Master實例,一般是由該實例的全局系統變量server_uuid表示;transaction_id代表事務在該實例上提交的順序,其爲大於或等於1的正向遞增序列。
GTID集合
集合,是由一個或多個確定的元素所構成的整體。GTID集合,顧名思義,這其中的元素就是GTID,由單個,或多個GTID,又或由一個範圍的GTID組成。如,3E11FA47-71CA-11E1-9E33-C80AA9429562:1-3:11:47-49。在實例中全局系統變量gtid_executed和gtid_purged往往存儲的就是GTID集合。
GTID集合也是有格式的,如下:
gtid_set:
uuid_set [, uuid_set] ...
| ''
uuid_set:
uuid:interval[:interval]...
uuid:
hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh
h:
[0-9|A-F]
interval:
n[-n]
(n >= 1)
GTID存儲
GTID是存儲在系統表mysql.gtid_executed中的,該表一行記錄代表單個GTID,或GTID集合。
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa | 1 | 72 |
| c4e5d4a0-a9be-11e9-b444-080027f22add | 101005 | 188707 |
+--------------------------------------+----------------+--------------+
GTID何時被寫入mysql.gtid_executed表呢…,這取決於二進制日誌是否開啓。
當禁用二進制日誌時(該情況一般出現在Slave上),MySQL在執行(回放)完GTID(事務)後,同時將該GTID寫入mysql.gtid_executed表。在5.7版本中,對於DML語句,該過程是原子性的,但對於DDL語句不是原子性的(在8.0版本中,DML和DDL語句都是原子性的了。)。
當開啓二進制日誌時,在二進制日誌輪換,或實例關閉時,MySQL會將之前二進制日誌中全部GTID寫入mysql.gtid_executed表。若MySQL意外關閉了,在恢復(recovery)階段,沒寫入的GTID會再次被寫入mysql.gtid_executed(當然關閉了二進制日誌,恢復時,沒寫入的GTID是不能恢復的,之後複製也是無法繼續的)。
不難看出啓用二進制日誌時,mysql.gtid_executed表中的GTID不能代表全部的事務,該信息則是由全局系統變量@@GLOBAL.gtid_executed提供的。
[[email protected]][(none)]> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa | 1 | 72 |
| c4e5d4a0-a9be-11e9-b444-080027f22add | 101005 | 188707 |
+--------------------------------------+----------------+--------------+
4 rows in set (0.00 sec)
[[email protected]][(none)]> select @@global.gtid_executed;
+-----------------------------------------------------------------------
| @@global.gtid_executed |
+-----------------------------------------------------------------------
| aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-76:,
c4e5d4a0-a9be-11e9-b444-080027f22add:101005-338847 |
+-----------------------------------------------------------------------
1 row in set (0.00 sec)
注意,reset master會將mysql.gtid_executed表清空。
[[email protected]][(none)]> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| c4e5d4a0-a9be-11e9-b444-080027f22add | 1 | 188708 |
+--------------------------------------+----------------+--------------+
1 row in set (0.00 sec)
[[email protected]][(none)]> select @@global.gtid_executed;
+-----------------------------------------------+
| @@global.gtid_executed |
+-----------------------------------------------+
| c4e5d4a0-a9be-11e9-b444-080027f22add:1-888712 |
+-----------------------------------------------+
1 row in set (0.00 sec)
[[email protected]][(none)]> select @@global.gtid_purged;
+-----------------------------------------------+
| @@global.gtid_purged |
+-----------------------------------------------+
| c4e5d4a0-a9be-11e9-b444-080027f22add:1-101004 |
+-----------------------------------------------+
1 row in set (0.00 sec)
[[email protected]][(none)]> reset master;
Query OK, 0 rows affected (0.04 sec)
[[email protected]][(none)]> select * from mysql.gtid_executed;
Empty set (0.00 sec)
[[email protected]][(none)]> select @@global.gtid_executed;
+------------------------+
| @@global.gtid_executed |
+------------------------+
| |
+------------------------+
1 row in set (0.00 sec)
[[email protected]][(none)]> select @@global.gtid_purged;
+----------------------+
| @@global.gtid_purged |
+----------------------+
| |
+----------------------+
1 row in set (0.00 sec)