【文档】五、Mysql Binlog事件结构

2017-10-09  本文已影响142人  端木轩

这个部分描述了事件被写入binlog或者delay log中的属性。所有的事件有相同的整体结构,也就是包含事件头和事件数据:

+===================+
| event header      |
+===================+
| event data        |
+===================+

具体的内容随着Mysql版本的升级而不同,这导致了binlog格式的不一致:

v2的格式用于4.0.x的版本中,但是已经过期了,并且不再支持了。

有些事件的结构随着版本没有改变,而有些与版本有关。在所有的版本中,不同类型的事件在数据部分的结构不一样。

日志文件的第一个事件是特殊的。他是个符号事件,包含binlog版本和服务器版本。符号事件中的信息让程序能够决定日志文件的格式,这样剩余的事件内容才能被正确的解析出来。

下面说明下不同版本的binlog格式:

v1事件结构:

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    |
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    |
+=====================================+
| event  | fixed part       13 : y    |
| data   +----------------------------+
|        | variable part              |
+=====================================+

头长度=13字节,数据长度=(事件长度-13)字节,y与事件类型有关。

v3事件结构

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    |
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    |
|        +----------------------------+
|        | next_position    13 : 4    |
|        +----------------------------+
|        | flags            17 : 2    |
+=====================================+
| event  | fixed part       19 : y    |
| data   +----------------------------+
|        | variable part              |
+=====================================+

头长度=19字节,数据长度=(事件长度-19)字节,y与事件类型有关。

v4事件结构

+=====================================+
| event  | timestamp         0 : 4    |
| header +----------------------------+
|        | type_code         4 : 1    |
|        +----------------------------+
|        | server_id         5 : 4    |
|        +----------------------------+
|        | event_length      9 : 4    |
|        +----------------------------+
|        | next_position    13 : 4    |
|        +----------------------------+
|        | flags            17 : 2    |
|        +----------------------------+
|        | extra_headers    19 : x-19 |
+=====================================+
| event  | fixed part        x : y    |
| data   +----------------------------+
|        | variable part              |
+=====================================+

头长度=x字节,数据长度=(事件长度-x)字节,固定数据部分长度=y字节,变量数据程度=(事件长度-(x+y))字节。x由FDE(格式描述事件format description event)header_length给出。当前来说,x=19,所以extra_headers字段是空的。

y和事件类型有关,也是由FDE给出的。fixed-part的长度对于同一个事件类型是一样的,但是不同的事件类型是不一样的。

fixed-part有时候指的是post-header,变量部分有时候指的是payload或者body。

一、事件内容-写入约定

事件内容的写入约定如下:

有些事件使用封包整数,这是一个特殊的格式,用来有效的描述无符号整数。封包整数可以存储一个8字节的整数,小整数(small integer)占用1、3或4字节。根据下面的表格,第一个字节的值决定了如何读这个数字:

第一个字节 格式
0-250 第一个字节就是数字(0-250),不需要额外的字节。
252 使用多于2字节,数字的范围是251-0xffff
253 使用多于3字节,数字的范围是0xffff-0xfffff
254 使用多于8字节,数字范围是0xfffff-0xffffffffffffffff

二、事件头字段

每个事件以LOG_EVENT_HEADER_LEN长度开头,这个常量在v1格式中时13,在v3及以上格式中是19.

v1事件头:

+============================+
| timestamp         0 : 4    |
+----------------------------+
| type_code         4 : 1    |
+----------------------------+
| server_id         5 : 4    |
+----------------------------+
| event_length      9 : 4    |
+============================+

v1头的13个字节也包含在其他版本的事件头中。

v3事件头

+============================+
| timestamp         0 : 4    |
+----------------------------+
| type_code         4 : 1    |
+----------------------------+
| server_id         5 : 4    |
+----------------------------+
| event_length      9 : 4    |
+----------------------------+
| next_position    13 : 4    |
+----------------------------+
| flags            17 : 2    |
+============================+

和v1对比,v3以上中的事件头中包含两个额外的字段,总长度为19字节。

v4事件头

