GTID即全局事務ID(global transaction identifier),GTID其實是由server_uuid:transaction_id
組成的。其中server_uuid是一個MySQL實例的惟一標識,存放在數據目錄的auto.cnf
文件下,transaction_id表明了該實例上已經提交的事務數量,而且隨着事務提交單調遞增,因此GTID可以保證每一個MySQL實例事務的執行(不會重複執行同一個事務,而且會補全沒有執行的事務)。html
GTID集是一組全局事務標識符,以下所示:mysql
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按字母順序排列,數值間隔按升序合併。web
GTID存儲在mysql數據庫中名爲gtid_executed
的表中。 對於它表示的每一個GTID或GTID集合,該表中的一行包含原始服務器的UUID,以及該集合的起始和結束事務ID; 對於僅引用單個GTID的行,這兩個最後兩個值是相同的。sql
當slave禁用binlog時,mysql.gtid_executed
表使slave可以使用GTID,而且它能夠在二進制日誌丟失時保留GTID歷史記錄。數據庫
當gtid_mode爲ON或ON_PERMISSIVE時,GTID僅存儲在mysql.gtid_executed表中,存儲GTID的位置取決因而啓用仍是禁用binlog:安全
若是禁用二進制日誌記錄(log_bin爲OFF),或者若是禁用log_slave_updates,則服務器將屬於每一個事務的GTID與表中的事務一塊兒存儲。 此外,該表能夠按期壓縮; 此狀況僅不適用於複製中的master,由於在主服務器上,必須啓用二進制日誌記錄才能進行復制。bash
若是啓用了二進制日誌記錄(log_bin爲ON),則不管什麼時候輪詢二進制日誌或關閉服務器,服務器都會將寫入先前二進制日誌的全部事務的GTID寫入mysql.gtid_executed
表。 這種狀況適用於複製主服務器或啓用了二進制日誌記錄的複製從服務器。服務器
若是服務器意外中止,則當前二進制日誌中的GTID集不會保存在mysql.gtid_executed
表中。 在這種狀況下,這些GTID會在恢復期間添加到表和gtid_executed
系統變量中的GTID集合中。session
啓用二進制日誌記錄時,mysql.gtid_executed
表不會爲全部已執行的事務提供GTID的完整記錄。 該信息由gtid_executed
系統變量的全局值提供。app
命令RESET MASTER
將重置mysql.gtid_executed表。
啓用GTID時,服務器會按期在mysql.gtid_executed
表上執行此類壓縮。 經過設置gtid_executed_compression_period
系統變量,您能夠控制壓縮表以前容許的事務數,從而控制壓縮率。 該變量的默認值爲1000; 這意味着,默認狀況下,在每1000次事務以後執行表的壓縮。 將gtid_executed_compression_period設置爲0能夠防止執行壓縮; 可是,若是執行此操做,您應該爲gtid_executed
表可能須要的磁盤空間量的大幅增長作好準備。
【注意】:
啓用binlog時,且不使用gtid_executed_compression_period的值,會在每一個binlog輪換時壓縮mysql.gtid_executed表。
壓縮前:
mysql> SELECT * FROM mysql.gtid_executed; +--------------------------------------+----------------+--------------+ | source_uuid | interval_start | interval_end | |--------------------------------------+----------------+--------------| | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 37 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 38 | 38 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 39 | 39 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 40 | 40 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 41 | 41 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 42 | 42 | | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 43 | 43 | ...
壓縮後:
+--------------------------------------+----------------+--------------+ | source_uuid | interval_start | interval_end | |--------------------------------------+----------------+--------------| | 3E11FA47-71CA-11E1-9E33-C80AA9429562 | 37 | 43 | ...
mysql.gtid_executed
表的壓縮由名爲thread/sql/compress_gtid_table
的專用前臺線程執行。 該線程未在SHOW PROCESSLIST的輸出中列出,但能夠將其視爲performance_schema.threads
表中的一行,以下所示:
mysql> SELECT * FROM performance_schema.threads WHERE NAME LIKE '%gtid%'\G *************************** 1. row *************************** THREAD_ID: 26 NAME: thread/sql/compress_gtid_table TYPE: FOREGROUND PROCESSLIST_ID: 1 PROCESSLIST_USER: NULL PROCESSLIST_HOST: NULL PROCESSLIST_DB: NULL PROCESSLIST_COMMAND: Daemon PROCESSLIST_TIME: 1509 PROCESSLIST_STATE: Suspending PROCESSLIST_INFO: NULL PARENT_THREAD_ID: 1 ROLE: NULL INSTRUMENTED: YES HISTORY: YES CONNECTION_TYPE: NULL THREAD_OS_ID: 18677
thread/sql/compress_gtid_table
線程一般會休眠,直到執行了gtid_executed_compression_period
事務,而後喚醒以執行mysql.gtid_executed
表的壓縮,如前所述。 而後它休眠直到另外一個gtid_executed_compression_period
事務發生,而後喚醒再次執行壓縮,無限期地重複此循環。 禁用二進制日誌記錄時將此值設置爲0意味着線程始終處於休眠狀態且從不喚醒。
GTID的生命週期包括如下步驟:
gtid_purged
gtid_purged
系統變量(@@global.gtid_purged
)中的GTID集包含已在服務器上提交但在服務器上的任何二進制日誌文件中不存在的全部事務的GTID。 如下類別的GTID在此集合中:
SET @@global.gtid_purged
明確添加到集合中的GTID服務器啓動時,將初始化gtid_purged
系統變量中的GTID集。 每一個二進制日誌文件都以事件Previous_gtids_log_event開頭,該事件包含全部先前二進制日誌文件中的GTID集(由前一個文件的Previous_gtids_log_event中的GTID和文件自己中每一個Gtid_log_event的GTID組成)。 最舊的二進制日誌文件中的Previous_gtids_log_event的內容用於在服務器啓動時初始化gtid_purged集,並在清除二進制日誌文件時維護該集。
GTID使用master_auto_position=1
代替了基於binlog和position號的主從複製搭建方式,更便於主從複製的搭建。
類型 | ip | prot | server-id | 是否開啓binlog | binlog格式 | log_slave_updates參數 |
---|---|---|---|---|---|---|
master | 192.168.56.100 | 3307 | 1003307 | log-bin = /data/mysql/mysql3307/logs/my3307_binlog | binlog_format = row | log_slave_updates=1 |
slave | 192.168.56.200 | 3307 | 2003307 | log-bin = /data/mysql/mysql3307/logs/my3307_binlog | binlog_format = row | log_slave_updates=1 |
server_id
: 設置MySQL實例的server_id,每一個server_id不能同樣gtid_mode=ON
: MySQL實例開啓GTID模式enforce_gtid_consitency=ON
:使用GTID模式複製時,須要開啓參數,用來保證數據的一致性。log-bin
: MySQL必需要開啓binloglog-slave-updates=1
:決定SLAVE從Master接收到更新且執行是否記錄到SLAVE的binlog中binlog_format=ROW
: binlog格式爲rowskip-slave-start=1
(可選): 當SLAVE數據庫啓動的時候,SLAVE不會啓動複製1) 建立複製帳號
create user 'repl'@'%' identified by 'wanbin'; grant replication slave on *.* to 'repl'@'%';
2) master數據庫利用xtrabackup備份至slave上
innobackupex --defaults-file=/etc/my3307.cnf -uroot -pmysql --stream=tar ./ |ssh root@mysqldb2 "cat - > /data/backup/dbback`date +%Y%m%d_%H%M%S`.tar"
mkdir dbback20181012_151213 tar -xvf dbback20181012_151213.tar -C dbback20181012_151213
innobackupex --apply-log /data/backup/dbback20181012_151213/
innobackupex --defaults-file=/etc/my3307.cnf --copy-back /data/backup/dbback20181012_151213/ chown -R mysql:mysql /data/mysql/mysql3307/data mysqld --defaults-file=/etc/my3307.cnf &
1)查看xtrabackup_info文件中的gtid信息 cat xtrabackup_info|grep binlog_pos binlog_pos = filename 'my3307_binlog.000002', position '2401', GTID of the last change '3a068bf8-cdeb-11e8-8176-080027b0b461:1-10' 2)查看slave已執行的gtid是否爲空,若是不爲空,須要執行reset MASTER進行清理,不然沒法設置gtid。 root@localhost [(none)] 15:50:41>show master status \G; *************************** 1. row *************************** File: my3307_binlog.000002 Position: 234 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 3a068bf8-cdeb-11e8-8176-080027b0b461:1-10, ffe86a27-cdef-11e8-bb92-0800275b8a9a:1-2 1 row in set (0.00 sec) 3)執行reset master root@localhost [(none)] 15:50:52>reset master; Query OK, 0 rows affected (0.04 sec) root@localhost [(none)] 15:53:18>show master status\G *************************** 1. row *************************** File: my3307_binlog.000001 Position: 154 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec) 4)執行GTID_PURGED root@localhost [(none)] 15:56:32>set session sql_log_bin = 0; root@localhost [(none)] 15:56:53>set global gtid_purged='3a068bf8-cdeb-11e8-8176-080027b0b461:1-10'; root@localhost [(none)] 15:57:58>set session sql_log_bin = 1;
執行help change master to 能夠獲取change master to命令 CHANGE MASTER TO MASTER_HOST='192.168.56.100', MASTER_USER='repl', MASTER_PASSWORD='wanbin', MASTER_PORT=3307, master_auto_position=1;
start slave; #若是想分別指定啓動線程,可使用以下命令 START SLAVE IO_THREAD; START SLAVE SQL_THREAD; #一樣關閉命令: STOP SLAVE; #分別關閉命令: STOP SLAVE IO_THREAD; STOP SLAVE SQL_THREAD;
因爲基於GTID的複製依賴於事務,所以在使用時不支持MySQL中可用的某些功能。本節提供有關使用GTID進行復制的限制和限制的信息。
使用GTID時,使用非事務性存儲引擎(如MyISAM)對錶的更新不能在與使用事務性存儲引擎(如InnoDB)的表的更新相同的語句或事務中進行。
此限制是因爲對使用非事務性存儲引擎的表的更新與對同一事務中使用事務存儲引擎的表的更新混合可能致使將多個GTID分配給同一事務。
當master和slave使用不一樣的存儲引擎用於同一個表的相應版本時,也會發生這樣的問題,其中一個存儲引擎是事務性的而另外一個不是。 還要注意,定義爲在非事務性表上運行的觸發器多是致使這些問題的緣由。
在剛剛提到的任何一種狀況下,事務和GTID之間的一對一對應關係被破壞,結果是基於GTID的複製沒法正常運行。
CREATE TABLE … SELECT對於基於語句的複製是不安全的。 使用基於行的複製時,此語句實際上記錄爲兩個單獨的事件 - 一個用於建立表,另外一個用於將源表中的行插入剛剛建立的新表中。 當在事務中執行此語句時,在某些狀況下,這兩個事件可能會接收相同的事務標識符,這意味着slave將跳過包含插入的事務。 所以,使用基於GTID的複製時不支持CREATE TABLE … SELECT。
使用GTID時(即,enforce_gtid_consistency系統變量設置爲ON時),事務,過程,函數和觸發器內不支持CREATE TEMPORARY TABLE和DROP TEMPORARY TABLE語句。 能夠在啓用GTID的狀況下使用這些語句,但僅限於任何事務以外,而且僅使用autocommit = 1。
要防止執行會致使基於GTID的複製失敗的語句,必須在啓用GTID時使用–enforce-gtid-consistency選項啓動全部服務器。
使用GTID時不支持sql_slave_skip_counter
。 若是您須要跳過事務,請使用master的gtid_executed變量的值; 有關詳細信息,請參考
https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-failover.html#replication-gtids-failover-empty
使用GTID時,不推薦使用CHANGE MASTER TO
語句的IGNORE_SERVER_IDS
選項,由於已經應用的事務會自動被忽略。 在啓動基於GTID的複製以前,請檢查並清除以前在相關服務器上設置的全部忽略的服務器ID列表。 能夠爲各個通道發出的SHOW_SLAVE_STATUS語句顯示已忽略的服務器ID列表(若是有)。 若是沒有列表,則Replicate_Ignore_Server_Ids
字段爲空。
若是目標服務器的二進制日誌中沒有GTID,則能夠將使用mysqldump建立的轉儲導入到啓用了GTID模式的MySQL服務器中。
當服務器在啓用全局事務標識符(GTID)的狀況下運行時(gtid_mode = ON),請不要經過mysql_upgrade啓用二進制日誌記錄(–write-binlog選項)。