天天看點

剖析MySQL GTID複制

今兒的這篇博文,可以讓大家快速了解GTID特性,并能靈活地運用到生産環境中,希望對大家有幫助。

GTID原理介紹

GTID又叫全局事務ID(Global Transaction ID),是一個已送出事務的編号,并且是一個全局唯一的編号。MySQL5.6版本之後在主從複制類型上新增了GTID複制。

GTID是由server_uuid和事務id組成的,即GTID = server_uuid:transaction_id。 server_uuid是在資料庫啟動過程中自動生成的,每台機器的server-uuid不一樣。uuid存放在資料目錄的auto.cnf檔案下。而transaction_id就是事務送出時由系統順序配置設定的一個不會重複的序列号。

GTID存在的價值

(1)GTID使用master_auto_position=1代替了基于binlog和position号的主從複制搭建方式,更便于主從複制的搭建。

(2)GTID可以知道事務在最開始是在哪個執行個體上送出的。

(3)GTID友善實作主從之間的failover,再也不用不斷地去找position和binlog 了。

主從複制中GTID的管理與維護

GTID帶來最友善的一點就是主從複制的搭建過程了。它跟異步複制、半同步複制類似,隻不過不再利用傳統複制模式的binlog檔案和position号了,而是在從庫“change master to”時使用master_auto_position=1的方式進行搭建,這就讓操作變得更加友善和可靠。

GTID搭建過程中的注意事項

主從庫需要設定的參數如下。

主庫配置:

gtid_mode=on
enforce_gtid_consistency=on
log_bin=on           

server-id不能與從庫一樣。

從庫配置:

binlog_format=row
gtid_mode=on
enforce_gtid_consistency=on
log_slave_updates=1           

雖然在MySQL5.7版本之後可以關閉掉log_slave_updates,使用gtid_executed這張表。但還是建議在從庫中開啟。server-id不能與主庫一樣。

配置好參數之後,主庫也建立了複制賬号,如果是新搭建的主從環境,就可以直接在從庫就可以執行change master to語句了。如果是已經運作了一段期間的主庫,還需要利用備份方式從主庫“dump”出資料到從庫中,先完成基于某個點的GTID複制,然後從庫從那個點之後再開始追主庫。利用mysqldump備份,備份後的檔案中會有SET @@GLOBAL.GTID_PURGED= *,利用xtrabackup工具備份,備份後的檔案中會直接記錄需要跳過的GTID。啟動複制之後,從庫會直接跳過已經執行過GTID的範圍,直接從主庫擷取新的GTID資訊。

在主庫執行show master status指令,通過Executed_Gtid_Set來檢視執行過的GTID。

剖析MySQL GTID複制

在MySQL5.7版本之後,gtid_executed這個值持久化了。在MySQL庫下新增了一張表gtid_executed:

剖析MySQL GTID複制

該表會記錄已經執行的GTID集合的資訊,有了這張表,就不用再像MySQL5.6版本時,必須開啟log_slave_updates參數,從庫才可以進行複制。GTID資訊會儲存在gtid_executed表中,可以關閉從庫的binlog,節約binlog的記錄開銷。在執行reset master時,會清空表内所有的資料。

MySQL5.7還有一個參數gtid_executed_compression_period,用來控制gtid_executed表的壓縮。該參數預設值為1000,意味着表壓縮在執行完1000個事務之後開始。

剖析MySQL GTID複制

從MySQL5.7.6開始,gtid_mode支援動态修改,gtid_mode可取值為:

OFF—不支援GTID的事務;

OFFPERMISSIVE—新的事務是匿名的,同時允許複制的事務可以是GTID,也可以是匿名的;

ON PERMISSIVE—新的事務使用GTID,同時允許複制的事務可以是GTID,也可以是匿名的;

ON—支援GTID的事務。

在生産環境中,可能有把傳統複制改為GTID的複制模式的需求。這裡特意強調一點,gtidmode雖然支援動态修改,但不支援跳躍式修改。從ON PERMISSIVE修改為OFF是不可以的。下面會有實驗來展示傳統複制與GTID複制之間的切換過程。

在從庫上可通過show slave status指令來擷取接收的gtid(retrieve_gtid_set)和執行的gtid(execute_gtid_set)。

GTID複制與傳統複制的切換

前面已經搭建好了MySQL5.7版本的GTID複制模式,下面先來操作從GTID複制模式切換為傳統複制模式的過程。

環境介紹:主庫為192.168.56.101,從庫為192.168.56.102。

目前主從狀态展示。

剖析MySQL GTID複制
剖析MySQL GTID複制

實施過程如下:

(1)先在從庫中執行stop slave,停掉主從複制。然後調整為傳統複制模式,讓master_auto_position=0。

執行如下指令:

CHANGE MASTER TO master_auto_position=0,Master_Host='192.168.56.101',MASTER_USER='bak',MASTER_PASSWORD='bak123','Master_Log_File='mysql-binlog.000002',MASTER_LOG_POS=1141;

執行完成之後,開啟複制功能start slave。

(2)需要在主從伺服器上同時調整GTID模式為on_permissive。

剖析MySQL GTID複制
  1. 需要在主從伺服器上同時調整gtid模式為off_permissive;
    剖析MySQL GTID複制
  2. 需要在主從伺服器上同時關閉gtid功能;
    剖析MySQL GTID複制
  3. 然後記得把修改gtid_mode=off和enforce_gtid_consistency=off寫入配置檔案my.cnf中。下次重新開機直接生效。
  4. 測試是否切換成功。

    首先向主庫的zs庫下的tt表中,插入一條資料

剖析MySQL GTID複制

檢視從庫,正常把這條資料同步成功!

剖析MySQL GTID複制

然後在從庫執行show slave status檢視主從複制狀态,發現gtid的值沒有增加。證明切換成功

剖析MySQL GTID複制

然後再操作從傳統複制模式切換為GTID複制模式的過程;

1.先要在主從庫上同時修改參數enforce_gtid_consistency=warn。確定在error log中不會出現警告資訊。如果有,需要先修複,才能往後進行執行。

剖析MySQL GTID複制

2.然後再在主從伺服器上把enforce_gtid_consistency改為on,來保證gtid的一緻性

剖析MySQL GTID複制
  1. 接着在主從伺服器上同時調整gtid模式為off_permissive;
    剖析MySQL GTID複制
  2. 繼續在主從伺服器上同時調整gtid模式為on_permissive;
    剖析MySQL GTID複制
  3. 确認從庫的Ongoing_anonymous_transaction_count該參數是否0,如果為0,意味着沒有等待的事務。可以直接進入下一步操作了!
    剖析MySQL GTID複制
  4. 在主從庫上同時設定gtid_mode=on
    剖析MySQL GTID複制

檢視gtid參數設定,目前都是開啟狀态。

剖析MySQL GTID複制
  1. 最後一步把傳統複制模式改為gtid複制。先要把原有的傳統複制停掉,執行stop slave操作,然後再執行change master to master_auto_position=1;

    執行完stop slave檢視目前主從的狀态為:

剖析MySQL GTID複制
剖析MySQL GTID複制

然後再執行change master to master_auto_position=1;随之開啟主從複制start slave;

  1. 驗證是否切換成功
剖析MySQL GTID複制
剖析MySQL GTID複制

然後在從庫執行show slave status檢視主從複制狀态,發現gtid的值增加了。證明開啟了GTID複制方式,切換成功

剖析MySQL GTID複制

GTID使用中的限制條件

GTID複制是針對事務來說的,一個事務隻對應一個GTID,好多的限制就在于此。

(1)不能使用create table table_name select * from table_name。

(2)在一個事務中既包含事務表的操作又包含非事務表。

(3)不支援CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE語句操作。

(4)使用GTID複制從庫跳過錯誤時,不支援執行該sql_slave_skip_counter參數的文法。