MYSQL Binlog协议分析

此处不讨论建立连接,验证和handshake的交互协议

Binlog协议

一个MYSQL 通信包由包头包体组成

包体根据具体的交互协议有自身的组成结构, 在binlog消息体组成结构如下

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

| 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              |

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

注意: 消息体里组成是包括2部分的,第一个字节是master发送给slave的errorcode, 第二个字节开始才是具体消息, 所以一个完整的MYSQL binlog通信包组成如下

 
   

一次binlog复制通信包含若干个binlog通信包

我们通过抓包工具抓取一次binlog复制来分析

我们在master里更新了一条数据, 产生了 41 这条通信数据, 里面包含了4个mysql binlog通信包

第一个binlog事件消息

头3个字节 45 00 00就是消息长度, 注意,在mysql协议里,数值类型是用小序列来传输数据的(小序列: 低位先传), 这条消息里实际消息长度内容是 00 00 45 , 也就是69(45是16进制, 69是10进制)

第4个字节2c是master传过来的序号

第5个字节00时errorcode, 0表示没有错误, 其他是错误

第6~9  4个字节是timestamp

第10 个字节02 是event type, 比如query, insert, update,delete等的类型码

第11-14个字节是serverid, 这里是02 00 00 00, 也是小序列

第15~19个字节是eventlengthoffset, 这里是44 00 00 00, 也是小序列

第二个binlog事件消息

结构和第一个基本一样, 只是消息长度,序号,eventtype等内容不一样

以上是原生mysql复制binlog的交互协议情况, 如果开启了semi半同步, 协议就发生变化, tcp通信次数, 包体结构等都和原来的有差异

抓包分析:

我们在master里更新了一条数据, 产生了 5 这条通信数据, 里面包含了5个mysql binlog通信包, 比原生的多了1条, 而且包结构也变成了以下结构

 
   

第一个binlog事件消息是新增的事件

第6个字节是新增的字节码, ef是固定的值,表示这是个semi的消息

第7个字节是新增的字节码, 0或者1, 0表示不需要回一个ack给master, 1表示需要, 一次复制通信(包含5个binlog事件)只有最后一个binlog事件的值为1

第8个字节开始就是具体消息, 和原生的一样

最后一个binlog事件消息

第7个字节值是1 ,  表示要返回一个ack给master

以下就是ack给master的内容

Slave ack给master 的消息是7这条通信数据

第1-3个字节师消息长度,这里的内容是12 00 00, 十进制内容是18

第4个字节是序号 , 这里是0, (注意: 每次tcp交互里这个序号都被重至为0)

第5个字节是semi标示 ,固定为ef

第6~14个字节,一共8个字节表示位置offset, ef 0a 00 00 00 00 00 00 同样是小序列

第15个字节开始是binlog的文件名 每个字节存储的是ascii码, 如这里的4f=O, 4e=N,2e=.,30=0,36=6, 就是ON.000006

如果安装了semi插件后,并不启用semi同步,就不会发送ack给master, 就是上面7这个数据包不会发送

Master要发送semi字节给slave前提是slave连接上master后必须发送SET @rpl_semi_sync_slave= 1 指令给master, 看下面抓包效果

1c 00 00 00 是包头

0x03 是指令码       COM_QUERY

53开始后面的字节都是具体字符串的ascii码

完整事件流

Slave连接上master后, master 首先会发ROTATE_EVENT和FORMAT_DESCRIPTION_EVENT 2个事件给slave, ROTATE_EVENT事件告诉slave下一个要读取的binlog(可以理解成初始化要读取的binlog)

Master发生一个插入sql, 如insert into test1 values(15), 分别发送给slave的事件是ANONYMOUS_GTID_LOG_EVENT-->QUERY_EVENT-->TABLE_MAP_EVENT-->WRITE_ROWS_EVENT-->XID_EVENT

(1)

ANONYMOUS_GTID_LOG_EVENT

(2)

QUERY_EVENT

header {

version: 1

logfileName: "20170105-162017-bin.000001"

logfileOffset: 1920

serverId: 1

serverenCode: "UTF-8"

executeTime: 1508809530000

sourceType: MYSQL

schemaName: ""

tableName: ""

eventLength: 72

}

entryType: TRANSACTIONBEGIN

storeValue: " \354\001"

(3)

TABLE_MAP_EVENT

(4)

WRITE_ROWS_EVENT

header {

version: 1

logfileName: "20170105-162017-bin.000001"

logfileOffset: 2040

serverId: 1

serverenCode: "UTF-8"

executeTime: 1508809530000

sourceType: MYSQL

schemaName: "test"

tableName: "test1"

eventLength: 40

eventType: INSERT

}

entryType: ROWDATA

storeValue: "\b\333\001\020\001P\000b\035\022\033\b\000\020\004\032\002id \000(\0010\000B\00215R\aint(11)"

(5)

XID_EVENT

header {

version: 1

logfileName: "20170105-162017-bin.000001"

logfileOffset: 2080

serverId: 1

serverenCode: "UTF-8"

executeTime: 1508809530000

sourceType: MYSQL

schemaName: ""

tableName: ""

eventLength: 31

}

