0

0

MySQL Row格式Binlog的解析(1)

php中文网

php中文网

发布时间:2016-06-01 13:08:14

|

2002人浏览过

|

来源于php中文网

原创

用mysql 行格式的复制的slave经常会遇到复制出错1062和1032 错误,一般是镜像异常宕机导致主从复制数据不一致所致,但是有些库本身很大,重建成本很大,并且这些库的数据一致性用户可能都不是太关心的,所以之前的处理办法一般是遇到主键冲突的就跳过,遇到找不到key的就用mysqlbinlog解析一下 把数据补出来,但是这种方法太人肉话,处理起来很慢,所以之前做过一个自动修数据的工具,也是解析binlog日志,然后生成sql语句去执行。

做这个工具还有另外一个用途,既然能解析BINLOG日志,这样也可以做基于BINLOG的恢复,当然这个功能之前阿里也有人做过,但是做的方法不太一样,可以参考MySQL的 flashback.

解析BINLOG需要知道一下几点:

  1.         出现异常的start-position
  2.         异常结束的end-position

因为是在Slave机器上运行,所以这里解析的全部都是relay log.

通过show slave status 可以清楚的知道

  • start-psoition: Relay_Log_Pos
  • end-position : 这个信息并不能直接从show slave status  里面获得,这个要算一下,计算方法:

      end-position = Relay_Log_Pos + (end_log_pos - Exec_Master_Log_Pos)

              (end_log_pos - Exec_Master_Log_Pos) 这个就代表这个事物从开始到出错执行的字节数。

      end_log_pos  在show slave status 的错误信息里面也有,取出来就可以了。

知道了起始位置和结束位置,剩下的就可以解析了。如果不清楚binlog event的可以看下官方文档:

http://dev.mysql.com/doc/internals/en/binlog-event.html

 写代码的过程中也大量参考了文档。

我使用python进行解析的,其实用什么语言都一样,步骤如下:

     

  1.           首先seek到起始位置
  2.           解析第一个event type ,如果是table_map_event 开启解析,如果不是就跳过,因为如果是一个正常的语句在ROW格式里记录的方式肯定是table_map_event + 具体的操作,所以如果第一个不是table_map_event 那么要么就是binlog有损坏 要么就是起始位置不对。
  3.           如果解析到了tabl_map_event,下面对我们有用的event类型也就三个:insert event / update event /delete event, 当解析掉这个event 我们基本上就可以拼凑出一个SQL语句了。
  4.           然后继续解析下一个table_map_evnt 以此类推,就能解析出很多个SQL语句。

 

基本过程就是这样,那么怎么解析呢

首先说说event:

 基本上所有的event 格式都是一样的,都是由header + data 这两部分组成。

header 里面都是固定的,不同的event可变部分在DATA里面。

DATA分为fixed part 和variable part.

header  格式

          | timestamp(0:4)| type_code(4:1)| server_id(5:4)| event_length(9:4)| next_position(13:4) | flags(17:2)| extra_header(19:x-19)|

data 格式

         |fix_data x:y  |  variable_data  

header 说明 :

  •        timestamp 时间戳
  •        type_code  event类型 很有用
  •        server_id 没啥用
  •        event_lenght 整个event长度包括header
  •        next_position   下个event的position 很有用
  •        flags 没用
  •        extra_header 这个目前都没啥用

所以整个header一共19字节,DATA部分占用字节数:event_length - 19

下面说一下几种用到的BINLOG格式:

  • TABLE_MAP_EVENT: 19
  • WRITE_ROWS_EVENT : 23
  • UPDATE_ROWS_EVENT : 24
  • DELETE_ROWS_EVENT :  25

这里要注意一下,从MySQL5.6.2 开始 event的type 变化了,所以导5.6的需要改一下,5.6的我还没有详细的测试过,不知道还有什么坑。

  •     #mysql5.6.2 events
  •     # WRITE_ROWS_EVENT= 30
  •     # UPDATE_ROWS_EVENT= 31
  •     # DELETE_ROWS_EVENT= 32
  •     # INCIDENT_EVENT= 26

     

因为header部分都一样,所以直接说DATA部分了。

TABLE_MAP_EVENT

Data:

     Fixed data:

  •                Table_id (6bytes)
  •                extra  not use (2bytes)

     Variable data     

  •                Schema_length (1bytes)
  •                Schame name (Schema_length  size )
  •                0  //空字符占一字节
  •                Table length (1bytes)
  •                Table name (table length size)
  •                0  //空字符占一字节
  •                Column size (变长,最多存8个byte,最大为2的64次方)
  •                Coulmn type (column size bytes )

我们能从table_map_event 里面得到什么?

 没错 主要能得到的就是库名和表名还有字段类型

表明和库名都好弄,直接读出来不用转,字段类型MySQL还有一个专门的转换表,每一个字节对应一个字段类型。

http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::MYSQL_TYPE_DATETIME

PicWish
PicWish

推荐!专业的AI抠图修图,支持格式转化

下载

那么现在表表库名字段类型都有了,感觉还少了字段名称,字段名称直接去MySQL里面去查。

sql= ("select * from information_schema.columns where table_schema='

%s’"

           " and table_name=

'%s’")

这样我们这些元数据信息都有了,就需要解析具体的数据了,然后把解析好的数据直接填进去。

那么下面就只剩下如何解析别的event格式了。

先从WRITE_ROWS_EVENT 开始:

WRITE_ROWS_EVENT 其实就是一个insert操作,前面也说过每一份event的header都是一样的,只是DATA部分有区分而已,所以WRITE_ROWS_EVENT也一样,header部分为19字节,DATA部门为event_length-19字节。

那么DATA部分中的fixed data 和variables data各是什么呢?

Fixed data :

  •      Table_id (6bytes)
  •      extra  not use (2bytes)

Variables data :

  • col_num  (dynamic),一般是1bytes.
  • map_col (table bitmap)
  • Record 

可以看到fixed data 部分有用的信息不多,可能table_id 还有些用,重要的在variables data 部分。

  • col_num  代表字段的个数占用字节数是可变的,一般一字节就够了,1字节/2的八次方 一般也很难有表有几百个字段。
  • map_col  这个代表字段是否为空
  • Record  这个就是具体的记录内容。

怎么解析Record?

Record的格式是bit_map + record 的结构。

bit_map 的每一位代表字段是否为空,所以bit_map占用的字节数为:((columns+7)/8)

比如1100 代表一共四个字段,前两个字段为非空,后两个为NULL,为NULL的数据在record里面是不记录的。

所以呢,首先根据bitmap 判断字段是否为空,如果不为空则拿程序继续往下扫描,如果为空则判断下一个字段是否为空。

至此一个insert语句基本上是解析完了。

除此之外DELETE_ROWS_EVENT 基本上和insert一样。

UPDATE_ROWS_EVENT 稍微有一点点特别,UPDATE_ROWS_EVENT 也是bitmap + record ,但是Update包含更新前像和后像,所以一条Update的格式为

bitmap + record (前像) + bitnap + record (后像) 

基本上简单的一条语句就是这样:

table-map-event + insert/update/delete event

那么可能会出现这样的情况比如:

insert values (),(),()  或者delete id in (…)

一条SQL操作很多条记录的情况。

那么这种record 的格式就变成 record = (bitmap + data) +  (bitmap + data) .. 直到解析完为止

所以扫描的时候一定要把这个event扫描完,不然很容易出错。

这里先简单的介绍一下如何解析BINLOG吧,下面会再详细解析如何解析各个不同类型的字段。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

115

2025.12.24

拼豆图纸在线生成器
拼豆图纸在线生成器

拼豆图纸生成器有PixelBeads在线版、BeadGen和“豆图快转”;推荐通过pixelbeads.online或搜索“beadgen free online”直达官网,避开需注册的诱导页面。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

82

2025.12.24

俄罗斯搜索引擎yandex官方入口地址(最新版)
俄罗斯搜索引擎yandex官方入口地址(最新版)

Yandex官方入口网址是https://yandex.com。用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

546

2025.12.24

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

150

2025.12.24

php框架基础知识汇总
php框架基础知识汇总

php框架是构建web应用程序的架构,提供工具和功能,以简化开发过程。选择合适的框架取决于项目需求和技能水平。实战案例展示了使用laravel构建博客的步骤,包括安装、创建模型、定义路由、编写控制器和呈现视图。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

20

2025.12.24

Word 字间距调整方法汇总
Word 字间距调整方法汇总

本专题整合了Word字间距调整方法,阅读下面的文章了解更详细操作。

47

2025.12.24

任务管理器教程
任务管理器教程

本专题整合了任务管理器相关教程,阅读下面的文章了解更多详细操作。

7

2025.12.24

AppleID格式
AppleID格式

本专题整合了AppleID相关内容,阅读专题下面的文章了解更多详细教程。

12

2025.12.24

csgo视频观看入口合集
csgo视频观看入口合集

本专题整合了csgo观看入口合集,阅读下面的文章了知道更多入口地址。

371

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号