MySQL Binlog 文件格式解析(PREVIOUS_GTIDS_LOG_EVENT)
MySQL Binlog文件开头4字节固定为magic number,跟在magic number之后的第一个event通常是格式描述event(FORMAT_DESCRIPTION_EVENT),它记录了一些重要的元数据,比如event header的长度,每种event类型data部分固定长度的大小等等。Binlog event类型大概有40种,本文将介绍另外一种类型的event:PREVIOUS_GTIDS_LOG_EVENT,它记录了上一个binlog文件结束时执行到的gtid集合,通常这个event跟在格式描述event之后,如下图:
mysql> show binlog events in 'mysql-bin.000002';
+----------------+-----------+-------------+--------------------------------------------------------------------+
| Event_type | Server_id | End_log_pos | Info |
+----------------+-----------+-------------+--------------------------------------------------------------------+
| Format_desc | 10 | 123 | Server ver: 5.7.19-17-debug-log, Binlog ver: 4 |
| Previous_gtids | 10 | 194 | b0d850c2-dbd0-11e9-90c3-080027b8bded:1-53 |
| Gtid | 10 | 259 | SET @@SESSION.GTID_NEXT= 'b0d850c2-dbd0-11e9-90c3-080027b8bded:54' |
| Query | 10 | 346 | flush privileges |
+----------------+-----------+-------------+--------------------------------------------------------------------+
从以上示例可以看出Previous_gtids紧接在Format_desc之后,记录了上一个binlog文件结束时的gtid集合。
PREVIOUS_GTIDS_LOG_EVENT 格式解析:
event header 结构解析:
- timestamp:时间戳,表示该event的生成时间,占用4个字节
- type_code:event类型,占用1个字节
- server_id:生成event的server_id,占用4个字节
- event_length:event的大小,占用4个字节
- next_position:下一个event的位置,占用4个字节
- flags:event flags,占用2个字节
PREVIOUS_GTIDS_LOG_EVENT 对应的type_code为 35。
event data结构解析:
- sid数量,占用8个字节。比如:b0d850c2-dbd0-11e9-90c3-080027b8bded:1-123,c1132ab1-e9be-11e9-a9d7-fa163ec9e7c2:1-6224,有两个server_uuid,因此sid数量为2
- sid值,占用16字节,比如:b0d850c2-dbd0-11e9-90c3-080027b8bded,占用16字节
- sid对应的gtid段的数量,占用8字节。比如:b0d850c2-dbd0-11e9-90c3-080027b8bded:1-123:150-158,看最后的数字1-123:150-158,有两段gtid值,所以sid对应的gtid段的数量为2
- sid对应的gtid段的起始值,占用8字节,比如:1-123,起始值为1
- sid对应的gtid段的结束值,占用8字节,比如:1-123,结束值为123
- 如果有多个段,依次解析
- 如果有多个sid,依次解析
- 最后4字节,是这个binlog event的crc32检验值
一个完整的 PREVIOUS_GTIDS_LOG_EVENT event二进制示例,如下:
[root@host ~]# hexdump -C -s 123 -n 71 /data/mysql/data_5.7.19/mysql-bin.000002
0000007b 44 d9 2a 5e 23 0a 00 00 00 47 00 00 00 c2 00 00 |D.*^#....G......|
0000008b 00 80 00 01 00 00 00 00 00 00 00 b0 d8 50 c2 db |.............P..|
0000009b d0 11 e9 90 c3 08 00 27 b8 bd ed 01 00 00 00 00 |.......'........|
000000ab 00 00 00 01 00 00 00 00 00 00 00 36 00 00 00 00 |...........6....|
000000bb 00 00 00 bd de dc f1
- 1~19字节是event header
- 20~27字节是sid数量,值为1
- 28~43字节是sid值,为b0d850c2dbd011e990c3080027b8bded
- 44~51字节是gtid段的数量,值为1
- 52~59字节是gtid段的起始值,值为1
- 60~67字节是gtid段的结束值,值为54
- 68~71字节是整个event的crc32检验值
注意:
从MySQL的show binlog events 解析出的Previous_gtids值为 b0d850c2-dbd0-11e9-90c3-080027b8bded:1-53,实际从MySQL binlog文件中记录的值为 b0d850c2-dbd0-11e9-90c3-080027b8bded:1-54,不知道是MySQL的Bug还是有意为之。
最后:
本文案例涉及的MySQL版本、配置相关信息如下:
- MySQL Server 5.7.19
- binlog_format:ROW
- binlog_row_image:FULL
- gtid_mode:ON
文章评论