MySQL Binlog 文件格式解析(XID_EVENT)

2023年 8月 15日 80.7k 0

1. XID_EVENT 是什么?

MySQL Binlog 文件由 event 组成,event 有不同的类型,本文介绍的 XID_EVENT 表示一个事务的提交操作。

举个例子,执行一条事务,然后查看这个事务生成的 Binlog event,如下:

事务 SQL:

begin;
insert into t1 select 1,1;
commit;

生成的 Binlog Event:

mysql> show binlog events in 'mysql-bin.000003';
+------------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------+
| mysql-bin.000003 | 4 | Format_desc | 10 | 123 | Server ver: 5.7.19-17-debug-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids | 10 | 194 | b0d850c2-dbd0-11e9-90c3-080027b8bded:1-387 |
| mysql-bin.000003 | 194 | Gtid | 10 | 259 | SET @@SESSION.GTID_NEXT= 'b0d850c2-dbd0-11e9-90c3-080027b8bded:388' |
| mysql-bin.000003 | 259 | Query | 10 | 329 | BEGIN |
| mysql-bin.000003 | 329 | Table_map | 10 | 373 | table_id: 154 (db.t1) |
| mysql-bin.000003 | 373 | Write_rows | 10 | 417 | table_id: 154 flags: STMT_END_F |
| mysql-bin.000003 | 417 | Xid | 10 | 448 | COMMIT /* xid=3247 */ |
+------------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------+
7 rows in set (0.00 sec)

其中 Event_type 为 Xid 的 event 就是本文要介绍的 XID_EVENT,本文涉及的 MySQL 源码版本为 5.7.19。

2. XID_EVENT 格式

XID_EVENT 属于控制类的 event,在源码文件 libbinlogevents/src/control_events.cpp 中,看到如下解析 XID_EVENT 的一段代码,实际上这个 event 只存储了事务提交的 ID,这个 ID 使用 8 字节存储,代码如下:

Xid_event::
Xid_event(const char* buf,
const Format_description_event *description_event)
:Binary_log_event(&buf, description_event->binlog_version,
description_event->server_version)
{
//buf is advanced in Binary_log_event constructor to point to
//beginning of post-header
/*
We step to the post-header despite it being empty because it could later be
filled with something and we have to support that case.
The Variable Data part begins immediately.
*/
buf+= description_event->post_header_len[XID_EVENT - 1];
memcpy((char*) &xid, buf, 8);
}

因此,XID_EVENT 结构如下:

event header(19字节)
event data(即xid,8字节)
event checksum(4字节)

  • event header 格式是固定的,大小为 19 字节,参见:MySQL Binlog文件格式解析,其中 event type 值为 XID_EVENT,也就是 16。
  • event data 存储的是 xid 值,即事务提交 ID,占用 8 个字节。
  • event checksum,4 字节,checksum 校验码,每个 event 都会有。

使用 hexdump 解析 binlog 文件看看是不是符合这个结构。

根据前面 show binlog events in 'mysql-bin.000003'; 的输出,查找到 Xid 起始位置为 417,结束位置为 448,也就是说这个 event 占用 31 个字节,使用 hexdump 解析,命令如下:

hexdump -C -s 417 -n 31 mysql-bin.000003

[root@localhost data_5.7.19]# hexdump -C -s 417 -n 31 mysql-bin.000003
000001a1 72 3a 5c 5f 10 0a 00 00 00 1f 00 00 00 c0 01 00 |r:\_............|
000001b1 00 00 00 af 0c 00 00 00 00 00 00 25 9b ba 89 |...........%...|
000001c0

以上结果可以看到,前 19 个字节为 event header,其中 event_type 为 第 5 个字节,0x10,也就是 16,确实是 XID_EVENT。中间 8 个字节为 Xid,最后 4 个字节为 event 的 checksum值。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论