在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