首先,我们知道MySQL本身就带有replication的机制,我们需要伪造一个slave,向master注册,这样的话master才会发送binlog event。注册很简单,通过调用limysql.so中的cli_advanced_command(),指定binlog filename+position,向master发送COM_BINLOG_DUMP命令。在发送dump命令的时候,我们可以指定flag为BINLOG_DUMP_NON_BLOCK,这样master在没有可以发送的binlog event之后,就会返回一个EOF的包。数据包的具体格式如下:

例如COM_BINLOG_DUMP类型的数据包payload(数据包体)是这样的:

3.1.2 接收事件

通过调用libmysql.so库中的cli_safe_read()函数,获得master发过来的数据,每次获得一个事件记录的数据,cli_safe_read()的返回值标示了从master发送过来的数据的数据字节数。而发送过来的数据保存在mysql->net->read_pos数组中。

3.2 Binlog事件

通过调用libmysql.so库中的cli_safe_read()函数可以获取一次binlog事件。

MySQL的Binlog事件类型有27种,在MySQL5.6之后增加到38种,但是我们只介绍与ROW模式相关的事件,所有的event都含有如下通用的事件结构:

+===============================+

|      event header   |

+===============================+

|   event data     |

+===============================+

分别为事件头和事件体组成,而事件的内部结构随MySQL版本的不同而变化着,我们需要用到的版本为v4,用于mysql5.1及以上,其他版本就不做介绍了,想要了解的朋友可以参考官方文档。下图为v4版本的event header格式。

由于各个事件的事件头一致,这里我们就不重复介绍了,后面各个事件我们也将忽略对事件头字段的描述。

 

3.2.1 ROTATE_EVENT

ROTATE_EVENT,   记录了接下来要请求的binlog的信息。格式如下:

它里面其实就是标明下一个event所在的binlog filename和position。这里需要注意的是,当slave发送binlog dump之后,master会首先发送一个ROTATE_EVENT,用来告知slave下一个event所在的位置,然后才跟着其他事件。

3.2.2 QUERY_EVENT

QUERY_EVENT, 存储的是SQL,主要是一些与数据无关的操作,如begin,alter table,drop table,create table等。格式如下

  3.2.3 TABLE_MAP_EVENT

TABLE_MAP_EVENT,记录了某个table所对应的表信息,在其中存储了数据库名和表名等。格式如下:

在这个事件中我们需要注意的是,虽然我们可以用表的id标识符table_id来代表一个特定的表,但是因为alter table或rotate binlog event等原因,master会改变某个table的table_id,所以我们在外部不能使用这个table_id来索引某个table。

还需要关注的就是里面的column meta信息,后续我们解析ROW_EVENT的时候会根据这个来处理不同类型的数据。

3.2.4 ROWS_EVENT   

ROWS_EVENT,包含了insert,update,以及delete三种event,并且有v0,v1,v2三个版本。ROWS_EVENT的基本格式如下:

在这里MySQL5.6开始event的type发生变化了,所以MySQL5.6需要改一下,

所以为了我们软件的版本兼容性,我们需要在软件中支持不同的版本。

MySQL5.1~MySQL5.6

·        TABLE_MAP_EVENT:19

·        WRITE_ROWS_EVENT: 23

·        UPDATE_ROWS_EVENT: 24

·        DELETE_ROWS_EVENT:  25

MySQL5.6以上

·        TABLE_MAP_EVENT:19

·        WRITE_ROWS_EVENT: 30

·        UPDATE_ROWS_EVENT: 31

·     DELETE_ROWS_EVENT:  32

ROWS_EVENT的table_id跟TABLE_MAP_EVENT一样,虽然table_id可能变化,但是ROWS_EVENT和TABLE_MAP_EVENT的table_id是能保证一致的,所以我们也是通过这个来找到TABLE_MAP_EVENT的。

为了节省空间,ROWS_EVENT里面对于各列状态都是采用bitmap的方式来处理的。首先我们需要得到column present bitmap的数据,这个值用来表示当前列的一些状态,如果没有设置,也就是某列对应的bit为0,表名该ROWS_EVENT里该列的数据,外部用null代替就可以了。

然后就是每个record里的bitmap,这个是用来表明一行实际的数据里面有哪些列是NULL的,如果该列为NULL,则为1。

在得到column_bitmap和null_bitmap后,我们就可以实际解析这行对应的数据了,对于每一列,首先判断是否column_bitmap标记了,如果为0,这跳过用null表示,然后再看是否null_bitmap里面标记了,如果为1,则表明为null。

