MySQL Binlog解析(1)
一、Binlog File
Binlog files start with a Binlog File Header followed by a series of Binlog Event
Binlog文件从一个Binlog文件头开始,接着是一系列的Binlog事件。
1 Binlog File Header(文件头)
A binlog file starts with a Binlog File Header [ fe 'bin' ]
每一个binlog文件头都是fe bin,十六进制如下(fe 62 69 6e):
$ hexdump -C /tmp/binlog-test.log
00000000 fe 62 69 6e 19 6f c9 4c 0f 01 00 00 00 66 00 00 |.bin.o.L.....f..|
00000010 00 6a 00 00 00 00 00 04 00 6d 79 73 71 6c 2d 70 |.j.......mysql-p|
00000020 72 6f 78 79 2d 30 2e 37 2e 30 00 00 00 00 00 00 |roxy-0.7.0......|
2 Binlog Event(binlog事件)
The events contain the actual data that should be shipped from the master to the slave. Depending on the use, different events are sent.
事件包含主服务器发送到slave实际数据。根据实际使用情况,从而发送不同的事件。
The first event is either a START_EVENT_V3 or a FORMAT_DESCRIPTION_EVENT while the last event is either a STOP_EVENT or a ROTATE_EVENT.
第一个事件要么是START_EVENT_V3,要么是FORMAT_DESCRIPTION_EVENT,而最后一个事件要么是STOP_EVENT,要么是ROTATE_EVENT。在MySQL5.0以上版本中(binlog版本4),第一个事件都是FORMAT_DESCRIPTION_EVENT,最后一个是ROTATE_EVENT
A binlog event starts with a Binlog Event header and is followed by a Binlog Event Type specific data part
每个binlog事件都以一个binlog事件头开始,然后是一个binlog事件类型特定的数据部分。
2.1 FORMAT_DESCRIPTION_EVENT
A format description event is the first event of a binlog for binlog-version 4. It describes how the other events are layed out.added in MySQL 5.0.0 as replacement for START_EVENT_V3
格式描述事件是binlog(版本4)的第一个事件。它描述了其他事件是如何发生的。在MySQL5.0版本中添加用来替代START_EVENT_V3事件
1) Event header(事件头)
The binlog event header starts each event and is either 13 or 19 bytes long, depending on the binlog version.
事件头根据binlog版本不同,分为13字节和19字节。mysql5+版本都是binlog v4版本,都是19个字节。
Binlog header field(字段组成):
timestamp (4) -- seconds since unix epoch:第一个字段是时间戳,占4个字节
event_type(1) -- see Binlog Event Type :第二个字段是事件类型,占1个字节
server_id (4) -- server-id of the originating mysql-server. Used to filter out events in circular replication :第三个字段是源mysql主机的serverid,占4个字节,用于过滤循环复制中的事件。
event_size (4) -- size of the event (header, post-header, body):第四个字段是事件大小,占4个字节,包括事件头、事件体的总大小
log_pos (4) -- position of the next event:第五个字段是位置,占4个字节,表示下一个事件的位置
flags (2) -- see Binlog Event Flag:最后一个字段标志状态,占2个字节
2) Event body(事件体)
Binlog body field(字段组成):
binlog-version (2) -- version of this binlog format. #binlog文件版本号,2个字节
mysql-server version (string.fix_len) -- [len=50] version of the MySQL Server that created the binlog. The string is evaluted to apply work-arounds in the slave. #创建binlog的MySQL服务器版本,50个字节
create_timestamp (4) -- seconds since Unix epoch when the binlog was created #binlog创建时的时间戳,4个字节
event_header_length (1) -- length of the Binlog Event Header of next events. Should always be 19。
event type header length (string.EOF) -- a array indexed by Binlog Event Type - 1 to extract the length of the event specific header. 这些字节由已经定义的event的个数决定,5.6,5.7为39个,也就是39个字节说明了他们fixed data(posted header)的长度
CRC32(4): CRC32校验位,4个字节,文档上没有该字段,我通过分析binlog文件加上的。
3)【实战解析】:
分析FORMAT_DESCRIPTION_EVENT在binlog文件中的实际存储:
[root@shvm-5-39 mysql.bin]# /usr/local/mysql/bin/mysqlbinlog -vvv --base64-output='decode-rows' shvm-5-39.000001
# at 4
#171103 10:28:01 server id 2490050396 end_log_pos 123 CRC32 0x6c7b82a6 Start: binlog v 4, server v 5.7.19-log created 171103 10:28:01 at startup
ROLLBACK/*!*/;
# at 123
#171103 10:28:01 server id 2490050396 end_log_pos 154 CRC32 0x15e3db98 Previous-GTIDs
# [empty]
# at 154
#171103 10:28:04 server id 2490050396 end_log_pos 177 CRC32 0xbfbf2ea2 Stop
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--------------------------------------------------------------------------------------------------------
下面是十六进制格式:
[root@shvm-5-39 mysql.bin]# hexdump -C shvm-5-39.000001
00000000 fe 62 69 6e 31 d4 fb 59 0f 5c 27 6b 94 77 00 00 |.bin1..Y.\'k.w..|
00000010 00 7b 00 00 00 00 00 04 00 35 2e 37 2e 31 39 2d |.{.......5.7.19-|
00000020 6c 6f 67 00 00 00 00 00 00 00 00 00 00 00 00 00 |log.............|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 31 d4 fb 59 13 |...........1..Y.|
00000050 38 0d 00 08 00 12 00 04 04 04 04 12 00 00 5f 00 |8............._.|
00000060 04 1a 08 00 00 00 08 08 08 02 00 00 00 0a 0a 0a |................|
00000070 2a 2a 00 12 34 00 01 a6 82 7b 6c 31 d4 fb 59 23 |**..4....{l1..Y#|
00000080 5c 27 6b 94 1f 00 00 00 9a 00 00 00 80 00 00 00 |\'k.............|
00000090 00 00 00 00 00 00 98 db e3 15 34 d4 fb 59 03 5c |..........4..Y.\|
000000a0 27 6b 94 17 00 00 00 b1 00 00 00 00 00 a2 2e bf |'k..............|
000000b0 bf |.|
000000b1
-------------------------------------------------------------------------------------------------------
分析如下:
第一部分:binlog文件头,不同于事件头。上面解释过,前4个字节 fe 62 69 6e这个魔数表示文件头,固定的。
第二部分:接下来就是binlog事件了,事件分事件头和事件体,下面分析FORMAT_DESCRIPTION_EVENT如何存储的?
1) 31 d4 fb 59:前4个字节代表字段timestamp,采用小端字节序,值是0x59fbd431 换算成十进制:5X16^7+9X16^6+f*16^5+b*16^4+d*16^3+4X16^2+3*16^1+1X16^0=1509676081 换成时间:2017-11-03 10:28:01
2) 0f:第5个字节代表event_type=15,代表是FORMAT_DESCRIPTION_EVENT
3) 5c 27 6b 94:再4个字节代表server_id=0x946b275c 换算成十进制:9x16^7+4x16^6+6x16^5+b*16^4+2x16^3+7x16^2+5x16+c=2490050396
4) 77 00 00 00:这4个字节代表event_size=0x00000077 换成十进制:7*16^1+7*16^0=119
5) 7b 00 00 00:4个字节代表log_pos=0x0000007b 换成十进制:123,表示下一个event起始偏移,对应binlog文件中end_log_pos=123
6) 00 00:2个字节表示flags=0,表示该binlog文件已经被关闭,如果打开时为1,最后一个正在写入的binlog文件flags=1
7) 04 00:2个字节表示binlog版本号=4
8) 35 2e 37 2e 31 39 2d 6c 6f 67 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00:这50字节MySQL服务器版本server v 5.7.19-log
9) 31 d4 fb 59:0x59fbd431表示binlog创建时间戳,1509676081 换成时间:2017-11-03 10:28:01
10)13:这一个字节表示event_header_length=0x13=19,事件头是19字节
11)38 0d 00 08 00 12 00 04 04 04 04 12 00 00 5f 00 04 1a 08 00 00 00 08 08 08 02 00 00 00 0a 0a 0a 2a 2a 00 12 34 00 01:这39个字节表示有39个event
12)a6 82 7b 6c:0x6c7b82a6表示CRC32的值,同binlog文件中的值
以上分析的内容同binlog文件里看到的一致。
2.2 ROTATE_EVENT
1)触发条件
When a binary log file exceeds a size limit, a ROTATE_EVENT is written at the end of the file that points to the next file in the squence. This event is information for the slave to know the name of the next binary log it is going to receive.
# 当一个二进制日志文件超过大小限制时(max_binlog_size),ROTATE_EVENT将被触发,在文件的末尾写入,指向下一个文件。这个事件是给slave的信息,以便知道它将要接收的下一个二进制日志的名称。
# 当执行flush logs触发ROTATE_EVENT并生成新二进制文件,宕机不能触发该事件
2)存储格式
Fixed data part:
8 bytes. The position of the first event in the next log file. Always contains the number 4 (meaning the next event starts at position 4 in the next binary log). This field is not present in v1; presumably the value is assumed to be 4.
Variable data part:
The name of the next binary log. The filename is not null-terminated. Its length is the event size minus the size of the fixed parts.
1、事件头部分上面已经说过,占用19个字节,所有事件都是一样的。
2、事件体部分:
固定数据部分:8个字节,记录下一个二进制文件第一个事件的位置,该值总是等于4,也就是在新的binlog文件at 4.
可变数据部分:记录下一个binlog文件名,该值不能为空字符。长度等于 event size减去固定数据部分。
2.3 STOP_EVENT
1)触发条件
A master writes the event to the binary log when it shuts down
A slave writes the event to the relay log when it shuts down or when a RESET SLAVE statement is executed
master开启binlog,当数据库shut down时
slave开启binlog,当数据库shut down或者执行reset slave语句时
2)存储格式
1、事件头,占用19个字节。
2、事件体部分:
固定数据部分:Empty
可变数据部分:Empty
CRC校验:占用4个字节
一共占用23个字节
2.4 QUERY_EVENT
The query event is used to send text querys right the binlog.
查询事件用于向binlog发送文本查询。
1)触发条件
QUERY_EVENT类型的事件通常在以下几种情况下使用:
# 事务开始时,执行的BEGIN操作
# STATEMENT格式中的DML操作
# ROW格式中的DDL操作
2)存储格式
1、事件头,占用19个字节。
2、事件体部分:
固定数据部分:
# 4 bytes. The ID of the thread that issued this statement. Needed for temporary tables. This is also useful for a DBA for knowing who did what on the master.//4个字节存储thread id
# 4 bytes. The time in seconds that the statement took to execute. Only useful for inspection by the DBA.//4个字节 存储执行时间,单位秒
# 1 byte. The length of the name of the database which was the default database when the statement was executed. This name appears later, in the variable data part. It is necessary for statements such as INSERT INTO t VALUES(1) that don't specify the database and rely on the default database previously selected by USE.//1个字节,存储执行sql默认数据库名的长度
# 2 bytes. The error code resulting from execution of the statement on the master. //2个字节存储错误编码值,0代表没有错误。如果非零一般出现在非事务性表操作,如insert...select在插入1000条到mysiam失败了,部分数据写入到了binlog文件。
# 2 bytes (not present in v1, v3). The length of the status variable block.//2个字节存储状态变量块的长度
可变数据部分:
# Zero or more status variables (not present in v1, v3). Each status variable consists of one byte code identifying the variable stored, followed by the value of the variable. The format of the value is variable-specific, as described later.
存储上下文一些set 变量,key-value形式存储,它的长度在固定数据最后一个字段已经知道
# The default database name (null-terminated).
默认的数据库名,在固定数据部分已经知道它的长度
# 00:默认的1个字节
# The SQL statement. The slave knows the size of the other fields in the variable part (the sizes are given in the fixed data part), so by subtraction it can know the size of the statement.
存储SQL语句,它的长度可以通过event-size 减去 公有事件头19 减去 固定数据部分长度 减去 可变数据的变量长度 减去可变数据的数据库名长度 减去 CRC32(4个字节) 减去 1个字节(默认00)
3)实战分析
结合hexdump出来的数据和mysqlbinlog解析出的日志进行分析:
# at 259
#180530 18:42:31 server id 2490050396 end_log_pos 370 CRC32 0x6a9644c6 Query thread_id=7322991 exec_time=0 error_code=0
use `darren`/*!*/;
SET TIMESTAMP=1527676951/*!*/;
SET @@session.pseudo_thread_id=7322991/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
alter table t add index idx_1(id)
/*!*/;
-------公有事件头--------
19个字节这里再分析
--------固定数据部分(私有事件头)-----
1、thread_id:4个字节,6f bd 6f 00,十进制即7322991.存储了不同连接或会话的线程ID
2、execution time:4个字节,00 00 00 00,查询从开始执行到记录到binlog所花时间,单位s
3、schema length:1个字节,06,schema字符长度6。即darren
4、error code:2个字节,00 00,错误码
5、status-var length:2个字节,23 00,status-var的长度,为35
---------可变数据部分(事件体)--------
6、status var:35个字节,即00 00 00 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 04 21 00 21 00 21 00 0c 01 64 61 72 72 65 6e 00。以KV对的形式保存起来的一些了由SET命令设置的上下文信息。如SET @@session.sql_mode=0 等
7、schema:6字节,即64 61 72 72 65 6e,查询对应的asci码,刚好对应darren。表示选择的数据库是darren
8、00:默认1个字节
9、sql文本:33个字节,即:61 6c 74 65 72 20 74 61 62 6c 65 20 74 20 61 64 64 20 69 6e 64 65 78 20 69 64 78 5f 31 28 69 64 29,query的文本格式,里面存储的是BEGIN或原生的SQL等
MySQL Binlog解析(1)的更多相关文章
- MySQL Binlog 解析工具 Maxwell 详解
maxwell 简介 Maxwell是一个能实时读取MySQL二进制日志binlog,并生成 JSON 格式的消息,作为生产者发送给 Kafka,Kinesis.RabbitMQ.Redis.Goog ...
- mysql binlog解析概要
1,dump协议: 根据数据库的ip+port创建socket,如果创建成功,说明链接建立成功,接下来是使用dump协议订阅binlog 链接建立成功之后,服务端会主动向客户端发送如下问候信息gree ...
- MySQL Binlog解析
https://yq.aliyun.com/articles/238364?spm=5176.8067842.tagmain.52.73PjU3 摘要: 概述 MySQL的安装可以参考:Linux(C ...
- MySQL Binlog解析(2)
一.TABLE_MAP_EVENT Used for row-based binary logging beginning with MySQL 5.1.5.The TABLE_MAP_EVENT d ...
- 采用OpenReplicator解析MySQL binlog
Open Replicator是一个用Java编写的MySQL binlog分析程序.Open Replicator 首先连接到MySQL(就像一个普通的MySQL Slave一样),然后接收和分析b ...
- MySQL Binlog 介绍
Binlog 简介 MySQL中一般有以下几种日志: 日志类型 写入日志的信息 错误日志 记录在启动,运行或停止mysqld时遇到的问题 通用查询日志 记录建立的客户端连接和执行的语句 二进制日志 记 ...
- MySQL binlog的格式解析
我搜集到了一些资料,对理解代码比较有帮助. 在头文件中binlog_event.h中,有描述 class Log_event_header class Log_event_footer 参见[Myst ...
- Mysql binlog日志解析
1. 摘要: Mysql日志抽取与解析正如名字所将的那样,分抽取和解析两个部分.这里Mysql日志主要是指binlog日志.二进制日志由配置文件的log-bin选项负责启用,Mysql服务器将在数据根 ...
- 腾讯工程师带你深入解析 MySQL binlog
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 本文由 腾讯云数据库内核团队 发布在云+社区 1.概述 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的red ...
随机推荐
- ProtocolBuffer在Android端的解析
开题篇 近期公司在使用Protocol Buffer替代原先的json作为移动端的数据交互格式.虽然服务端和CTO把这项新技术吹的天花乱坠,说什么体积小,不易被破解乱七八糟的.可是作为Android端 ...
- 《C语言及程序设计》实践參考——分数的累加
返回:贺老师课程教学链接 项目要求 [项目1:分数的累加]编程序.输出1/3-3/5+5/7-7/9-+19/21的结果提示:假设直接解决上面的问题有困难.能够设计一条"由易到难" ...
- kafka 安装步骤
kafka安装文档 1.解压缩(官网下载:http://kafka.apache.org/downloads.html) tar -xzf kafka_2.10-0.8.2.0.tgz cd kafk ...
- 数码相机常用CCD/CMOS尺寸对比
数码相机的关键元件CCD或CMOS又称为“影像传感器”,其作用相当于感光胶片.CCD尺寸越大,采集光线的效果越好,画面记录的信息就越多,保留的细节也就越丰富,所以图像更完美漂亮. CCD尺寸的大小与像 ...
- Python+selenium之读取配置文件内容
Python+selenium之读取配置文件内容 Python支持很多配置文件的读写,此例子中介绍一种配置文件的读取数据,叫ini文件,python中有一个类ConfigParser支持读ini文件. ...
- jQuery中如何给动态添加的元素绑定事件
jquery中绑定事件一般使用bind,或者click,但是这只能是对已经加载好的元素定义事件,那些后来添加插入的元素则需要另行绑定.在1.7版本以前使用live.但是在1.8版本以后推荐使用on.这 ...
- 编写高质量代码--改善python程序的建议(四)
原文发表在我的博客主页,转载请注明出处! 建议十八:有节制的使用from...import语句 python提供了三种方式引入外部模块: import语句 from...import... __imp ...
- python中的json和pickle
author:headsen chen date::2018-04-10 09:56:54 json模块和pickle模块: 这是用于序列化的两个模块: 概念介绍:json和pickle模块是将数据 ...
- x-webkit-speech语音搜索
如果你没看到语音图标说明你的浏览器不支持x-webkit-speech 换个chrome你会发现输入框的右侧出现语音小图标.
- Spring MVC 多语言化的实践和学习
一.主要参考: SpringMVC简单实现国际化/多语言 - CSDN博客 https://blog.csdn.net/u013360850/article/details/70860144/ 二.总 ...