entryType: TRANSACTIONEND

storeValue: "\022\003184"

PS:

如果本地没有存储position,在slave启动的时候就会调用show master status 获取master 最新的position更新到本地

在实验中发现 master 的timeout时间设置很长, 当新日志送到canal, canal关闭,master由于收不到ack,一直hold着,再次启动canal, master hold住的事务能够进行下去,数据也落盘到master硬盘里,但再次启动的canal就没有收到之前中断掉的binlog(开始position是master最后的position)

mysql 协议分析的更多相关文章

  1. MySQL协议分析

    MySQL协议分析 标签: mysql 2015-02-27 10:22 1807人阅读 评论(1) 收藏 举报  分类: 数据库(19)    目录(?)[+]   1 交互过程 MySQL客户端与 ...

  2. MySQL协议分析2

    MySQL协议分析 议程 协议头 协议类型 网络协议相关函数 NET缓冲 VIO缓冲 MySQL API 协议头 ● 数据变成在网络里传输的数据,需要额外的在头部添加4 个字节的包头. . packe ...

  3. MySQL协议分析(2)

    MySQL协议分析(2) 此阶段是在压缩传输无加密条件下进行的协议分析 思路 结合Oracle官网的说明和自己用wireshark加python进行数据包分析 步骤 客户端与服务器端是否压缩的协商阶段 ...

  4. MySQL协议分析(1)

    MySQL协议分析 此阶段的协议分析是在未压缩未加密情况下的协议分析 思路: 结合Oracle官网和自己用wireshark抓的网络数据包进行协议分析 官网说明 mysql包共分为4段,格式如下: 第 ...

  5. mixer: mysql协议分析

    综述 要实现一个mysql proxy,首先需要做的就是理解并实现mysql通讯协议.这样才能通过proxy架起client到server之间的桥梁. mixer的mysql协议实现主要参考mysql ...

  6. mysql协议分析2---认证包

    主人看到navicat和mysql在那嘻嘻哈哈,眉来眼去的,好不快乐,忽然也想自己写个程序,直接去访问Mysql,虽然现在已经有很多现成的中间件可以直接拿来用了,程序只要负责写sql语句就行了,但是主 ...

  7. mysql协议分析1---报文的格式和基本类型

    navicat 和 mysql 是一对好基友,每天都有非常频繁的交流,主人在navicat上写下每条sql语句,轻轻的点了下执行按钮,navicat就飞快的把主人的指令传送到mysql那里,mysql ...

  8. mysql协议简析

    前言 如果要在命令行中连接mysql,最常用的便是 mysql -u root -p 这样指定用户名和密码 当然还可以使用远程连接 mysql -h 127.0.0.1 -u root -p 还有一种 ...

  9. Memcache的使用和协议分析详解

    Memcache的使用和协议分析详解 作者:heiyeluren博客:http://blog.csdn.NET/heiyeshuwu时间:2006-11-12关键字:PHP Memcache Linu ...

随机推荐

  1. runtime error (运行时错误)

    比如说: ①除以零 ②数组越界:int a[3]; a[10000000]=10; ③指针越界:int * p; p=(int *)malloc(5 * sizeof(int)); *(p+10000 ...

  2. Unity 3D的常用快捷键

    Unity中的常用快捷键 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Windows系统Unity3 ...

  3. 20155229 2016-2017-2 《Java程序设计》第五周学习总结

    20155229 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 第八章: Java中所有错误都会被打包为对象. 设计错误对象都继承自java.lang.Th ...

  4. SQL 存储过程入门(五)

    好久没来博客园留下点东西,忙到找工作,最近把工作落实了. 最近公司的业务都是存储过程开发,发现去维护起来相当困难. 由于是维护项目,产品很久前都发布了,然而有一些修改,让我们去修改现在的逻辑,去看懂人 ...

  5. PHP的extension_dir设置问题

    PHP安装时,extension_dir的路径要设成绝对路径:extension_dir = "D:/Tools/php-7.0.5/ext", 不然如果设成extension_d ...

  6. nginx location正则写法(转载)

    nginx location正则写法 一个示例: location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # ...

  7. DOMContentLoaded 和 Load 事件 区别(待补充)

    javascript会阻塞dom的解析.当解析过程中遇到<script>标签的时候,便会停止解析过程,转而去处理脚本,如果脚本是内联的,浏览器会先去执行这段内联的脚本,如果是外链的,那么先 ...

  8. Jenkins进阶-远程构建任务(4)

    开发过程中提交代码以后,如何不登录Jenkins就自动触发jenkins 任务来发布软件版本. 1.首先我们创建一个Jenkins任务. 2.选择"构建触发器"->勾选&qu ...

  9. loadrunner 函数解释

    一.lr_save_string 使用介绍1.该函数主要是将程序中的常量或变量保存为lr中的参数.格式: //将常量保存为参数lr_save_string("777"," ...

  10. Spring Cloud 入门 之 Hystrix 篇(四)

    原文地址:Spring Cloud 入门 之 Hystrix 篇(四) 博客地址:http://www.extlight.com 一.前言 在微服务应用中,服务存在一定的依赖关系,如果某个目标服务调用 ...