解读 MySQL Client/Server Protocol: Connection & Replication(下)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 解读 MySQL Client/Server Protocol: Connection & Replication

Handshake Response Packet

建立连接的过程中,当客户端收到了服务端的 Initial Handshake Packet 后,需要向服务端回应一个 Handshake Response Packet ,包的数据格式如下图所示:

handshake_response_41

依次是:

4 个字节的整数,Capabilities Flags,一定要设置 CLIENT_PROTOCOL_41,对于 MySQL 5.x 版本,使用默认的身份认证方式,还需要对应的设置 CLIENT_PLUGIN_AUTHCLIENT_SECURE_CONNECTION

4 个字节的整数,包大小的最大值,这里指的是命令包的大小,比如一条 SQL 最多能多大。

1 个字节的整数,字符编码方式。

23 个字节的填充位,全是 0x00。

以 NUL(0x00)结尾的字符串,登录的用户名。

CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA 一般不使用。

1 个字节的整数,auth_response_length,密码加密后的长度。

auth_response_length 指定长度的字符串,密码与随机数加密后的数据。

如果 CLIENT_CONNECT_WITH_DB 直接指定了连接的数据库,则需要传递以 NUL(0x00)结尾的字符串,内容是数据库名。

CLIENT_PLUGIN_AUTH 一般都需要,默认方式需要传递的值就是 mysql_native_password

可以看到,Handshake Response PacketInitial Handshake Packet 其实是相对应的。

OK_Packet & ERR_Packet

OK_PacketERR_Packet 是 MySQL 服务端通用的响应包。

OK_Packet

MySQL 5.7.5 版本以后,OK_Packet 还包含了 EOF_Packet(用来显示警告和状态信息)。区分 OK_PacketEOF_Packet:

OK: header = 0x00 and length of packet > 7EOF: header = 0xfe and length of packet < 9

MySQL 5.7.5 版本之前,EOF_Packet 是一个单独格式的包:

EOF_Packet

如果身份认证通过、连接建立成功,返回的 OK_Packet 就会是:

0x07 0x00 0x00 0x02 0x00 0x00 0x00 0x02 0x00 0x00 0x00

如果连接失败,或者出现错误则会返回 ERR_Packet 格式的包:

ERR_Packet

Replication

想要获取到 master 的 binlog 吗?只要你对接实现 replication 协议即可。

replication

1.client 与 server 之间成功建立连接、完成身份认证,这个过程就是上文所述的 connection phase 。2.client 向 server 发送 COM_REGISTER_SLAVE 包,表明要注册成为一个 slave ,server 响应 OK_Packet 或者 ERR_Packet,只有成功才能进行后续步骤。3.client 向 server 发送 COM_BINLOG_DUMP 包,表明要开始获取 binlog 的内容。4.server 响应数据,可能是:binlog network stream( binlog 网络流)。ERR_Packet,表示有错误发生。EOF_Packet,如果 COM_BINLOG_DUMP 中的 flags 设置为了 0x01 ,则在 binlog 没有更多新事件时发送 EOF_Packet,而不是阻塞连接继续等待后续 binlog event 。

COM_REGISTER_SLAVE

客户端向 MySQL 发送 COM_REGISTER_SLAVE ,表明它要注册成为一个 slave,包格式如下图:

com_register_slave

除了 1 个字节的固定内容 0x15 和 4 个字节的 server-id ,其他内容通常都是空或者忽略,需要注意的是这里的 user 和 password 并不是登录 MySQL 的用户名和密码,只是 slave 的一种标识而已。

COM_BINLOG_DUMP

注册成为 slave 之后,发送 COM_BINLOG_DUMP 就可以开始接受 binlog event 了。

com_binlog_dump

1 个字节的整数,固定内容 0x12 。4 个字节的整数,binlog-pos 即 binlog 文件开始的位置。2 个字节的整数,flags,一般情况下 slave 会一直保持连接等待接受 binlog event,但是当 flags 设置为了 0x01 时,如果当前 binlog 全部接收完了,则服务端会发送 EOF_Packet 然后结束整个过程,而不是保持连接继续等待后续 binlog event 。4 个字节的整数,server-id,slave 的身份标识,MySQL 可以同时存在多个 slave ,每个 slave 必须拥有不同的 server-id不定长字符串,binlog-filename,开始的 binlog 文件名。查看当前的 binlog 文件名和 pos 位置,可以执行 SQL 语句 show master status ,查看所有的 binlog 文件,可以执行 SQL 语句 show binary logs

Binlog Event

客户端注册 slave 成功,并且发送 COM_BINLOG_DUMP 正确,那么 MySQL 就会向客户端发送 binlog network stream 即 binlog 网络流,所谓的 binlog 网络流其实就是源源不断的 binlog event 包(对 MySQL 进行的操作,例如 inset、update、delete 等,在 binlog 中是以一个或多个 binlog event 的形式存在的)。

Replication 的两种方式:

异步,默认方式,master 不断地向 slave 发送 binlog event ,无需 slave 进行 ack 确认。半同步,master 向 slave 每发送一个 binlog event 都需要等待 ack 确认回复。


