首先看下,GTID 是什么。
GTID(global transaction identifier),是全局事务标识,它具有唯一性,一个事务对应一个GTID。一个GTID在一个服务器上只执行一次。
GTID表示方式:server_uuid:sequence number
。例如,2a264578-f8ec-11ea-bce4-0a580a301853:23
前面是server_uuid,后面是一个序列号。
-
server_uuid
:事务执行时所在的MySQL主库的uuid。传递到slave时,不会改变。在MySQL进程启动时,自动创建server uuid,并保存到auto.cnf文件中。 -
sequence number
:在每台MySQL服务器上都是从1开始自增长的序列,一个数值对应一个事务。
关于 gtid_executed
gtid_executed
表示所有在服务器上执行过的事务,以及通过SET gtid_purged
设置的事务。
gtid_executed
可通过SHOW MASTER STATUS
或SHOW SLAVE STATUS
查看,其中 Executed_Gtid_Set
字段就是。
执行RESET MASTER
会清空gtid_executed
,并且没有其他方式可以清空gtid_executed
。
关于gtid_purged
gtid_purged
表示已经提交,但不在任何bin log文件中的事务。
gtid_purged
是gtid_executed
的子集。
可以通过如下方式查看
select @@GLOBAL.gtid_purged;
+---------------------------------------------------------------------------------------+
| @@GLOBAL.gtid_purged |
+---------------------------------------------------------------------------------------+
| 2a264578-f8ec-11ea-bce4-0a580a301853:1-22,
2b5e22FF-f8ec-11ea-ad99-0a580a54f323:1-601 |
+---------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
通过如下方式设置
SET @@GLOBAL.gtid_purged = 'gtid_set'
日志最新的判断
如果以gtid_executed
作为日志最新的判定标准,从库实例之间是否可以选出日志最新的实例呢?
目前,以个人理解,是可以的。
可以使用GTID_SUBSET(set1,set2)
比较GTID集合。
如果set1中的GTID也在set2中,则返回true,否则,返回false。
从库实例之间,两两比较GTID,得出GTID最多的,即是日志最新的从库实例。
如果从库中有errant呢?
分两种情况:
-
如果errant影响了后续日志的复制,存在errant的从库实例与其他从库实例之间无法比较日志是否最新。(通过日志位点log file, log pos的方式是可以的,因为没有errant的从库,可以继续复制并应用binlog)。
-
如果errant不影响binlog日志的复制,则对选举日志最新从库实例无影响。