MySQL协议分析(结合PyMySQL)

MySQL Packets

当MySQL客户端或者服务端发送数据时,它会首先把数据分割成(2^24-1)bytes的包,然后给每个包加上packet header。

类型

名称

描述

int<3>

payload_length

负载长度,除了header的4字节

int<1>

sequence_id

序列ID

string

payload

实际负载

* 当数据大于16M时,payload_length设为 2^24−1 (ff ff ff)

* 序列ID在0~255循环,在新命令开始的时候重置为0

PyMySQL相关代码:

buff = b''

while True:

packet_header = self._read_bytes(4)

if DEBUG: dump_packet(packet_header)

btrl, btrh, packet_number = struct.unpack('

bytes_to_read = btrl + (btrh << 16)

if packet_number != self._next_seq_id:

raise err.InternalError("Packet sequence number wrong - got %d expected %d" %

(packet_number, self._next_seq_id))

self._next_seq_id = (self._next_seq_id + 1) % 256

recv_data = self._read_bytes(bytes_to_read)

if DEBUG: dump_packet(recv_data)

buff += recv_data

# https://dev.mysql.com/doc/internals/en/sending-more-than-16mbyte.html

if bytes_to_read == 0xffffff:

continue

if bytes_to_read < MAX_PACKET_LEN:

break

Replication协议

Binlog网络流

客户端首先发送一个COM_BINLOG_DUMP类型的包,如成功,Server响应返回Binlog网络流。

包负载如下表:

长度

字段

描述

1

COM_BINLOG_DUMP(0x12)

Binlog DUMP请求

4

binog-pos

binlog文件中的位置

2

flags

BINLOG_DUMP_NON_BLOCK(0x01)

4

server-id

slave的server id

string[EOF]

binlog-filename

master上的binlog文件名

python-mysql-replication的相关代码:(BinLogStreamReader.__connect_to_stream)

if not self.auto_position:

# only when log_file and log_pos both provided, the position info is

# valid, if not, get the current position from master

if self.log_file is None or self.log_pos is None:

cur = self._stream_connection.cursor()

cur.execute("SHOW MASTER STATUS")

self.log_file, self.log_pos = cur.fetchone()[:2]

cur.close()

prelude = struct.pack('

+ int2byte(COM_BINLOG_DUMP)

if self.__resume_stream:

prelude += struct.pack('

else:

prelude += struct.pack('

if self.__blocking:

prelude += struct.pack('

else:

prelude += struct.pack('

prelude += struct.pack('

prelude += self.log_file.encode()

如果binlog-filename为空,服务端会自动定位,返回第一个已知的binlog,这时候客户端发送的包为COM_BINLOG_DUMP_GTID。

包负载如下图:

长度

字段

1

COM_BINLOG_DUMP_GTID

2

flags

4

server-id

4

binlog-filename-len

string[len]

binlog-filename

8

binlog-pos

4

data-size

string[len]

data

python-mysql-replication的相关代码:(BinLogStreamReader.__connect_to_stream)

else:

# Format for mysql packet master_auto_position

#

# All fields are little endian

# All fields are unsigned

# Packet length uint 4bytes

# Packet type byte 1byte == 0x1e

# Binlog flags ushort 2bytes == 0 (for retrocompatibilty)

# Server id uint 4bytes

# binlognamesize uint 4bytes

# binlogname str Nbytes N = binlognamesize

# Zeroified

# binlog position uint 4bytes == 4

# payload_size uint 4bytes

# What come next, is the payload, where the slave gtid_executed

# is sent to the master

# n_sid ulong 8bytes == which size is the gtid_set

# | sid uuid 16bytes UUID as a binary

# | n_intervals ulong 8bytes == how many intervals are sent for this gtid

# | | start ulong 8bytes Start position of this interval

# | | stop ulong 8bytes Stop position of this interval

# A gtid set looks like:

# 19d69c1e-ae97-4b8c-a1ef-9e12ba966457:1-3:8-10,

# 1c2aad49-ae92-409a-b4df-d05a03e4702e:42-47:80-100:130-140

#

# In this particular gtid set, 19d69c1e-ae97-4b8c-a1ef-9e12ba966457:1-3:8-10

# is the first member of the set, it is called a gtid.

# In this gtid, 19d69c1e-ae97-4b8c-a1ef-9e12ba966457 is the sid

# and have two intervals, 1-3 and 8-10, 1 is the start position of the first interval

# 3 is the stop position of the first interval.

gtid_set = GtidSet(self.auto_position)

encoded_data_size = gtid_set.encoded_length

header_size = (2 + # binlog_flags

4 + # server_id

4 + # binlog_name_info_size

4 + # empty binlog name

8 + # binlog_pos_info_size

4) # encoded_data_size

prelude = b'' + struct.pack('

+ int2byte(COM_BINLOG_DUMP_GTID)

# binlog_flags = 0 (2 bytes)

prelude += struct.pack('

# server_id (4 bytes)

prelude += struct.pack('

# binlog_name_info_size (4 bytes)

prelude += struct.pack('

# empty_binlog_name (4 bytes)

prelude += b'\0\0\0'

# binlog_pos_info (8 bytes)

prelude += struct.pack('

# encoded_data_size (4 bytes)

prelude += struct.pack('

# encoded_data

prelude += gtid_set.encoded()

Binlog Event

Binlog Event Header

Binlog事件的包头长度为13或19字节,根据binlog版本的不同。

长度

字段

描述

4

timestamp

unix纪年起的秒数

1

event_type

Binlog事件类型

4

server-id

服务端server id

4

event-size

事件大小(包含header)

4

log_pos

下一事件的位置

2

flags

Binlog事件flag

python-mysql-replication的相关代码:(BinLogPacketWrapper.__init__)

# OK value

# timestamp

# event_type

# server_id

# log_pos

# flags

unpack = struct.unpack('

# Header

self.timestamp = unpack[1]

self.event_type = byte2int(unpack[2])

self.server_id = unpack[3]

self.event_size = unpack[4]

# position of the next event

self.log_pos = unpack[5]

self.flags = unpack[6]

# MySQL 5.6 and more if binlog-checksum = CRC32

if use_checksum:

event_size_without_header = self.event_size - 23

else:

event_size_without_header = self.event_size - 19

Binlog事件类型

python-mysql-replication的相关代码:(BinLogPacketWrapper.__init__)

__event_map = {

# event

constants.QUERY_EVENT: event.QueryEvent,

constants.ROTATE_EVENT: event.RotateEvent,

constants.FORMAT_DESCRIPTION_EVENT: event.FormatDescriptionEvent,

constants.XID_EVENT: event.XidEvent,

constants.INTVAR_EVENT: event.IntvarEvent,

constants.GTID_LOG_EVENT: event.GtidEvent,

constants.STOP_EVENT: event.StopEvent,

constants.BEGIN_LOAD_QUERY_EVENT: event.BeginLoadQueryEvent,

constants.EXECUTE_LOAD_QUERY_EVENT: event.ExecuteLoadQueryEvent,

# row_event

constants.UPDATE_ROWS_EVENT_V1: row_event.UpdateRowsEvent,

constants.WRITE_ROWS_EVENT_V1: row_event.WriteRowsEvent,

constants.DELETE_ROWS_EVENT_V1: row_event.DeleteRowsEvent,

constants.UPDATE_ROWS_EVENT_V2: row_event.UpdateRowsEvent,

constants.WRITE_ROWS_EVENT_V2: row_event.WriteRowsEvent,

constants.DELETE_ROWS_EVENT_V2: row_event.DeleteRowsEvent,

constants.TABLE_MAP_EVENT: row_event.TableMapEvent,

#5.6 GTID enabled replication events

constants.ANONYMOUS_GTID_LOG_EVENT: event.NotImplementedEvent,

constants.PREVIOUS_GTIDS_LOG_EVENT: event.NotImplementedEvent

}

mysql协议分析 row_MySQL协议分析(结合PyMySQL)相关推荐

  1. mysql binlog协议_mysql binlog协议分析--具体event

    这几天在修改canal, 连接mysql和maria接收到的event有所区别 拿一个简单的insert sql来举例 mysql 会有以下几个event写入到binlog里 1.ANONYMOUS_ ...

  2. 接口协议之抓包分析 TCP 协议

    TCP 协议是在传输层中,一种面向连接的.可靠的.基于字节流的传输层通信协议. 环境准备 对接口测试工具进行分类,可以如下几类: 网络嗅探工具:tcpdump,wireshark 代理工具:fiddl ...

  3. 透视RPC协议:SOFA-BOLT协议源码分析

    前提 最近在看Netty相关的资料,刚好SOFA-BOLT是一个比较成熟的Netty自定义协议栈实现,于是决定研读SOFA-BOLT的源码,详细分析其协议的组成,简单分析其客户端和服务端的源码实现. ...

  4. 计算机网络协议教案,计算机网络实验教案(6)网络协议分析-IP协议3.pdf

    计算机网络实验教案(6)网络协议分析-IP协议3.pdf (2页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 <计算机网络实验> ...

  5. Wireshark数据抓包分析(网络协议篇)1.2安装Wireshark

    Wireshark数据抓包分析(网络协议篇)1.2安装Wireshark Wireshark(前称Ethereal)是一个网络包分析工具.该工具主要是用来捕获网络包,并显示包的详细情况.本节将分别介绍 ...

  6. Wireshark数据抓包分析(网络协议篇)第1章网络协议抓包概述

    Wireshark数据抓包分析(网络协议篇)第1章网络协议抓包概述 网络协议是用于不同计算机之间进行网络通信的.网络协议是网络上所有设备(如网络服务器.计算机.交换机.路由器等)之间通信规则的集合,它 ...

  7. Wireshark数据抓包分析——网络协议篇

    Wireshark数据抓包分析--网络协议篇 Wireshark是目前最受欢迎的抓包工具.它可以运行在Windows.Linux及MAC OS X操作系统中,并提供了友好的图形界面.同时,Wiresh ...

  8. linux nDPI 协议检测 源码分析

    关于nDPI的基本功能就不在这介绍了,有兴趣了解的读者可以阅读官方的快速入门指南:https://github.com/ntop/nDPI/blob/dev/doc/nDPI_QuickStartGu ...

  9. SSL/TLS 协议简介与实例分析

    作者:drinkey 以前读RFC时总结的一篇文章,主要介绍了SSL/TLS协议的相关知识,包括协议本身以及简单的密码学概念,以及用实例解析了HTTP over SSL的协商过程,在最后简要列出了SS ...

最新文章

  1. Attention is All You Need?LSTM提出者:我看未必
  2. java中所有函数都是虚函数_关于Java:虚拟函数与纯虚函数之间的区别是什么?...
  3. skywalking使用方法_基于SkyWalking的监控系统安装与使用教程 PDF 下载
  4. 心理压力如何测试软件,心理压力测试 缓解压力有什么办法
  5. Nuget官方包源问题
  6. 深入理解iPhone委托模式兼谈iPhone生命周期
  7. mysql建立软链接_MySQL(一)安装
  8. paip.c++ bcb string 转换操作大总结.
  9. MISC图片隐写之foremost
  10. jar逆向工具Luyten
  11. OAuth 2.0授权框架详解
  12. 使用计算机眼睛保护方法有哪些,使用电脑保护眼睛的方法有哪些
  13. 提交健康信息服务器拥挤,python hpilo 监控 hp ilo 服务器健康信息
  14. 国内手机号码11位的原因
  15. mysql mod如何使用_MySQL MOD()用法及代码示例
  16. 美国大学生数学建模竞赛赛题题型分类
  17. PostgreSQL 源码解读(31)- 查询语句#16(查询优化-表达式预处理#1)
  18. solidworks批量图号分离_SolidWorks2014基于宏实现快速图号名称分离.docx
  19. 遥感数据处理之哨兵5P数据处理
  20. 【日期】根据日期求星期

热门文章

  1. python实现矩阵共轭和共轭转置
  2. 自定义控件其实很简单2/12
  3. geoserver热图
  4. Java多线程学习笔记(三)休眠(sleep),让步(yield),插队(join)
  5. rx580显卡运行不了Linux,RX580吃鸡不流畅原因找到了 真相令人无语
  6. 英飞凌基础学习笔记PSI5(Peripheral Sensor Interface)
  7. 遥感图像存储格式BSQ/BIL/BIP
  8. 使用 Plotly 和 ChartJS 图形库创建 Flask 仪表板
  9. 辩论赛计算机软件更重要论据,善意的谎言辩论会正方观点要例子
  10. RHEL-UEFI引导恢复规范