但是,因为我们得到的是一行数据的二进制流,又如何将一列数据解析出来呢,这里就需要靠TABLE_MAP_EVENT里的column_meta了。Column_def中定义了该列的数据类型,对于一些特定的类型,譬如MYSQL_TYPE_LONG,MYSQL_TYPE_TINY等,长度都是固定的,所以我们可以直接读取对应长度的数据得到实际的值,但对于一些类型,则没有这么简单。这时候就需要通过meta来辅助计算了。举个例子:

MYSQL_TYPE_BLOB类型,meta为1表示的为tinyblob,第一个字节解释blob的长度,2表名的是shortblob,前两个字节为blob的长度等,而对于MYSQL_TYPE_VARCHAR,meta存储的则是string的长度,下一小节我们介绍每一种类型的计算方法。

3.2.5 XID_EVENT

XID_EVENT一般出现在一个事务操作之后或者其他语句提交之后。它的主要作用提交事务操作和把事件刷新至binlog文件中。里面存的是8个字节的事务ID号。

3.3 不同的数据类型的长度

上一节我们介绍了在不同事件的事件格式以及需要注意的事项,在其中ROWS_EVENT事件中,在record中bit_map之后的列数据中,针对不同的数据类型,可能在record中占用不同的字节,因从需要针对每种数据类型进行处理,

下面列出大部分常用数据类型的字节数和解析方法:

3.3.1 MYSQL_TYPE_INT家族

3.3.2 MYSQL_TYPE_DOUBLE家族

MYSQL_TYPE_NEWDECIMAL类型

声明语法为decimal(M,D),decimal参量的取值范围如下:

M为数字的最大数(精度),其范围为1~65,默认为10

D是小数点后面的数目(标度)。范围为0~30,但不得超过M

table_map_event中的metadata为2个字节,它会记录该类型的精度和标度,其中第一个字节表示精度,第二个字节表示精度。那么数据的长度是如何计算的呢?

比如说decimal(15,5)a=1234567890.12345,那么a的精度为15,标度为5,所以a的整数位最多为10,mysql中每9个数字用一个32位4个字节的×××来存储,剩下不够9个字节的按照如下方式:

intdig2byte[10] = {0,1,1,2,3,3,3,4,4,4};

该数组表示剩下几个字节的数字用几个字节存储。为什么这样做呢,我们知道一个int型变量能存储的最大整数位2^32,是一个十位数的整数,所以最多可以表示9位数的数字。binlog中的decimal按照小数点前后分别存储,所以a的整数位需要2个int型来存储,小数后的计算方式也一样,需要3个字节存储,所以decimal(15,5)在binlog中需要11个字节来存储数据

3.3.3 MYSQL_TYPE_STRING

处理该类型数据时,需要利用metadata辅助计算,metadata的前一个字节表示类型,后一个字节表示长度,如果类型为MYSQL_TYPE_SET和MYSQL_TYPE_EUM时,数据的长度则为后一个字节的大小。如果类型为

MYSQL_TYPE_STRING,第一个字节的数字即为该类型数据的长度。

3.3.4 MYSQL_TYPE_BIT

查看mysqlcapture实现代码

3.3.5 MYSQL_TYPE_DATA家族

3.3.6 MYSQL_TYPE_BLOB家族

Metadata为1,第一个字节表示长度,metadata为2,前两个字节表示长度,metadata为3,前三个字节表示长度,metadata为4,前四个字节表示长度。

3.3.7MYSQL_TYPE_VARCHAR

如果metadata小于256,则第一个字节表示数据的长度,如果metadata大于256

则前两个字节表示数据的长度。

转载于:https://blog.51cto.com/11461240/1765412