+============================+
| timestamp         0 : 4    |
+----------------------------+
| type_code         4 : 1    |
+----------------------------+
| server_id         5 : 4    |
+----------------------------+
| event_length      9 : 4    |
+----------------------------+
| next_position    13 : 4    |
+----------------------------+
| flags            17 : 2    |
+----------------------------+
| extra_headers    19 : x-19 |
+============================+

v4的事件头中包含一个extra_headers字段,是为了以后扩展用。当前x=19,所以v4和v3当前格式一样。

注意:extra_headers么有在FORMAT_DESCRIPTION_EVENT或ROTATE_EVENT的头中出现。

在log_event.h中,包含几个事件头的常量:

事件头中包含以下信息:

4字节。表示的是语句开始执行的时间,格式与TIMESTAMP SQL数据类型一样。

1字节。事件类型。1表示START_EVENT_V3,2表示QEURY_EVENT,以此类推。这些数字定义在log_event.h的Log_event_type的枚举类中。

4字节,产生这个事件的mysqld服务器id。这个是在服务器中配置文件配置的,用于主从复制。server id会在循环复制时避免死循环(开启了--log-slave-updates配置)。假设M1、M2和M3的server id分别是1、2、3,而且他们循环复制:M1是M2的主,M2是M3的主,M3是M1的主。他们的主从关系如下:

M1---->M2
 ^      |
 |      |
 +--M3<-+

客户端发起了一个插入语句给M1,M1执行了之后,写入了M1的binlog文件中,包含了server id为1。这个事件被发给了M2,M2也执行了这个语句,然后写binlog的时候,server id还是1,因为这个事件最初是由M1发起的。然后M3也收到了这个事件,执行完成后写入到M3的binlog文件时,server id还是1。然后M1收到了这个事件之后,在执行插入语句之前,可以分析出server id=1,也就是这个语句最初是本机发起的,这个语句会被忽略执行。

4字节。事件的总长度,包含事件头和事件数据。大部分的事件小于1000字节,除非使用LOAD DATA INFILE(因为包含加载文件,所以他们可能很大)

2字节,详见下一节。

可变大小,当前为0。

事件flag

对于v3及以上版本中,事件头中包含一个2字节的时间flag在FLAGS_OFFSET=17位置上。在log_event.h中并没有定义。

当前的事件flag:

表示一个binlog文件是否正确的被关闭了。这个标志位只对FORMAT_DESCRIPTION_EVENT生效。当这个事件被写入日志文件时,才会设置这个标志位。当日志文件后续被关闭后,这个标志位会被清除掉。(这是Mysql修改已经写完的binlog文件的唯一情况)。

仅供mysqlbinlog使用,使他能够正确的处理临时表。mysqlbinlog把binlog中的事件打印出来,让你能够理解打印出来的内容。但是如果两个独立的线程使用同样的临时表名,比如:

<thread id 1>
CREATE TEMPORARY TABLE t (a INT);
<thread id 2>
CREATE TEMPORARY TABLE t (a INT);

这种情况下,简单的执行sql语句,会导致表t已经存在的错误。所以使用临时表的事件需要设置这个标志位,那样mysqlbinlog知道需要在变量值钱设置假的线程id,例如:

SET PSEUDO_THREAD_ID=1;
CREATE TEMPORARY TABLE t (a INT);
SET PSEUDO_THREAD_ID=2;
CREATE TEMPORARY TABLE t (a INT);

这样,服务器接收到命令后就没有歧义了。所有情况下都打印SET PSEUDO_THREAD_ID,及时临时表没有用到,这样不会产生bug,但是会有点慢。

在一个语句被记录前,抑制产生USE语句。用于任何不需要使用默认数据库的事件中,比如CREATE DATABASE和DROP DATABASE。

在事件写入日志文件中后,导致binlog内部的表映射版本增加。

过时的标志位:

三、事件数据字段(事件详细信息)

事件数据部分的结构依赖于事件类型:

数据部分包含固定大小和可变大小两部分。两部分都可以为空,这由事件类型决定。(比如,STOP_EVENT只包含头,数据内容都为空)。

事件数据的大小=事件大小-事件头大小。下面的规则对binlog中所有的事件都通用:

上一篇 下一篇

猜你喜欢

热点阅读