MySQL GTID Replication:html
從MySQL5.6開始增長了強大的GTID(Global Transaction ID,全局事務ID)這個特性,用來強化數據庫的主備一致性, 故障恢復, 以及容錯能力。用於取代過去傳統的主從複製(即:基於binlog和position的異步複製)。mysql
藉助GTID,在發生主備切換的狀況下,MySQL的其餘slave能夠自動在新主上找到正確的複製位置,這大大簡化了複雜複製拓撲下集羣的維護,也減小了人爲設置複製position發生誤操做的風險。另外,基於GTID的複製能夠忽略已經執行過的事務,減小了數據發生不一致的風險。sql
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複製的優勢:多線程
一、根據傳統的複製原理,當鏈接發生故障時,須要從新鏈接到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進行數據同步併發
二、多線程複製(基於庫),在MySQL5.6之前的版本,slave的複製是單線程的。一個事件一個事件的讀取應用。而master是併發寫入的,因此延遲是避免不了的。惟一有效的方法是把多個庫放在多臺slave,這樣又有點浪費服務器。在MySQL5.6裏面,咱們能夠把多個表放在多個庫,這樣就可使用多線程複製,當只有1個庫,多線程複製是沒有用的(即:所謂的並行複製)
簡單來講就是:跟多線程複製相關。多線程複製是基於組提交方式實現的,而組提交信息是存儲在GTID中的異步
GTID的做用:ide
一、根據GTID能夠知道事務最初是在哪一個實例上提交的
二、GTID的存在方便了Replication的Failoverui
GTID複製實現的工做原理:
一、master更新數據時,會在事務前產生GTID,一同記錄到binlog日誌中
二、slave端的I/O線程將變動的binlog,寫入到本地的relay log中
三、SQL線程從relay log中獲取GTID,而後對比slave端的binlog是否有記錄(因此MySQL5.6 slave端必須開啓binlog)
四、若是有記錄,說明該GTID的事務已經執行,slave會忽略
五、若是沒有記錄,slave就會從relay log中執行該GTID的事務,並記錄到binlog
六、在解析過程當中會判斷是否有主鍵,若是沒有就用二級索引,若是沒有就用所有掃描
GTID使用限制:
一、 MySQL5.7以後纔開始支持動態切換GTID相關的參數
二、 不支持CREATE TABLE ... SELECT statements
三、 不支持CREATE TEMPORARY TABLE statements inside transactions
四、 transaction or statement 既更新了事務表又更新了非事務表
五、 使用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)
如下內容是筆者從博客、論壇等收集的資料,不保證正確性,僅供參考:
一、gtid_executed
在當前實例上執行過的GTID集合,實際上包含了全部記錄到binlog中的事務。因此,設置set sql_log_bin=0後執行的事務不會生成binlog事件,也不會被記錄到gtid_executed中。執行reset master能夠將該變量清空
二、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的子集。
三、gtid_next
會話級變量,指示如何產生下一個GTID。可能的取值:
AUTOMATIC,自動生成下一個GTID,實現上是分配一個當前實例上還沒有執行過的序號最小的GTID
ANONYMOUS,設置後執行事務不會產生GTID
顯式指定的GTID,能夠指定任意形式合法的GTID值,但不能是當前gtid_executed中的已經包含的GTID,不然,下次執行事務時會報錯
四、gtid_mode
是否開啓GTID複製功能
五、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官網或者一些博客論壇摘錄的理解。本着實踐是檢驗真理的惟一標準的原則,記錄本文更多的做用爲未來實際應用的時候作鋪路。因此,筆者不保證內容準確性,僅供參考。歡迎業內大佬指出其中不當之處,在此先表示感謝!