Mysql binlog 解析相关推荐

  1. log解析工具 px4_详解MySQL Binlog解析工具--binlog2sql,基于表级别的数据恢复

    概述 最近碰到某个表需要做数据回退,如果回退整个数据库动作又太大,所以用了binlog2sql来实现,这里先介绍一下binlog2sql的相关内容. binlog2sql是一个开源的Python开发的 ...

  2. MySQL Binlog 解析工具 Maxwell 详解

    maxwell 简介 Maxwell是一个能实时读取MySQL二进制日志binlog,并生成 JSON 格式的消息,作为生产者发送给 Kafka,Kinesis.RabbitMQ.Redis.Goog ...

  3. MySQL Binlog解析

    概述 MySQL的安装可以参考:Linux(CentOS)中常用软件安装,使用及异常--MySQL, VmTools MySQL关于Binlog的官方文档:The Binary Log 基于Binlo ...

  4. mysql binlog解析 c_解析MYSQL BINLOG二进制格式(9)--infobin解析binlog帮助文档

    原创:转载请说明出处谢谢! 上接 http://blog.itpub.net/7728585/viewspace-2133188/ 解析MYSQL BINLOG 二进制格式(1)--准备工作 http ...

  5. opentrace在mysql中使用_采用OpenReplicator解析MySQL binlog

    Open Replicator是一个用Java编写的MySQL binlog分析程序.Open Replicator 首先连接到MySQL(就像一个普通的MySQL Slave一样),然后接收和分析b ...

  6. mysql binlog 回退_MYSQL Binglog分析利器:binlog2sql使用详解

    大部分使用mysql的业务也都会开启binlog,用以记录数据库的更新操作.当然binlog的格式大家也都比较清楚,分别是statement.mixed.row模式.针对row格式的binlog,它以 ...

  7. binlog解析工具—my2sql

    文章目录 一.工具介绍 1.1 工具对比 1.2 用途 1.3 限制 1.4 性能对比 二.工具使用 2.1 参数说明 2.2 使用案例 一.工具介绍   my2sql是go版MySQL binlog ...

  8. MySQL Binlog 介绍

    Binlog 简介 MySQL中一般有以下几种日志: 日志类型 写入日志的信息 错误日志 记录在启动,运行或停止mysqld时遇到的问题 通用查询日志 记录建立的客户端连接和执行的语句 二进制日志 记 ...

  9. php读取binlog,PHP解析Mysql Binlog

    PHP解析Mysql Binlog,依赖于mysql-replication-listener库 详见:[https://github.com/bullsoft/php-binlog](https:/ ...

  10. mysql write rows_解析MYSQL BINLOG 二进制格式(5)--WRITE_ROW_EVENT

    展开阅读全文 原创:转载请说明出处谢谢! 上接 http://blog.itpub.net/7728585/viewspace-2133188/ 解析MYSQL BINLOG 二进制格式(1)--准备 ...

最新文章

  1. R语言ggplot2可视化分组散点图、将图例放置在图像内部的指定区域、自定义缩放图例中点形状pch的大小(增大或者缩小)、change size of shape elements
  2. 使用jquery获取url以及jquery获取url参数的方法
  3. hdu2594 简单KMP
  4. 富人为什么会富,穷人为什么穷?看完你就懂
  5. python实现异步的几种方式_终于搞明白了,异步Python比同步Python究竟快在哪里?...
  6. 清空本地_PyQt5播放实时视频流或本地视频文件
  7. 据说学编程的计算这题不超1分钟!
  8. 贝莱德集团CEO劳伦斯·芬克: 伟大的公司,都有一个长期战略
  9. 在OpenCV里实现Prewitt算子
  10. 吃鸡显示连接服务器超时,吃鸡 怎么显示连接超时 | 手游网游页游攻略大全
  11. 由 12306.cn 谈谈高并发+高负载网站性能技术
  12. 盘点近些年成功的游戏联名营销
  13. 刚才先入为主到了令人发指的地步
  14. linux微信原生版2.1.5,优麒麟版重新打包,适用于debian内核系统
  15. 【进程、线程和进程间通信】(三)进程间通信
  16. 阿里巴巴暑期实习用户体验研究员 面试经验+总结
  17. python pandas合并多个excel,三行Python代码,合并多个Excel文件
  18. 深度:保健产品市场正在经历深度震荡与变革转型,新时代环境下孕育哪些创新发展机会?
  19. KgoUI(1) 之 技术选型angular 和 vue
  20. 【redis】redis之持久化机制

热门文章

  1. 通过100个单词掌握英语语法(二十三)go
  2. javafx将数据库内容输出到tableview表格
  3. ZeroMQ API(一) 总序
  4. Linux基础介绍【第五篇】
  5. 《Entity Framework 6 Recipes》中文翻译系列 (11) -----第三章 查询之异步查询 (转)...
  6. AngularJs的TDD
  7. NoSQL之HBase
  8. 批量删除Cookie(实用)
  9. flash cs4中3D特性之PerspectiveProjection属性设置
  10. Isolate -- Be Forget Feature Of The Object-Orient Programming