GTID模式介紹!

MySQL GTID Replication

MySQL5.6開始增加了強大的GTID(Global Transaction ID,全局事務ID)這個特性,用來強化數據庫的主備一致性, 故障恢復, 以及容錯能力。用於取代過去傳統的主從複製(即:基於binlog和position的異步複製)。

藉助GTID,在發生主備切換的情況下,MySQL的其他slave可以自動在新主上找到正確的複製位置,這大大簡化了複雜複製拓撲下集羣的維護,也減少了人爲設置複製position發生誤操作的風險。另外,基於GTID的複製可以忽略已經執行過的事務,減少了數據發生不一致的風險。


GTID組成:

GTID是由server_uuid和事務id組成的,即GTID=server_uuid:transaction_id。
server_uuid,是在MySQL第一次啓動時自動生成並持久化到auto.cnf文件(存放在數據目錄下,每臺機器的server_uuid都不一樣。
transaction_id,是一個從1開始的自增計數,表示在這個主庫上執行的第n個事務。MySQL會保證事務與GTID之間的1:1映射,如:b6af5b5c-666f-11e9-bed3-000c29b85ea6:1
表示在以b6af5b5c-666f-11e9-bed3-000c29b85ea6爲唯一標識的MySQL實例上執行的第1個數據庫事務。
一組連續的事務可以用 "-" 連接的事務序號範圍表示。例如:b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-5


基於GTID複製的優點

1、根據傳統的複製原理,當連接發生故障時,需要重新連接到master主機,需要找到binlog和position,然後change master to 連接到master主機,此過程需要人工來做,比較麻煩,也容易出錯,尤其是master寫操作較多時,更不容易確定position,如果flush table with read lock,勢必會影響到線上業務。而GTID複製方式不需要找master的binlog和position,只需要知道master的ip、端口、賬號密碼,即可進行復制,MySQl會通過內部機制自動找點同步(MASTER_AUTO_POSITION=1)
簡單來說就是:簡化複製。傳統複製是基於file和position來實現的,而file和position是人爲確定的,file還好一些,但是position卻是實時變動的,難以確定,除非對全庫加讀鎖,但這勢必會對線上業務產生影響,GTID會自動找position進行數據同步


2、多線程複製(基於庫),在MySQL5.6以前的版本,slave的複製是單線程的。一個事件一個事件的讀取應用。而master是併發寫入的,所以延遲是避免不了的。唯一有效的方法是把多個庫放在多臺slave,這樣又有點浪費服務器。在MySQL5.6裏面,我們可以把多個表放在多個庫,這樣就可以使用多線程複製,當只有1個庫,多線程複製是沒有用的(即:所謂的並行複製)
簡單來說就是:跟多線程複製相關。多線程複製是基於組提交方式實現的,而組提交信息是存儲在GTID中的


GTID的作用

1、根據GTID可以知道事務最初是在哪個實例上提交的
2、GTID的存在方便了Replication的Failover


GTID複製實現的工作原理:
1、master更新數據時,會在事務前產生GTID,一同記錄到binlog日誌中
2、slave端的I/O線程將變更的binlog,寫入到本地的relay log中
3、SQL線程從relay log中獲取GTID,然後對比slave端的binlog是否有記錄(所以MySQL5.6 slave端必須開啓binlog)
4、如果有記錄,說明該GTID的事務已經執行,slave會忽略
5、如果沒有記錄,slave就會從relay log中執行該GTID的事務,並記錄到binlog
6、在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果沒有就用全部掃描


GTID使用限制:
1、  MySQL5.7之後纔開始支持動態切換GTID相關的參數
2、  不支持CREATE TABLE ... SELECT statements
3、  不支持CREATE TEMPORARY TABLE statements inside transactions
4、  transaction or statement 既更新了事務表又更新了非事務表
5、  使用GTID複製從庫跳過錯誤時,不支持執行sql_slave_skip_counter參數的語法


GTID相關狀態變量介紹:
推薦閱讀MySQL官網英文原著

Master、Slave上都可以查看GTID相關的狀態變量
mysql> show global variables like '%gtid%';
+--------------------------+------------------------------------------+
| Variable_name            | Value                                    |
+--------------------------+------------------------------------------+
| enforce_gtid_consistency | ON                                       |
| gtid_executed            | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-7 |
| gtid_mode                | ON                                       |
| gtid_owned               |                                          |
| gtid_purged              |                                          |
+--------------------------+------------------------------------------+
5 rows in set (0.00 sec)


以下內容是筆者從博客、論壇等收集的資料,不保證正確性,僅供參考:

1、gtid_executed
在當前實例上執行過的GTID集合,實際上包含了所有記錄到binlog中的事務。所以,設置set sql_log_bin=0後執行的事務不會生成binlog事件,也不會被記錄到gtid_executed中。執行reset master可以將該變量清空

2、gtid_purged
binlog不可能永久停留在服務器上,需要進行定期清理(如通過expire_logs_days),否則遲早它會把磁盤空間用完。gtid_purged用於記錄已經被清除了的binlog事務集合,它是gtid_executed的子集。只有gtid_executed爲空時才能手動設置該變量,此時會同時更新gtid_executed爲和gtid_purged相同的值。gtid_executed爲空意味着要麼之前沒有啓動過基於GTID的複製,要麼執行過reset master。執行reset master時同樣也會把gtid_purged置空,即始終保持gtid_purged是gtid_executed的子集。

3、gtid_next
會話級變量,指示如何產生下一個GTID。可能的取值:
AUTOMATIC,自動生成下一個GTID,實現上是分配一個當前實例上尚未執行過的序號最小的GTID
ANONYMOUS,設置後執行事務不會產生GTID
顯式指定的GTID,可以指定任意形式合法的GTID值,但不能是當前gtid_executed中的已經包含的GTID,否則,下次執行事務時會報錯

4、gtid_mode
是否開啓GTID複製功能

5、enforce-gtid-consistency = ON
啓動強制GTID的一致性,如果開啓GTID功能則此參數必須要開啓;slave在做同步複製時,無須找到binlog日誌和POS點,直接change master to master_auto_position=1即可,自動根據GTID進行同步數據。


延伸:

多線程複製

MySQL5.6之前的版本,同步複製是單線程的、隊列的,只能一個一個執行。在MySQL5.6裏,可以做到多個庫之間的多線程複製。例如數據庫裏,存放着用戶表、商品表、價格表、訂單表,那麼將每個業務表單獨放在一個庫裏,這時就可以做到多線程複製,但一個庫裏的表,多線程複製是無效的(因爲同一個庫進行多線程複製到Slave上時會造成問題);每個數據庫僅能使用一個線程(即:MySQL5.6多線程複製基於庫),複製涉及到多個數據庫時多線程複製纔有意義。Slave上多線程複製的控制參數爲slave-parallel-workers=0(0表示禁用多線程功能)


題外:

本文的主要作用是記錄GTID的用途、優缺點、使用限制、狀態變量介紹等,內容大多是從MySQL官網或者一些博客論壇摘錄的理解。本着實踐是檢驗真理的唯一標準的原則,記錄本文更多的作用爲將來實際應用的時候做鋪路。所以,筆者不保證內容準確性,僅供參考。歡迎業內大佬指出其中不當之處,在此先表示感謝!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章