MySQL GTID概念
- GTID的概念
- GTID sets
- mysql.gtid_executed Table
- mysql.gtid_executed Table Compression
GTID是由源库(主库)每次事务提交产生的唯一标识,这个GTID不仅是单实例的唯一标识,而且在一组主从结构中也是唯一标识,并且所有的GTID和所有的事务都是一对一的关系。
GTID格式如下:
GTID = source_id:transaction_id
sourceid表示源库,通常来说,服务器的server_uuid主要就是为了这个目的。transaction_id是由事务提交的顺序产生的一个连续的数字。例如,第一个提交的事务的事务号就是1,第十个提交的事务产生的事务号就是10,并且,GTID不可能为0,例如server_uuid为3E11FA47-71CA-11E1-9E33-C80AA9429562的第23个事务的GTID就表示为如下:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
以上的GTID表示可以在SHOW SLAVE STATUS或者在binlog中看到。可以通过命令mysqlbinlog --base64-output=DECODE-ROWS或者SHOW BINLOG EVENTS解析binlog文件见到。
例如,我们通过SHOW MASTER STATUS或SHOW SLAVE STATUS见到如下格式:
3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5
这个例子显示server_uuid为3E11FA47-71CA-11E1-9E33-C80AA9429562的第一到第五个事务。这个表达式也用于启动复制START SLAVE时的选项SQL_BEFORE_GTIDS和SQL_AFTER_GTIDS。
- GTID sets
一个GTID集合由如下的全局事务编号来表示:
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的字母和数字是按升序的方式排列的。
GTID通常出现在主从结构中。这就表示我们可以通过解析binlog获取到在从库上应用任何事务的来源。此外,一旦给定的GTID的事务已经在给定的数据库上执行过以后,相同的GTID的事务将不再执行。因此,相同GTID的事务在从库上只能执行一次,这就保证了数据的一致性。
一旦主从结构采用了GTID,我们就不再需要主库的binlogfile名和复制的位置点。所有同步所需要的主库的信息直接从复制的数据流中就可以得到。GTID代替了传统复制所需要的文件偏移量。因此,在change master的时候不需要MASTER_FILE和MASTER_LOG_POS选项,只需要开启MASTER_AUTO_POSITION即可。
GTID的产生由下面几步产生
1.一个事务在主库上执行并提交。这个事务由主库的UUID和未在该实例内使用过的最小非零事务序列号标识。GTID写入主库的binlog。
2.binlog传输到从库上以后存入从库的relay log,slave读取GTID然后设置自己的gtid_next的值,这个值告诉slave下一个事务必须使用这个GTID。
提醒:slave 设置gtid_next是一个会话级的变量
3.slave会去确认这个GTID的事务是否已经执行过了并且其他会话也没有读过该GTID,如果这个GTID没有用过,那么slave就会去写GTID,应用该事务然后写改事务到自身的binlog中。简而言之就是,多个客户端不允许同时应用同一个事务。
4.因为.gtid_next是非空,slave不会主动去为某个事务去生成一个GTID,而是把GTID存在.gtid_next这个变量中,也就是说从master获取到GTID,然后写入到该变量中,最后才写binlog。