ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL源码分析之 通信协议(一)

2022-05-13 12:32:30  阅读:314  来源: 互联网

标签:字节 通信协议 EOF 源码 服务器 MySQL 长度 数据包 客户端


MySQL源码分析之 通信协议(一)

mysql 通信协议用于 mysql 客户端和服务器之间的通讯,通过以下几种方式实现:

 1)、接口: (Connector/C, Connector/J, 等) 即平时我们所说的 JDBC ODBC 等接口

 2)、mysql 中间件

 3)、主服务器和从服务器之间的通信

mysql 协议支持一下几点功能:

 1)、使用 SSL 的透明加密

 2)、透明压缩

 3)、连接阶段,进行身份验证和数据交换的能力

 4)、执行阶段,接收客户端发来的命令并执行他们

交互过程:

MySQL客户端与服务器的交互主要分为两个阶段:握手认证阶段和命令执行阶段。

握手认证阶段为客户端与服务器建立连接后进行,交互过程如下:

  • 服务器 -> 客户端:握手初始化消息
  • 客户端 -> 服务器:登陆认证消息
  • 服务器 -> 客户端:认证结果消息

客户端认证成功后,会进入命令执行阶段,交互过程如下:

  • 客户端 -> 服务器:执行命令消息
  • 服务器 -> 客户端:命令执行结果

MySQL客户端与服务器的完整交互过程如下

 

基本类型:

1、整型

整型分为固定长度的整型和可变长度的整型(变长在这里指的是存储长度)。

固定长度类型属于无符号整型,分别有1、2、3、4、6、8字节长度,使用小字节序传输最低有效字节排在第一位。以3字节长度整型为例可以查看 int3store()

变长整型,可能占用1、3、4、9个字节,具体取决于其数值。把一个整型值转换为一个可变字节长度存储需要如下操作:

因此,如果需要将变长存储的整型转化为数值,需要检查第一个字节。

注意: 如果数据包的第一个字节是长度编码的整数,其字节值为0xFE,则必须检查数据包的长度,以验证其是否有足够的空间容纳8字节整数。如果不是,它可能是一个EOF数据包。 

2、字符串

字符串在协议中有以下几种形势:

1)、固定长度的字符串,具有已知的硬编码长度。例如,ERR数据包的sql状态总是5字节长

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

3)、字符串的长度由另一个字段确定,或在运行时计算

4)、长度编码字符串,字符串长度不固定,无'NULL'(0x00)结束符,编码方式与上面的 Length Coded integer 相同

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

报文结构: 如果 MySQL 客户端和服务器想发送数据,需要将数据拆为2**24大小的数据包(即16M)因此客户端和服务器之间以最大16M 的数据包进行交换。会为每个数据块预先添加一个数据包头。因此可以这么理解:报文分为消息头和消息体两部分,其中消息头占用固定的4个字节,消息体长度由消息头中的长度字段决定,报文结构如下:

  

 1、消息头,记录了报文长度:用于标记当前请求消息的实际数据长度值,以字节为单位,占用3个字节,最大值为 0xFFFFFF,即接近 16 MB 大小(比16MB少1个字节)

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

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

通用响应包(服务响应报文):

响应包可以分为三种,OK_Packet、 ERR_Packet、EOF_Packet。从MySQL 5.7.5开始,OK数据包也被用来表示EOF,EOF数据包被弃用。如果设置了CLIENT_PROTOCOL_41,即MySQL 版本大于4.1。 

该数据包包含一个警告计数。

1、OK 响应报文

客户端的命令执行正确时,服务器会返回OK响应报文。

如果 header = 0 并且packer 长度大于7,说明这个包是 OK 数据包

如果 header = 0xFE 并且 packer 长度小于9,说明这个包是 EOF 包。 

affecred rows:受影响行数,当执行 INSERT/UPDATE/DELETE 语句时所影响的数据行数

last_insert_id: 值为AUTO_INCREMENT索引字段生成,如果没有索引字段,则为0x00。注意:当INSERT插入语句为多行数据时,该索引ID值为第一个插入的数据行索引值,而非最后一个

status_flags:  服务器状态,客户端可以通过该值检查命令是否在事务处理中

warnings:   告警次数,即告警发生的次数

session state info:  会话状态信息

info:  服务器消息,服务器返回给客户端的消息,一般为简单的描述性字符串,可选字段。

**会话状态信息**

状态变化信息作为一组状态变化块在OK数据包中发送,这些状态变化块由以下部分组成:

类型:数据的类型,可以查看 enum_session_state_type.。 数据,会话信息改变的数据

 

enum enum_session_state_type {
  SESSION_TRACK_SYSTEM_VARIABLES, /**< Session system variables */
  SESSION_TRACK_SCHEMA,           /**< Current schema */
  SESSION_TRACK_STATE_CHANGE,     /**< track session state changes */
  SESSION_TRACK_GTIDS,            /**< See also: session_track_gtids */
  SESSION_TRACK_TRANSACTION_CHARACTERISTICS, /**< Transaction chistics */
  SESSION_TRACK_TRANSACTION_STATE            /**< Transaction state */
};

 数据字段的解释取决于类型值。

1)、SESSION_TRACK_SYSTEM_VARIABLES   会话跟踪系统变量

2)、SESSION_TRACK_SCHEMA  会话跟踪模式

3)、SESSION_TRACK_STATE_CHANGE 会话跟踪状态更改。 指示会话状态是否发生更改的标志字节。此标志表示为ASCII值

2、ERR 响应报文 

错误包意味着产生了错误信息,在 MySQL4.1版本之后,它包含一个 SQL 状态值,错误文本大小不能超过 Error texts cannot exceed。 代码函数 net_send_error_packet()

header: 消息头,ERR 报文问 0xFF

error-code:  错误码,定义在源代码/include/mysqld_error.h头文件中

sql_state_marker:  服务器状态标志,恒为'#'字符

sql_sate: 服务器状态,服务器将错误编号通过mysql_errno_to_sqlstate函数转换为状态值,状态值由5字节的ASCII字符组成,定义在源代码/include/sql_state.h头文件中

error_message: 错误信息,错误消息字符串到达消息尾时结束,长度可以由消息头中的长度值计算得出。消息长度为0-512字节

3、EOF 响应报文 

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

在 mysql 的通信协议中,EOF 数据包和 OK 数据包是一样的目的,用来标记一个查询结果的结束。在 MySQL5.7因为 OK 数据包发生了更改(如会话状态跟踪),为了避免 EOF 数据发生重复更改,在 MySQL5.7.5之后弃用 OK 数据包。

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

warnings: 告警计数,服务器告警数量,在所有数据都发送给客户端后该值才有效。

status_flags: 状态标志位,包含类似SERVER_MORE_RESULTS_EXISTS这样的标志位。

:由于EOF值与其它Result Set结构共用1字节,所以在收到报文后需要对EOF包的真实性进行校验,校验条件为:

  • 第1字节值为0xFE
  • 包长度小于9字节

未完待续。。。。

 

标签:字节,通信协议,EOF,源码,服务器,MySQL,长度,数据包,客户端
来源: https://www.cnblogs.com/jkin/p/16257513.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有