Binlog 有三种模式:

statement ,binlog 存储的是原始 SQL 语句。row ,binlog 存储的是每行的实际前后变化。mixed ,混合模式,binlog 存储的一部分是 SQL 语句,一部分是每行变化。

Binlog Event 的包格式如下图:

binlog_event

每个 Binlog Event 包都有一个确定的 event header ,根据 event 类型的不同,可能还会有 post header 以及 payload 。

Binlog Event 的类型非常多:

Binlog Management:START_EVENT_V3

FORMAT_DESCRIPTION_EVENT: MySQL 5.x 及以上版本 binlog 文件中的第一个 event,内容是 binlog 的基本描述信息。STOP_EVENTROTATE_EVENT: binlog 文件发生了切换,binlog 文件中的最后一个 event。SLAVE_EVENTINCIDENT_EVENT

HEARTBEAT_EVENT: 心跳信息,表明 slave 落后了 master 多少秒(执行 SQL 语句 SHOW SLAVE STATUS 输出的 Seconds_Behind_Master 字段)。

Statement Based Replication Events(binlog 为 statement 模式时相关的事件):

QUERY_EVENT: 原始 SQL 语句,例如 insert、update ... 。

INTVAR_EVENT: 基于会话变量的整数,例如把主键设置为了 auto_increment 自增整数,那么进行插入时,这个字段实际写入的值就记录在这个事件中。

RAND_EVENT: 内部 RAND() 函数的状态。

USER_VAR_EVENT: 用户变量事件。

XID_EVENT: 记录事务 ID,事务 commit 提交了才会写入。

Row Based Replication Events(binlog 为 row 模式时相关的事件):

TABLE_MAP_EVENT: 记录了后续事件涉及到的表结构的映射关系。

v0 事件对应 MySQL 5.1.0 to 5.1.15 版本DELETE_ROWS_EVENTv0: 记录了行数据的删除。

UPDATE_ROWS_EVENTv0: 记录了行数据的更新。

WRITE_ROWS_EVENTv0: 记录了行数据的新增。

v1 事件对应 MySQL 5.1.15 to 5.6.x 版本

DELETE_ROWS_EVENTv1: 记录了行数据的删除。

UPDATE_ROWS_EVENTv1: 记录了行数据的更新。

WRITE_ROWS_EVENTv1: 记录了行数据的新增。

v2 事件对应 MySQL 5.6.x 及其以上版本

DELETE_ROWS_EVENTv2: 记录了行数据的删除。

UPDATE_ROWS_EVENTv2: 记录了行数据的更新。

WRITE_ROWS_EVENTv2: 记录了行数据的新增。

LOAD INFILE replication(加载文件的特殊场景,本文不做介绍):

LOAD_EVENT

CREATE_FILE_EVENT

APPEND_BLOCK_EVENT

EXEC_LOAD_EVENT

DELETE_FILE_EVENT

NEW_LOAD_EVENT

BEGIN_LOAD_QUERY_EVENT

EXECUTE_LOAD_QUERY_EVENT

想要解析具体某个 binlog event 的内容,只要对照官方文档数据包的格式即可。

结语

MySQL Client/Server Protocol 协议其实很简单,就是相互之间按照约定的格式发包,而理解了协议,相信你自己就可以实现一个 lib 去注册成为一个 slave 然后解析 binlog 。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
SQL 关系型数据库 MySQL
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
3月前
|
关系型数据库 MySQL 数据库
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
222 0
|
4月前
|
数据采集 关系型数据库 MySQL
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format
48 1
|
4月前
|
关系型数据库 MySQL Java
【Azure 应用服务】应用服务连接 Azure MySQL 一直失败,报错 Create connection error
【Azure 应用服务】应用服务连接 Azure MySQL 一直失败,报错 Create connection error
|
5月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
375 3
|
5月前
|
网络协议 关系型数据库 MySQL
启动mysql时的异常为:[ERROR] Can‘t start server: Bind on TCP/IP port. Got error: 98: Address already in used
启动mysql时的异常为:[ERROR] Can‘t start server: Bind on TCP/IP port. Got error: 98: Address already in used
|
5月前
|
安全 关系型数据库 MySQL
【Python】已解决:pymysql.err.OperationalError:(2003 “Can’t connect to MySQL server on ‘localhost’ ([WinEr
【Python】已解决:pymysql.err.OperationalError:(2003 “Can’t connect to MySQL server on ‘localhost’ ([WinEr
713 1
|
6月前
|
Web App开发 关系型数据库 MySQL
ucenter info:can not connect to MySQL server 报错!怎么解决
ucenter info:can not connect to MySQL server 报错!怎么解决
47 1
|
5月前
|
关系型数据库 MySQL 数据库
2003-Can`t connect to Mysql server on ‘154.8.165.152‘(10038)
2003-Can`t connect to Mysql server on ‘154.8.165.152‘(10038)

推荐镜像

更多
下一篇
DataWorks