mysql日志解析table_map_MySQL二进制日志分析-TABLE_MAP_EVENT
发布日期:2021-06-24 16:47:38 浏览次数:2 分类:技术文章

本文共 2508 字,大约阅读时间需要 8 分钟。

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/Li_Xiang_996/article/details/102740081

TABLE_MAP_EVENT用于描述即将发生数据变化的表的结构。当用户提交一条修改语句时(如, insert, update, delete),MySQL会产生2个Binlog事件: 第一个就是TABLE_MAP_EVENT,用于描述改变对应表的结构(表名, 列的数据类型等信息);紧接着的是ROWS_EVENT,用于描述对应表的行的实际变化值,后续会继续介绍。

先看TABLE_MAP_EVENT的官方定义:The TABLE_MAP_EVENT defines the structure if the tables that are about to be changed.

post-header:

if post_header_len == 6 {

4 table id

} else {

6 table id

}

2 flags

payload:

1 schema name length

string schema name

1 [00]

1 table name length

string table name

1 [00]

lenenc-int column-count

string.var_len [length=$column-count] column-def

lenenc-str column-meta-def

n NULL-bitmask, length: (column-count + 8) / 7

1. table id

用于唯一标识一个表的结构,table id是MySQL自动递增分配的。需要注意的是,table id唯一标识的是一个表结构,而不是实际的数据库表。如,一个普通表tpcc.my_test1, 如果在MySQL实例运行期间,没有发生结构变化(DML),那么它的table id就不会变化;但结构发生变化后,会生成新的TABLE_MAP_EVENT,并且使用新的table id标识。

table id是数值类型,根据TABLE_MAP_EVENT的post_header的长度不同占用的字节数也不同,如果post_header的长度为6,那么table_id占用4个字节,否者占6个字节。post_header的长度可以通过前面提到的FORMAT_DESCRIPTION_EVENT获取,这里不赘诉了。

2.flags

占2个字节,保留给未来使用,不需要关心。

3. schema length and name

这里记录了对应表的schema名,首先通过1个字节记录schema名的长度,然后根据长度,就可以获取schema名,并以null[0x00]结尾。

4.table length and name

这里记录了对应表的表名,首先通过1个字节记录表名的长度,然后根据长度,就可以获取表名,并以null[0x00]结尾。

5. column-count

记录了对应表有多少列,lenenc-int类型,也就是Length-Encoded-Integer,可以参考文档https://dev.mysql.com/doc/internals/en/integer.html#packet-Protocol::LengthEncodedInteger。

简单来说,是一种可变长的存储数值的协议,具体实现来说:

根据第一个字节的数值来确定该数值的存储字节数:

如果第一个字节数值小于0xfb,则该数值通过1个字节存储;

如果第一个字节数值等于0xfc,则该数值通过2个字节存储;

如果第一个字节数值等于0xfd,则该数值通过3个字节存储;

如果第一个字节数值等于0xfe,则该数值通过8个字节存储;

先读取第一个字节,根据第一个字节的值,来获取column-count有多少个字节。

6. column-def

记录了表的列的类型,每一列占1个字节,总共column-count个字节。如:

0x04: 对应MYSQL_TYPE_FLOAT,

0x05: 对应MYSQL_TYPE_DOUBLE,

0xfc: 对应MYSQL_TYPE_BLOB等。

7. column_meta_def

记录了表的列的类型的元数据(通常为列的长度和精度),有些列类型没有元数据,有些类型有元数据,根据类型不同,有的用1个字节记录,有的用2个字节记录。列的元数据解析列值至关重要。

如: MYSQL_TYPE_NEWDECIMAL(0xf6)有2个字节的元数据,第一个字节用于记录长度(precision), 第二个字节用于记录精度(scale):

decimal(8,2) meta_def = 0x0802

如: MySQL 5.6.4引入新的日期时间类型:TIME2, TIMESTAMP2, and DATETIME2, 在新类型中引入了"fractional seconds part - FSP",可以记录精度可以小于秒级,其中"FSP"的长度就记录在1个字节的元数据中:

timestamp(3) meta_def =0x03

8. NULL-bitmask

记录字段是否可以为空,通过位图方式记录,1个bit代表一个字段。

9. Option Mea Data

这是8版本后新增加的部分,根据MySQL的binlog_row_metadata的值,记录了列更多额外的信息,这里不做介绍,可以参考BinlogMiner的代码。

TABLE_MAP_EVENT的具体代码实现可以参考:

https://github.com/Li-Xiang/BinlogMiner/blob/master/src/org/littlestar/mysql/binlog/event/body/impl/TableMapEventBody.java

转载地址:https://blog.csdn.net/weixin_33946505/article/details/113613188 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql创建密码服务断开_MySQL连接与断开服务器 | 学步园
下一篇:unity wsad 鼠标_Unity键盘WASD实现物体移动

发表评论

最新留言

很好
[***.229.124.182]2024年04月17日 04时05分46秒