01_mysql协议基础

来源:互联网 发布:如何做淘宝店招 编辑:程序博客网 时间:2024/04/30 01:25

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;

0 0
原创粉丝点击