该协议具有一些在整个协议中使用的非常基本的类型:
MySQL协议具有一组可编码的整型:
Protocol::FixedLengthInteger
定长整数类型。固定长度的无符号整数将其值存储在一系列字节中,最低有效字节在前(小端存储模式)。最低有效位是指删除后对整个值影响最小的那一位。
通过网络发送这字节时,接收方需要知道字节内容是如何编码的(小端存储模式/大端存储模式)才能将原始字节转换为内部整数表示形式。
大小端模式与硬件的体系结构相关。
MySQL使用以下固定长度的无符号整数变体:
int<1>
: 1 byteint<2>
: 2 byteint<3>
: 3 byteint<4>
: 4 byteint<6>
: 6 byteint<8>
: 8 byte一个长度为3的定长整数类型,内容值为1,存储形式如下:01 00 00
。
Protocol::LengthEncodedInteger
int<lenenc>
:长度可编码整数类型。使用1、3、4或9个字节的整数,具体取决于其数字值。
将数字值转换为长度可编码整数:
大于/等于 | 小于 | 存储为 |
---|---|---|
0 | 251 | 1-byte integer |
251 | 2^16 | 0xFC + 2-byte integer |
216 | 2^24 | 0xFD + 3-byte integer |
224 | 2^64 | 0xFE + 8-byte integer |
要将长度可编码整数转换为数字值,要检查第一个字节。
0xfb
,则将其视为1字节整数。0xfc
,则后跟2个字节的整数。0xfd
,则后跟3个字节的整数。0xfe
,则后跟8个字节的整数。警告:如果数据包的第一个字节是长度可编码整数,并且其字节值为
0xFE
,则必须检查数据包的长度以验证其是否有足够的空间用于8字节整数。如果不是,则可能是EOF_Packet
。
根据上下文,第一个字节可能还具有其他含义:
0xfb
,则在ProtocolText::ResultsetRow
中表示NULL。0xff
,则是ERR_Packet
的第一个字节。警告:未定义
0xff
作为长度可编码整数类型的第一个字节。
fa
小于0xfb
,表示一个字节,它的十进制值为250fc fb 00
的第一个字节是0xfc
,表示长度是两个字节的整数,它的值是fb 00
即十进制值为251字符串是字节序列,在协议中以多种形式出现。
Protocol::FixedLengthString
string<fix>
:固定长度的字符串具有已知的硬编码长度。
ERR_Packet
长度始终为5个字节。
Protocol::NullTerminatedString
string<NUL>
:以00
字节结尾的字符串。
Protocol::VariableLengthString
string<var>
:字符串的长度由另一个字段确定或在运行时计算出来。
Protocol::LengthEncodedString
string<lenenc>
:长度可编码字符串是一个以描述字符串长度的长度编码整数类型作为前缀的字符串,其实是上面一种类型的特例。
int<lenenc>
):字符串的长度string<fix>
):[len=$length]stringProtocol::RestOfPacketString
string<EOF>
:如果字符串是数据包的最后一个组成部分,则可以从总数据包长度减去当前位置来计算其长度。
首先定义每个数据包的payload
来描述每个数据包,并提供一个示例,显示每个发送的数据包,包括其数据包头:
<packetname>
<description>
direction: client -> server
response: <response>
payload:
<type> <description>
Example:
01 00 00 00 01
其中<type>
描述数据包字节的顺序:
Type | Description |
---|---|
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<lenenc> | Protocol::LengthEncodedInteger |
string<lenenc> | Protocol::LengthEncodedString |
string<fix> | Protocol::FixedLengthString |
string<var> | Protocol::VariableLengthString |
string<EOF> | Protocol::RestOfPacketString |
string<NUL> | Protocol::NulTerminatedString |
注意:某些数据包具有可选字段或不同的字段分布,具体取决于作为
Protocol::HandshakeResponse
数据包一部分发送的Protocol::CapabilityFlags
。
如果字段具有固定值,则在description
部分将其显示为十六进制值,如方括号:[00]。
ProtocolBinary::MYSQL_TYPE_STRING
ProtocolBinary::MYSQL_TYPE_VARCHAR
ProtocolBinary::MYSQL_TYPE_VAR_STRING
ProtocolBinary::MYSQL_TYPE_ENUM
ProtocolBinary::MYSQL_TYPE_SET
ProtocolBinary::MYSQL_TYPE_LONG_BLOB
ProtocolBinary::MYSQL_TYPE_MEDIUM_BLOB
ProtocolBinary::MYSQL_TYPE_BLOB
ProtocolBinary::MYSQL_TYPE_TINY_BLOB
ProtocolBinary::MYSQL_TYPE_GEOMETRY
ProtocolBinary::MYSQL_TYPE_BIT
ProtocolBinary::MYSQL_TYPE_DECIMAL
ProtocolBinary::MYSQL_TYPE_NEWDECIMAL
value(lencenc_str)---string
03 66 6f 6f -- string = "foo"
ProtocolBinary::MYSQL_TYPE_LONGLONG
value (8) -- integer
01 00 00 00 00 00 00 00 -- int64 = 1
ProtocolBinary::MYSQL_TYPE_LONG
, ProtocolBinary::MYSQL_TYPE_INT24
value (4) -- integer
01 00 00 00 -- int32 = 1
ProtocolBinary::MYSQL_TYPE_SHORT
, ProtocolBinary::MYSQL_TYPE_YEAR
value (2) -- integer
01 00 -- int16 = 1
ProtocolBinary::MYSQL_TYPE_TINY
value (1) -- integer
01 -- int8 = 1
ProtocolBinary::MYSQL_TYPE_DOUBLE
MYSQL_TYPE_DOUBLE
以IEEE 754双精度格式存储浮点数。
在C语言存储中,第一个字节是有效位的最后一个字节,即小端存储。
value (string.fix_len) -- (len=8) double
66 66 66 66 66 66 24 40 -- double = 10.2
ProtocolBinary::MYSQL_TYPE_FLOAT
MYSQL_TYPE_FLOAT
以IEEE 754单精度格式存储浮点数。
value (string.fix_len) -- (len=4) float
33 33 23 41 -- float = 10.2
ProtocolBinary::MYSQL_TYPE_DATE
, ProtocolBinary::MYSQL_TYPE_DATETIME
, ProtocolBinary::MYSQL_TYPE_TIMESTAMP
在二进制协议中存储DATE,DATETIME和TIMESTAMP字段。
为了节省空间,可以压缩数据包:
0
,且不发生为0字段4
,且不发送为0字段7
,并且不发送微秒字段11
0b da 07 0a 11 13 1b 1e 01 00 00 00 -- datetime 2010-10-17 19:27:30.000 001
04 da 07 0a 11 -- date = 2010-10-17
0b da 07 0a 11 13 1b 1e 01 00 00 00 -- timestamp
ProtocolBinary::MYSQL_TYPE_TIME
在二进制协议中存储TIME字段。
为了节省空间,可以压缩数据包:
0
,且不发生为0字段8
,并且不发送微秒字段12
0c 01 78 00 00 00 13 1b 1e 01 00 00 00 -- time -120d 19:27:30.000 001
08 01 78 00 00 00 13 1b 1e -- time -120d 19:27:30
01 -- time 0d 00:00:00
ProtocolBinary::MYSQL_TYPE_NULL
仅存储在NULL位图中。