MySQL 通信协议介绍
1、数据类型
了解MySQL协议包之前必需先知道其数据类型
1.1 Integer Types 整数类型
(1)定长整型
固定长度, 小端编码, 有下面几种(括号内的代表所占字节数):
int<1>
int<2>
int<3>
int<4>
int<6>
int<8>
(2)变长整型
可能长度为1, 3, 4, 9 个字节, 实际长度取决于数值的大小.记为 int
编码过程, 记数值为N:
1.若 N < 251, 则编码为单字节
2.若 251 <= N < 2^16, 则编码为 0xfc + 2-byte integer
3.若 2^16 <= N < 2^24, 则编码为 0xfd + 3-byte integer
4.若 2^24 <= N < 2^64, 则编码为0xfe + 8-byte integer
解码过程, 先看第一个字节, 记其值为N1,
1.若 N1 <= 0xfb, 则说明该整数就是N1
2.若 N1 = 0xfc,则说明接下来2字节也是该整数的部分, 取出加上0xfc即为原数值
3.若 N1 = 0xfd, ...
4.若 N1 = 0xfe, ...
值得注意的是, 当协议包的第一个字节为0xfe时, 应该检查接下来是否有8个字节, 若没有则说明该协议包可能是EOF_PACKET
1.2 String Types 字符串类型
(1)FixedLengthString
定长字符串,记为 string
(2)NulTerminatedString
由NUL标识结束的字符串, NUL即0x00,记为string
(3)VariableLengthString
变长字符串, 长度由别的其它字段决定或者运行时动态计算出来的,记为string
(4)LengthEncodedString
长度编码的字符串, 即其前面有个整型int说明接下来的字符串的长度, 起始就是VariableLengthString,记为string
(5)RestOfPacketString
若一个字符串是一个协议包的最后一个字段, 那该字符串的长度当然就等于包长 - 当前位置,记为string
2.MySQL协议包
客户端或服务端要发消息给对方时:
1.把消息分成若干个长度小于 2^24-1(即16 M)的消息
2.给每个消息前面加一个4字节包头.
如下:
Type
Name
Description
int<3>
payload_length
payload字段的长度
int<1>
sequence_id
序列号
string
payload
payload包体
例如CMD_QUIT的整包字节序列为:01 00 00 00 01
1.通用响应报文
(1) OK_Packet
表示操作成功的报文,5.7开始用该报文替代EOF_Packet
报文格式:
判断时OK还是EOF规则:
OK: header = 0 and length of packet > 7
EOF: header = 0xfe and length of packet < 9
(2) ERR_Packet
表示操作失败的报文. It contains a SQL state value if CLIENT_PROTOCOL_41 is enabled.
报文格式:
(3) EOF_Packet
If CLIENT_PROTOCOL_41 is enabled, the EOF packet contains a warning count and status flags.
EOF报文用来表示多个报文组成的一个报文簇的结束,比如当客户端发送查询命令到mysql server时,mysql会按顺序回复以下报文:
1.ResultSetHeaderPacket --报文中携带了查询结果包含的字段的个数N,以及其它一些信息
2.FieldPacket * N -- N个FieldPacket,每一个都表示一个字段的定义
3.EOF Packet -- 表示字段定义的所有报文已发送完毕
4.RowDataPacket * M -- 每个报文表示一行数据
5.EOF Packet -- 表示行数据报文发送完毕。
报文格式: