MySQL GTID概念
- GTID的概念
- GTID sets
- mysql.gtid_executed Table
- mysql.gtid_executed Table Compression
GTID是由源庫(主庫)每次事務提交產生的唯一標識,這個GTID不僅是單實例的唯一標識,而且在一組主從結構中也是唯一標識,並且所有的GTID和所有的事務都是一對一的關係。
GTID格式如下:
GTID = source_id:transaction_id
sourceid表示源庫,通常來說,服務器的server_uuid主要就是爲了這個目的。transaction_id是由事務提交的順序產生的一個連續的數字。例如,第一個提交的事務的事務號就是1,第十個提交的事務產生的事務號就是10,並且,GTID不可能爲0,例如server_uuid爲3E11FA47-71CA-11E1-9E33-C80AA9429562的第23個事務的GTID就表示爲如下:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
以上的GTID表示可以在SHOW SLAVE STATUS或者在binlog中看到。可以通過命令mysqlbinlog --base64-output=DECODE-ROWS或者SHOW BINLOG EVENTS解析binlog文件見到。
例如,我們通過SHOW MASTER STATUS或SHOW SLAVE STATUS見到如下格式:
3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5
這個例子顯示server_uuid爲3E11FA47-71CA-11E1-9E33-C80AA9429562的第一到第五個事務。這個表達式也用於啓動複製START SLAVE時的選項SQL_BEFORE_GTIDS和SQL_AFTER_GTIDS。
- GTID sets
一個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集在MySQL中有多種用途。例如,.gtid_executed和.gtid_purged系統變量也保存了GTID的值。此外,函數GTID_SUBSET()和GTID_SUBTRACT()也需要GTID作爲輸入參數。系統變量返回GTID時,UUID的字母和數字是按升序的方式排列的。
GTID通常出現在主從結構中。這就表示我們可以通過解析binlog獲取到在從庫上應用任何事務的來源。此外,一旦給定的GTID的事務已經在給定的數據庫上執行過以後,相同的GTID的事務將不再執行。因此,相同GTID的事務在從庫上只能執行一次,這就保證了數據的一致性。
一旦主從結構採用了GTID,我們就不再需要主庫的binlogfile名和複製的位置點。所有同步所需要的主庫的信息直接從複製的數據流中就可以得到。GTID代替了傳統複製所需要的文件偏移量。因此,在change master的時候不需要MASTER_FILE和MASTER_LOG_POS選項,只需要開啓MASTER_AUTO_POSITION即可。
GTID的產生由下面幾步產生
1.一個事務在主庫上執行並提交。這個事務由主庫的UUID和未在該實例內使用過的最小非零事務序列號標識。GTID寫入主庫的binlog。
2.binlog傳輸到從庫上以後存入從庫的relay log,slave讀取GTID然後設置自己的gtid_next的值,這個值告訴slave下一個事務必須使用這個GTID。
提醒:slave 設置gtid_next是一個會話級的變量
3.slave會去確認這個GTID的事務是否已經執行過了並且其他會話也沒有讀過該GTID,如果這個GTID沒有用過,那麼slave就會去寫GTID,應用該事務然後寫改事務到自身的binlog中。簡而言之就是,多個客戶端不允許同時應用同一個事務。
4.因爲.gtid_next是非空,slave不會主動去爲某個事務去生成一個GTID,而是把GTID存在.gtid_next這個變量中,也就是說從master獲取到GTID,然後寫入到該變量中,最後才寫binlog。