您好,登錄后才能下訂單哦!
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官網或者一些博客論壇摘錄的理解。本著實踐是檢驗真理的唯一標準的原則,記錄本文更多的作用為將來實際應用的時候做鋪路。所以,筆者不保證內容準確性,僅供參考。歡迎業內大佬指出其中不當之處,在此先表示感謝!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。