Beginning with MySQL 5.7.5, GTIDs are stored in a table named gtid_executed, in the mysql database. A row in this table contains, for each GTID or set of GTIDs that it represents, the UUID of the originating server, and the starting and ending transaction IDs of the set; for a row referencing only a single GTID, these last two values are the same. 也就是说gtid_executed表是Gtid持久化的一个工具,如前文所描述Gtid_state中的get_executed_gtids/get_lost_gtids/get_gtids_only_in_table/get_previous_gtids_logged这些数据都是存储在内存中的,那么在数据库重启后需要进行初始化,那么这需要读取Gtid持久化的介质,我们可以发现gtid_executed是一个innodb表建表语句如下,并且我们可以手动更改它,但是千万不要这么干:
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=utf8 STATS_PERSISTENT=0 那么在5.7.5以前没有gtid_executed表不是也没有问题吗?其实除了gtid_executed表以外我们还有一个Gtid持久化的介质那就是binlog中的Gtid event。所以总结一下Gtid持久化介质:
Step 3: Restart both servers with GTIDs enabled. To enable binary logging with global transaction identifiers, each server must be started with GTID mode, binary logging, slave update logging enabled, and with statements that are unsafe for GTID-based replication disabled. In addition, you should prevent unwanted or accidental updates from being performed on either server by starting both in read-only mode. This means that both servers must be started with (at least) the options shown in the following invocation of mysqld_safe: shell> mysqld_safe --gtid_mode=ON --log-bin --log-slave-updates --enforce-gtid-consistency & 开启binlog同时设置设置log_slave_updates=ture必然造成一个问题,实际上从库很多时候我们是不需要做级联slave,设置log_slave_updates=ture会造成需要额外的空间和性能开销。自然这种情况下我们需要另外的一种Gtid持久化介质,而并不是binlog中的Gtid event。为了解决这个问题,5.7中gtid_executed表应运而生了。然而gtid_executed表是否需要实时更新呢?显然在slave端不开启binlog或者开启binlog不设置log_slave_updates=ture的情况下它需要实时更新,因为I/O thread执行过得Gtid是必须持久化的,而在主库上因为有binlog的Gtid event的存在他是不需要实时更新的,这样不同的对待方式也能够减轻负担提高性能。 同时在官方文档上也有相关描述它分为是否开始binlog进行描述,但是其描述并不是最详细的。所以这部分在后面我会进行详细描述。
When binlog_gtid_simple_recovery=TRUE, which is the default in MySQL 5.7.7 and later, the server iterates only the oldest and the newest binary log files and the values of gtid_purged and gtid_executed are computed based only on Previous_gtids_log_event or Gtid_log_event found in these files. This ensures only two binary log files are iterated during server restart or when binary logs are being purged 当然这部分也会在后面进行详细的描述,这里只是简单提一下。那么我们通过mysqlbinlog 和infobin工具分别确认这一点。
5.6. 26 不开启Gtid mysqlbinlog:
*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #171211 16:20:10 server id 20155 end_log_pos 120 CRC32 0x12617db7 Start: binlog v 4, server v 5.6.26-74.0-log created 171211 16:20:10 # Warning: this binlog is either in use or was not closed properly. # at 120 #171211 16:20:14 server id 20155 end_log_pos 192 CRC32 0x696752cb Query thread_id=30 infobin:
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #171211 16:26:49 server id 1 end_log_pos 123 CRC32 0xf9a36298 Start: binlog v 4, server v 5.7.14-7-debug-log created 171211 16:26:49 # Warning: this binlog is either in use or was not closed properly. # at 123 #171211 16:26:49 server id 1 end_log_pos 194 CRC32 0x5865633f **Previous-GTIDs** # da267088-9c22-11e7-ab56-5254008768e3:1-32 # at 194 infobin: