mysql格式分隔符row_MySQLRow格式Binlog的解析(1)

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

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

解析BINLOG需要知道一下几点:出现异常的start-position

异常结束的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进行解析的,其实用什么语言都一样,步骤如下:

首先seek到起始位置

解析第一个event type ,如果是table_map_event 开启解析,如果不是就跳过,因为如果是一个正常的语句在ROW格式里记录的方式肯定是table_map_event + 具体的操作,所以如果第一个不是table_map_event 那么要么就是binlog有损坏 要么就是起始位置不对。

如果解析到了tabl_map_event,下面对我们有用的event类型也就三个:insert event / update event /delete event, 当解析掉这个event 我们基本上就可以拼凑出一个SQL语句了。

然后继续解析下一个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 dataSchema_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

那么现在表表库名字段类型都有了,感觉还少了字段名称,字段名称直接去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吧,下面会再详细解析如何解析各个不同类型的字段。

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:php中文网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/409105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[机器学习笔记] Note1--机器学习简介

阅读本文大约需要 2 分钟 本文结构: 什么是机器学习监督学习(Supervised Learning)非监督学习(Unsupervised Learning)课程小结 这是学习 Andrew Ng 在 Coursea 上的机器学习课程所做的笔记。 什么是机器学习 对于机器学习,并没有一个一致认同的定义…

cellet 的相关线程

cellet启动了两个进程,分别是cellet-resource和cellet进程,这两个进程分别启动了一系列的线程: cellet-resource: StartExecutorReceiver ResourceInfoSender ExecutorControlReceiver 这个进程启动上述线程之后就会监控,是否其子…

mysql执行过程五步_简单五步教你搭建MySQL主从复制

环境主机:172.17.0.2从机:172.17.0.3环境:CentOS7MySQL:5.6.38目标:实现主机172.17.0.2到从机172.17.0.3基于Binlog的主从复制目前MySQL提供两种方式主从复制:基于Binlog(我们此篇就是基于Binlog的主从复制…

[机器学习笔记] Note2--单变量线性回归

继续是机器学习课程的笔记,这节介绍的是单变量线性回归算法,线性回归算法也是一个比较基础的算法。 模型表达 首先是以房屋交易问题为例,假设我们回归问题的训练集如下表所示: Size in feet2feet2(x)Price($) in 1000’s (y)21…

css格式化文本

选择字体 font-family: "Times New Roman", Times, serif; 注意:字体名称中包含多个单词要用("")括起来。 字体颜色 color:#cccccc(16进制) color: rgb(0%, 100%, 0%) 或者 color: rbg(0, 255, 0) rgb颜色,百分数表示0-2…

[线性代数]Note 1--方程组的几何解释

这是记录麻省理工学院公开课:线性代数的笔记,网址是麻省理工公开课:线性代数 第一节课说的是有关方程组的几何解释。网址是方程组的几何解释 首先是介绍方程组的几何解释,提出可以用矩阵表示,然后矩阵表示有两种表达方…

linux打印mysql堆栈_第25问:MySQL 崩溃了,打印了一些堆栈信息,怎么读?

问题在 09 问中,我们开启了 coredump 功能,在 MySQL 崩溃时获得了有用的 coredump 信息。那如果没开启 coredump,仅有 error log 中的堆栈信息,我们如何分析有效的信息?实验我们沿用 09 问中的 MySQL 崩溃的场景&#…

winform中treeview控件实现部分节点显示checkbox

用过asp.net的应该知道,要在treeview中实现上述功能可以使用ShowCheckBox 属性指定那些节点显示checkbox哪些不显示,可是winform中的treeview只提供一个ShowCheckBoxes 属性,要么全部节点显示checkbox,要不全部不显示,而指定节点没…

[机器学习笔记] Note3--多变量线性回归

继续是机器学习课程的笔记,这节课介绍的是多变量的线性回归。 多变量线性回归 多维特征 上节课介绍的是单变量的线性回归,这节课则是进一步介绍多变量的线性回归方法。 现在假设在房屋问题中增加更多的特征,例如房间数,楼层等…

mysql主键long_MySQL主键设计

[TOC]在项目过程中遇到一个看似极为基础的问题,但是在深入思考后还是引出了不少问题,觉得有必要把这一学习过程进行记录。MySQL主键设计原则MySQL主键应当是对用户没有意义的。MySQL主键应该是单列的,以便提高连接和筛选操作的效率永远也不要…

linux 常用工具

sqlitebrowser sudo apt-get install sqlitebrowser 转载于:https://www.cnblogs.com/xxhong/archive/2013/03/01/2938585.html

[机器学习笔记] Note4--逻辑回归

继续是机器学习课程的笔记,这节课会介绍逻辑回归。 分类问题 这节课会介绍的是分类问题,其结果是离散值。分类问题的例子有判断电子邮件是否是垃圾邮件;判断肿瘤是良性还是恶性;判断一次金融交易是否是欺诈等等。 首先从二元的…

华为日历怎么显示一月_华为手机日历怎么设置

大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。设置华为手机日历的方法:1、打开“时钟”,点击右下角的设置;2、点击“日期和时间”;3、关闭“自动确定日期和时间”和“自动确定时区”…

javascript中children和childNodes的区别

javascript中children和childNodes的区别 1、childNodes:它是标准属性,它返回指定元素的子元素集合,包括HTML节点,所有属性,文本节点。 可以通过nodeType来判断是哪种类型的节点,只有当nodeType1时才是元素…