2.2.2 PREVIOUS_GTIDS_LOG_EVENT
1.PREVIOUS_GTIDS_LOG_EVENT的作用
这个Event只包含可变部分。通常作为binary log的第二个Event,用于描述前面所有binary log包含的GTID SET(包括已经删除的)。
前面我们说过,初始化GTID模块的时候也会扫描binary log中的这个Event。在relay log中同样包含这个Event,主要用于描述I/O线程接收过哪些GTID,后面我们能看到MySQL实例初始化的时候可能扫描relay log中的这个Event来确认Retrieved_Gtid_Set,在4.7节会进行详细介绍。
2.源码重要接口
主库
· 初始化构造函数:Previous_gtids_log_event::Previous_gtids_log_event(const Gtid_set *set);
· 写入binlog cache:Previous_gtids_log_event::write(IO_CACHE* file)。
从库
· 读取构造函数:Previous_gtids_log_event::Previous_gtids_log_event(const char *buf,uint event_len,const Format_description_event *description_event);
· 本Event始终会被跳过,不会被SQL线程应用:Previous_gtids_log_event::do_shall_skip(Relay_log_info *rli)。
3.主体格式
整个写入过程集中在Gtid_set::encode函数中,因为GTID SET中可能出现多个server_uuid,并且可能出现GTID SET Interval,因此是可变的。在Gtid_set::encode函数中,我们也可以清晰地看到它在循环扫描GTID SET中的每个server_uuid和每个GTID SET Interval,如下。
图2-3展示了这种结构。
图2-3
以下为可变部分。
· number of sids:8字节,小端显示,本GITD SET中server_uuid的数量。
· server_uuid:16字节,GTID SET中的server_uuid。
· n_intervals:8字节,本server_uuid中GTID SET Interval的数量。
· inter_start:8字节,每个GTID SET Interval起始的gno。
· inter_next:8字节,每个GTID SET Interval结尾的下一个gno。
注意:由于一个GTID SET可以包含多个server_uuid,所以第2到第5部分可能包含多个。如果某个server_uuid中还包含多个GTID SET Interval,则第4和第5部分也可能包含多个GTID SET Interval(参见图2-3)。
4.实例解析
下面是一个PREVIOUS_GTIDS_LOG_EVENT(mysqlbinlog--hexdump 输出),是由笔者手动删除auto.cnf后构造出来的。
从第二排开始解析如下。
02 00 00 00 00 00 00 00:包含2个server_uuid。小端显示就是2。
24 98 54 63 a5 36 11 e8 a3 0c 52 54 00 81 38 e4:第一个server_uuid。
01 00 00 00 00 00 00 00:n_intervals表示本GTID SET Interval的数量。小端显示就是1。
01 00 00 00 00 00 00 00:inter_start,第一个GTID SET Interval起始的gno为1。
08 00 00 00 00 00 00 00:inter_next,第一个GTID SET Interval结尾的下一个gno为8。
6c ea 48 f6 92 6c 11 e9 b1 cb 52 54 00 81 38 e4:第二个server_uuid。
01 00 00 00 00 00 00 00:n_intervals表示本GTID SET Interval的数量。小端显示就是1。
01 00 00 00 00 00 00 00:inter_start,第一个GTID SET Interval起始的gno为1。
05 00 00 00 00 00 00 00:inter_next,第一个GTID SET Interval结尾的下一个gno为5。
解析结果如下。
24985463-a536-11e8-a30c-5254008138e4:1-7
6cea48f6-926c-11e9-b1cb-5254008138e4:1-4
可以看到它们是一致的,只是inter_next应该减去了1,因为Event中记录的是GTID SET Interval结尾的下一个gno。
5.生成时机
一般在binary log切换的时候,PREVIOUS_GTIDS_LOG_EVENT 作为第二个 Event写入binary log。