11 协议解析 数据包字段拆解

如果MySQL客户端或服务器要发送数据,则:

  • 将数据拆分为大小为(2^24-1)字节的数据包
  • 在每个块之前添加一个packet header

Protocol::Packet

客户端和服务器之间的数据以最大16MByte的数据包交换。

TypeNameDescription
int<3>payload_lengthpayload长度,数据包中字节数,前4个字节作为作为数据包的header
int<1>sequence_idSequence ID
string<var>payload数据包的payload,[len=payload_length]

示例:

COM_QUIT的数据包如下:

packet : 01 00 00 00 01

+------------+-----------------+-------------+
| Length = 1 | Sequence ID = 0 | Payload = 1 |
+------------+-----------------+-------------+
| 01 00 00   | 00              | 01          |
+------------+-----------------+-------------+
  • length: 1
  • sequence_id: x00;序列号随每个数据包增加,它从0开始,并在Command phase开始新命令时重置为0。
  • payload: 0x01

发送超过16Mbyte的数据包

如果payload大于或等于2^24-1字节,则将数据包的长度设置为2^24-1(ff ff ff),同时剩下的payload也一起发送,直到数据包的payload小于2^24-1字节为止。

发送payload是16777215(2^24-1)字节的数据包如下:

ff ff ff 00 ...
00 00 00 01

Protocol::Handshake

初始握手包,当客户端连接到服务器时,服务器将向客户端发送握手数据包。根据服务器版本和配置选项,将发送初始数据包的不同变体。

为了允许服务器添加对较新协议的支持,第一个字节定义了协议版本。

从3.21.0版本开始发送Protocol::HandshakeV10

Protocol::HandshakeV10

数据包格式:

TypeNameDescription
int<1>protocol versionAlways 10
string<NUL>server versionhuman readable status information
int<4>thread ida.k.a. connection id
string[8]auth-plugin-data-part-1first 8 bytes of the plugin provided data (scramble)
int<1>filler0x00 byte, terminating the first part of a scramble
int<2>capability_flags_1The lower 2 bytes of the Capabilities Flags
int<1>character_setdefault server a_protocol_character_set, only the lower 8-bits
int<2>status_flagsSERVER_STATUS_flags_enum
int<2>capability_flags_2The upper 2 bytes of the Capabilities Flags
if capabilities & CLIENT_PLUGIN_AUTH {
int<1>auth_plugin_data_lenlength of the combined auth_plugin_data (scramble), if auth_plugin_data_len is > 0
} else {
int<1>00constant 0x00
}
string[10]reservedreserved. All 0s.
$lengthauth-plugin-data-part-2Rest of the plugin provided data (scramble), $len=MAX(13, length of auth-plugin-data - 8)
if capabilities & CLIENT_PLUGIN_AUTH {
NULLauth_plugin_namename of the auth_method that the auth_plugin_data belongs to
}

如果客户端支持SSL(将设置Capabilities FlagsCLIENT_SSL同时客户端的mysql_ssl_mode不会被设置为SSL_MODE_DISABLED)将发送一个名为Protocol::SSLRequest的简短数据包,使服务器建立SSL层并等待客户端的下一个数据包。

客户端将会回复Protocol::HandshakeResponse

任何时候,任何错误,客户端都会断开连接。

上次修改: 19 May 2020