1 基本类型

1.1 整数类型

1.1.1 固定长度整型

MySQL报文中整型值分别有1、2、3、4、6、8字节长度,使用小字节序传输。

1.1.2 长度编码整数类型

一个整数,消耗1,3,4或9个字节,具体取决于其数值

要将数字值转换为长度编码的整数:

如果值<251,则将其存储为1字节整数。

如果值为≥251且< 2^16,则存储为0xfc + 2字节整数。

如果值为≥2^16 和 <2^24, 0xfd + 3字节整数存储。

如果值为≥2^24 和 <2^64, 0xfe + 8字节整数存储。

要将长度编码的整数转换成其数值,请检查第一个字节:

如果是<0xfb,则将其视为1字节整数。

如果是0xfb,空数据,数据的真实长度为零。

如果是0xfc,则后跟2字节整数。

如果是0xfd,则后跟3个字节的整数。

如果为0xfe,则后跟8字节整数。

注意:
- 0xfe也可能是EOF_Packet
- 0xfb在ResultsetRow中表示NULL
- 0xff是ERR_Packet的第一个字节

1.2 字符串类型

1.2.1 固定长度字符串(FixedLengthString)

固定长度的字符串具有已知的硬编码长度。
一个例子是ERR_Packet的sql-state ,它总是5个字节长。

1.2.2 以NULL结尾(NulTerminatedString)

字符串长度不固定,当遇到’NULL’(0x00)字符时结束。

1.2.3 长度编码的字符串(LengthEncodedString)

长度编码的字符串是以长度编码整数为前缀描述字符串的长度的字符串。

1.2.4 VariableLengthString

字符串的长度由某个字段决定。

1.2.5 RestOfPacketString

如果字符串是数据包的最后一个组成部分,则可以从整个数据包长度减去当前位置计算其长度。

描述了数据包的字节序列:

类型

描述

int<1>

1 byte Protocol::FixedLengthInteger

int<2>

2 byte Protocol::FixedLengthInteger

int<3>

3 byte Protocol::FixedLengthInteger

int<4>

4 byte Protocol::FixedLengthInteger

int<6>

6 byte Protocol::FixedLengthInteger

int<8>

8 byte Protocol::FixedLengthInteger

int

Protocol::LengthEncodedInteger

string

Protocol::LengthEncodedString

string

Protocol::FixedLengthString

string

Protocol::VariableLengthString

string

Protocol::RestOfPacketString

string

Protocol::NulTerminatedString

2 数据包

类型

名称

描述

int <3>

payload_length

有效载荷的长度 分组中超过组成数据包头的最初4个字节的字节数

int <1>

sequence_id

序列号

string

payload

[len = payload_length ]分组的有效载荷

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

2.1 消息头

2.1.1 报文长度

用于标记当前请求消息的实际数据长度值,以字节为单位,占用3个字节,最大值为 0xFFFFFF,即接近 16 MB 大小(比16MB少1个字节)。
如果有效负载大于或等于2^24 -1字节,则长度设置为2^24 -1(0xffffff ),并且附加数据包与剩余的有效载荷一起发送,直到数据包的有效载荷小于2^24 -1字节。

2.1.2 序号

在一次完整的请求/响应交互过程中,用于保证消息顺序的正确,每次客户端发起请求时,序号值都会从0开始计算。

2.2 消息体

消息体用于存放请求的内容及响应的数据,长度由消息头中的长度值决定。

3 通用响应数据包

3.1 OK_Packet

一个OK数据包从服务器发送到客户端,表示成功的执行命令。 从MySQL 5.7.5开始,OK数据包也用于表示EOF,并且不推荐使用EOF数据包。

如果设置了CLIENT_PROTOCOL_41 ,则该数据包包含警告计数。

类型

名称

描述

int<1>

header

[00]或[fe] OK包头

int

affected_rows

受影响的行

int

last_insert_id

最后一个insert-id

if capabilities & CLIENT_PROTOCOL_41 {{

int<2>

status_flags

状态标志

int<2>

warnings

警告数量

} elseif capabilities & CLIENT_TRANSACTIONS {

int<2>

status_flags

状态标志

}

if capabilities & CLIENT_SESSION_TRACK {

string

info

人类可读状态信息

if status_flags & SERVER_SESSION_STATE_CHANGED {

string

session_state_changes

会话状态信息

}

} else {

string

info

人类可读状态信息

}

下面规则区分数据包是否表示OK或EOF:
- OK报文: header = 0,包长度> 7
- EOF报文: header = 0xfe,包长度 < 9

3.2 ERR_Packet

该数据包发出错误信号。 如果启用CLIENT_PROTOCOL_41 ,它将包含SQL状态值。

类型

名称

描述

int <1>

header

[ff] ERR数据包的头

int <2>

error_code

错误代码

if capabilities & CLIENT_PROTOCOL_41 {

string[1]

sql_state_marker

标记的SQL状态

string[5]

sql_state

SQL状态

}

string

error_message

可读错误消息

3.3 EOF_Packet

如果启用CLIENT_PROTOCOL_41 ,则EOF数据包包含警告计数和状态标志。

类型

名称

描述

int <1>

header

[fe] EOF数据包的头

if capabilities & CLIENT_PROTOCOL_41 {

int <2>

warnings

警告数量

int <2>

status_flags

状态标志

}

EOF数据包可能会出现在可能出现Protocol::LengthEncodedInteger地方。 您必须检查数据包长度是否小于9,以确保它是EOF数据包。

3.4 Status Flags

Flag

Value

Comment

SERVER_STATUS_IN_TRANS

0x0001

a transaction is active

SERVER_STATUS_AUTOCOMMIT

0x0002

auto-commit is enabled

SERVER_MORE_RESULTS_EXISTS

0x0008

SERVER_STATUS_NO_GOOD_INDEX_USED

0x0010

SERVER_STATUS_NO_INDEX_USED

0x0020

SERVER_STATUS_CURSOR_EXISTS

0x0040

Used by Binary Protocol Resultset to signal that COM_STMT_FETCH must be used to fetch the row-data.

SERVER_STATUS_LAST_ROW_SENT

0x0080

SERVER_STATUS_DB_DROPPED

0x0100

SERVER_STATUS_NO_BACKSLASH_ESCAPES

0x0200

SERVER_STATUS_METADATA_CHANGED

0x0400

SERVER_QUERY_WAS_SLOW

0x0800

SERVER_PS_OUT_PARAMS

0x1000

SERVER_STATUS_IN_TRANS_READONLY

0x2000

in a read-only transaction

SERVER_SESSION_STATE_CHANGED

0x4000

connection state information has changed

4.字符集

MySQL具有非常灵活的字符集支持,如字符集支持中所述。 可以查询字符集及其ID的列表如下:

SELECT id,collation_name FROM information_schema.collations ORDER BY id;