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

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

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

  • v1:用于3.23版本
  • v3:用于4.0.2到4.1版本
  • v4:用于5.0及以上版本

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。

一、事件内容-写入约定

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

  • 数字是按照地位优先的格式写入的(最不重要字节有限),除非显式表示
  • 表示位置或长度的值以字节形式写入,并且是无符号的
  • 有些数字是以封包整数的形式写入的,这个格式后面再详细说明
  • 字符串有以下几种格式:
    • 字符串可能写入一个固定长度域中,右边以null填充(0x00)
    • 可变长度的字符串前面包含一个表示字符串长度的内容
    • 有些可变长度的字符串以null结尾,有些不是。每个字符串中有符号表示属于哪种情况。
    • 对于null结尾的字符串,最前面是字符串长度,这个长度不包含结尾的null字节,除非显式表明
    • 如果存在可变长度的字符串在事件结尾,并且事件前面没有任何内容,这个字符串的长度=事件长度-事件中其他内容的长度。

有些事件使用封包整数,这是一个特殊的格式,用来有效的描述无符号整数。封包整数可以存储一个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:13字节:timestamp+type code+server ID+event length
  • v3:19字节:v1的字段+next position+flags
  • v4:19字节或更多:v3的字段+可能有其他信息

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中,包含几个事件头的常量:

  • EVENT_TYPE_OFFSET = 4
  • SERVER_ID_OFFSET = 5
  • EVENT_LEN_OFFSET = 9
  • LOG_POS_OFFSET = 13
  • FLAGS_OFFSET = 17

事件头中包含以下信息:

  • timestamp

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

  • type_code

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

  • server id

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,也就是这个语句最初是本机发起的,这个语句会被忽略执行。

  • event_length

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

  • next_position(v1不包含):4字节。下个时间在master的binlog中的位置。这个格式在binlog和relay log中不一样,而且与server版本有关(对于relay log来说,与master的版本有关)

    • v3版本的binlog:事件开头的偏移量,从binlog文件的开头开始计算。也就是说,在事件写入之前,等于tell()的值。

      所以binlog的第一个事件的next_position=4,对于事件n和n+1,next_position(n+1)=next_position(n)+event_length(n)。
    • v3版本的relay log,master是v1:可能是0,但是没法测试,因为现在已经基本没有3.23的服务器了。
    • v3版本的relay log,master是v3:开头事件的偏移量和master中binlog文件一样,也是从master的binlog文件开头开始计算。
    • v4版本的binlog:事件结尾的偏移量,从binlog文件开头开始计算。也就是说,等于在事件被写入之后,正好等于tell()的值。所以binlog中第一个事件的next_position=4+event_length,对于事件n和n+1,next_position(n+1)=next_position(n)+event_length(n+1)。
  • flags(v1中没有)

2字节,详见下一节。

  • extra_headers(v1和v3中不存在)

可变大小,当前为0。

事件flag

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

当前的事件flag:

  • LOG_EVENT_BINLOG_IN_USE_F=0x1(5.0.3新增)

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

  • LOG_EVENT_THREAD_SPECIFIC_F=0x4(4.1.0新增)

仅供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,但是会有点慢。

  • LOG_EVENT_SUPPRESS_USE_F=0x8(4.1.7新增)

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

  • LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F=0x10(5.1.4新增)

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

过时的标志位:

  • LOG_EVENT_TIME_F(4.1.1过期)。从未被设置过
  • LOG_EVENT_FORCED_ROTATE_F(4.1.1过期):这个标志位是在master的ROTATE_EVENT中配置的,但是没有任何用处。

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

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

  • v1和v3版本中,事件类型完全决定了数据格式
  • v4中,数据部分的解析除了依赖于事件类型,还依赖于格式描述事件的信息。这是因为在v4中,允许包含一个extra headers字段,这个字段的大小是在格式描述事件中定义的。实际上,当前这个字段是空的。

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

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

  • 对于所有相同类型的事件,固定部分的大小一样。
  • 对于所有相同类型的事件,可变部分的大小可能不一样。

【文档】五、Mysql Binlog事件结构的更多相关文章

  1. 前端(十八)—— jQuery高级操作:选择器、文本属性与类、事件、文档操作、动画、结构关系

    JQ选择器.文本属性与类.事件.文档操作.动画.结构关系 可参考jQuery的API文档 一.选择器 1.css语法匹配 标签 | 类 | id | 交集 群组 | 后代 | 兄弟 伪类 | 属性 $ ...

  2. 朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素

    朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素 [下载文本PDF进行阅读] 本文我会来说说我认为架构评审中应该看的一些点,以及我写设计文档的一些心得.助你在架构评审中过五关斩六将,助 ...

  3. API文档管理工具-数据库表结构思考.

    API文档管理工具-数据库表结构思考. PS: 管理工具只是为了方便自己记录API的一些基本信息,方便不同的开发人员 (App Developer, Restful API Developer)之间的 ...

  4. 部署openstack的官网文档解读mysql的配置文件

    部署openstack的官网文档解读mysql的配置文件(使用与ubutu和centos7等系统) author:headsen chen  2017-10-12 16:57:11 个人原创,严禁转载 ...

  5. 【文档】三、Mysql Binlog事件类文件和类型

    在内部,服务器使用C++类文件来表示binlog事件.标准在log_event.h文件中,这些类的方法代码在log_event.cc中. log_event是基础类.其他的详细的事件子类都是来源于他. ...

  6. ElasticSearch 基本概念 and 索引操作 and 文档操作 and 批量操作 and 结构化查询 and 过滤查询

    基本概念 索引: 类似于MySQL的表.索引的结构为全文搜索作准备,不存储原始的数据. 索引可以做分布式.每一个索引有一个或者多个分片 shard.每一个分片可以有多个副本 replica. 文档: ...

  7. PHP实例:使用PHPExcel导入Excel2003文档和Excel2007文档到MySQL数据库中

    如果要使用phpExcelReader将Excel 数据导入到mysql 数据库,请读者点击这个文章查看. 使用phpExcelReader将Excel 数据导入到mysql 数据库. 下面我们介绍另 ...

  8. 【swupdate文档 五】从可信的来源更新镜像

    从可信的来源更新镜像 现在越来越重要的是,设备不仅要能安全地进行更新操作, 而且要能够验证发送的图像是否来自一个已知的源, 并且没有嵌入恶意软件. 为了实现这个目标,SWUpdate必须验证传入的镜像 ...

  9. 【文档】四、Mysql Binlog事件含义详解

    下面对binlog中事件做个简单说明: UNKNOWN_EVENT 这个事件类型应该永远不会出现.它从不会写入binlog中.如果binlog中的事件没法被识别成其他已知事件,他被当做UNKNOWN_ ...

随机推荐

  1. Oracle EBS Model Function Technical

    ♡.Oracle EBS(ERP)Oracle 是公司名字,这个我估计大家都知道.EBS是E-Business Suite的缩写,简单的说,就是Oracle做的一个企业级的信息化软件或者系统,里面包含 ...

  2. JDBC 中 socketTimeout 的作用

    如果我们把socketTimeout设置如下: socketTimeout=60000; 这意味着60秒以内服务器必须开始给客户端吐数据,以保持socket的活性.配置成60秒,一般查询都不会遇到问题 ...

  3. [转载]灵动思绪EF(Entity FrameWork)

    很久之前就想写这篇文章了,但是由于种种原因,没有将自己学习的EF知识整理成一片文章.今天我就用CodeFirst和ModelFirst两种方式的简单案例将自己学习的EF知识做个总结. 在讲解EF之前, ...

  4. Ubuntu 16.04.2 LTS 安装 jdk1.6 和 tomcat6 (一)

    java和tomcat环境配置已经有很多教程和文章,最近项目需要配置Ubuntu 16.04.2下的古老的java6和tomcat 6,遇到小坑,特记录和分享. 网上的教程不是太新,就是太老,还有一些 ...

  5. centos7 安装SSH

    1.安装OpenSSH服务(CentOS系统默认安装了openssh)      yum install openssh-server -y 2.配置OpenSSH服务(默认的配置已可以正常工作) O ...

  6. jQuery限制文本框的输入长度

    jQuery限制文本框输入,包含粘贴. //限制文本框的输入长度 $(function () { $(document).on("keypress", ".txt-val ...

  7. js虚拟数字小键盘

    效果图 页面代码: @Html.TextBoxFor(m=>Model.FBP[i].RealNumb,new{onclick="showKeyboard('txtRealNumbOp ...

  8. MD5签名

    /// <summary>        /// 校验签名        /// </summary>        /// <param name="mode ...

  9. MVC框架入门准备(二) - 语言包类与工厂模式

    语言包类: 相关配置项 LANG_FOLDER : 语言包目录名,默认为Lang LANG_AUTO : 自动识别语言,默认为true DEFAULT_LANG : 默认语言,默认为zh-cn方法 取 ...

  10. (转)科普:SATA、PCIe、AHCI、NVMe

    原文链接:https://forum.51nb.com/thread-1670848-1-1.html IT 界总喜欢发明新名词.而且同一个东西,可能有几个不同的名字.同一个名字,又可能指不同的东西. ...