在MySQL5.6的時候,主從複製開啓了GTID,在slave執行show slave status \G的時候能夠獲取獲得當前執行的GTID的集合信息。在MySQL5.6的時候這個值並非持久化到文件或者數據庫表中的,而是每次在slave重啓的時候從最後一個binlog文件的末尾讀取寫入內存中去的。那麼這個樣子就會形成一個問題,在從庫沒有開啓log_slave_updates這個參數的時候或者說維護人員不當心將binlog文件給刪除了以後,那麼slave重啓以後就會獲取不到gtid_executed的值,那麼主從環境就會掛掉。mysql
而且還須要注意的一點就是,就算咱們開啓了log_slave_updates這個參數,將全部來自於master的事務在本地回放的時候寫入slave本地的binlog中去的話,那麼不可避免會形成磁盤IO和磁盤空間資源的浪費。sql
在MySQL5.7的時候則將gtid_executed的信息持久化到了表中,這個表就是mysql.gtid_executed表:數據庫
root@mysqldb 11:03: [(none)]> show create table mysql.gtid_executed \G *************************** 1. row *************************** Table: gtid_executed Create Table: CREATE TABLE `gtid_executed` ( `source_uuid` char(36) NOT NULL COMMENT 'uuid of the source where the transaction was originally executed.', `interval_start` bigint(20) NOT NULL COMMENT 'First number of interval.', `interval_end` bigint(20) NOT NULL COMMENT 'Last number of interval.', PRIMARY KEY (`source_uuid`,`interval_start`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 STATS_PERSISTENT=0
執行SQL能夠看到這個表的一些具體信息:服務器
root@mysqldb 11:04: [(none)]> select * from mysql.gtid_executed ; +--------------------------------------+----------------+--------------+ | source_uuid | interval_start | interval_end | +--------------------------------------+----------------+--------------+ | 4725234c-1acc-11e8-9ff9-000c29a80f41 | 1 | 781 | | 4725234c-1acc-11e8-9ff9-000c29a80f41 | 989 | 1011 | | 4cf4a087-1ba3-11e8-92f6-000c2920ceb4 | 1 | 2239 | +--------------------------------------+----------------+--------------+ 3 rows in set (0.00 sec)
新增mysql.gtid_executed表以後,slave重啓以後能夠直接從這個表中獲取信息。須要注意的是mysql.gtid_executed是在主從服務器上面都會進行更新的,而表slave_relay_log_info僅僅只是在從服務器進行更新的。ide
能夠看到上述的表mysql.gtid_executed並無記錄每一個事務的GTID的值,而是記錄了GTID的起始值和末尾值,這個是由於爲了不這個表的記錄瘋狂的增加,因此MySQL5.7引入了一個新的進程進行專門的壓縮,而且有專門的參數來設置這個壓縮比。ui
root@mysqldb 11:58: [(none)]> select thread_id,thread_os_id,name,processlist_command,processlist_state from performance_schema.threads where name like '%compress%'; +-----------+--------------+--------------------------------+---------------------+-------------------+ | thread_id | thread_os_id | name | processlist_command | processlist_state | +-----------+--------------+--------------------------------+---------------------+-------------------+ | 27 | 23839 | thread/sql/compress_gtid_table | Daemon | Suspending | +-----------+--------------+--------------------------------+---------------------+-------------------+ 1 row in set (0.00 sec) root@mysqldb 11:59: [(none)]> show global variables like 'gtid_executed_compression_period'; +----------------------------------+-------+ | Variable_name | Value | +----------------------------------+-------+ | gtid_executed_compression_period | 1000 | +----------------------------------+-------+ 1 row in set (0.01 sec) root@mysqldb 11:59: [(none)]>
還有一點須要咱們注意的:mysql.gtid_executed的記錄方式是和從庫是否開啓記錄二進制日誌是有很大的關係的。如果slave開啓了二進制日誌,則該表只會在二進制日誌切割的時候或者MySQL正常關閉進行更新,不然的話就會進行實時的更新。還有須要注意的一點就是,在MySQL異常關閉的時候GTID的信息是不會記錄到這個表中的,在MySQL恢復的時候會從binlog中記錄寫入這個表中的。日誌
當binlog開啓的時候,而且exectued_gtids_compression_period值未使用的時候,MySQL的binlog輪換也會引發mysql.gtid_executed表的自動壓縮。code