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. centos7 mysql的安装

    本文记录centos7安装mysql的一些过程与遇到的一些坑 下载mysql的压缩包,直接从官网上面下载,链接:http://dev.mysql.com/downloads/mysql/ 选择 MyS ...

  2. Linux C:access()时间条件竞争漏洞

    access()函数用来检查调用进程是否可以对指定的文件执行某种操作. ================================================================ ...

  3. 动态更新 HTML 内容 —— AJAX

    通过 JavaScript 加载数据,在不刷新网页的情况下,更新网页内容的技术,称为 AJAX(Asynchronous JavaScript and XML,异步 JavaScript 和 XML) ...

  4. 4天赚4000RMB 引流秘籍 卑鄙无耻之徒

    他说:有什么引流秘籍吗? 我说:贴吧.天涯.论坛都不错,只要不明着发广告,每天被动加几十个人轻轻松松的,如果执行力好,几百上千都有可能. 他说:我该怎么操作. 我说:网上找点好的帖子,简单修改一下部分 ...

  5. Jsonp的实现

    JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题. 由于同源策略,一般来说位于 server1.com 的网页无法与不是 serv ...

  6. liunx的文件系统及相关的基本命令

    1.ls     当前目录列表 2.cd 切换 3.cd ..    返回上一级 4.cat 文件      显示文件内容 5.mkdir 文件夹名    创建一个新的文件夹 6.rmdir 文件夹名 ...

  7. wireshark 抓包过滤器

    wireshark 抓包过滤器 https://www.cnblogs.com/laoxiajiadeyun/p/10365073.html 过滤器分为抓包过滤器和显示过滤器,抓包过滤器会将不满足过滤 ...

  8. 对象Date的方法

    Date()对象是js提供给我们的日期对象,可以利用它获取关于时间的量. var myDate = new Date() //首先构造一个时间对象,然后用对象的方法获取时间: 1.获取年份: var ...

  9. (7)random(随机模块)

    import random print(random.random()) #得到一个随机的数,但是随机的数的范围是(0,1),这里用小括号(开曲线)代表取不到0也取不到1,o-1之间只有小数,所以只能 ...

  10. jquery中not的用法[.not(selector)]

    描述: 从匹配的元素集合中移除指定的元素. 如果提供的jQuery对象代表了一组DOM元素,.not()方法构建一个新的匹配元素的jQuery对象,用于存放筛选后的元素.所提供的选择器是对每个元素进行 ...