ICode9

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

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

2022-05-16 17:31:36  阅读:277  来源: 互联网

标签:STATUS string 通信协议 auth SERVER 源码 MySQL 服务器 客户端


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

mysql 通信包括,握手连接阶段、命令执行阶段和主从复制协议。在连接执行以下任务,客户端和服务器数据交换,如果请求加密设置 ssl 连接通道,根据服务器对客户端进行身份验证。

服务器和客户端完整交互如下:

1、登录认证交互报文

初始化握手,初始化握手从服务端发送  Protocol::Handshake 包开始,然后客户端可以选择使用 SSL 协议。接着客户端发送 Protocol::HandshakeResponse数据包。

接下来介绍一下 HandshakeV10数据报文,其他版本可以参考源码文档

protocol version:  服务协议版本号,恒为10,该值由 PROTOCOL_VERSION 宏定义决定(参考MySQL源代码/include/mysql_version.h头文件定义)

server version: 服务版本信息,该值为字符串,由 MYSQL_SERVER_VERSION 宏定义决定(参考MySQL源代码/include/mysql_version.h头文件定义)

thread id:  服务器为当前连接创建的线程 id

auth-plugin-data-part-1: 挑战随机数前8字节(第一部分),MySQL数据库用户认证采用的是挑战/应答的方式,服务器生成该挑战数并发送给客户端,由客户端进行处理并返回相应结果,然后服务器检查是否与预期的结果相同,从而完成用户认证的过程.

filler:  填充值 0x00, 终止挑战随机数前8字节。

capability_flags_1:服务权能标志的低16位

character_set: 字符编码,标识服务器用的字符集。只包含低8位。

status_flags: 服务器状态,状态值定义如下(参考MySQL源代码/include/mysql_com.h中的宏定义)

enum SERVER_STATUS_flags_enum {
  SERVER_STATUS_IN_TRANS = 1,      /**< 当使用显示事务活关闭自动提交时会触发*/
  SERVER_STATUS_AUTOCOMMIT = 2,   /**< 服务处于自动提交模式 */
  SERVER_MORE_RESULTS_EXISTS = 8, /**< 使用 mulit query 时,存在下一条 query */
  SERVER_QUERY_NO_GOOD_INDEX_USED = 16, /**< 查询没有使用好的索引 */
  SERVER_QUERY_NO_INDEX_USED = 32, /**< 查询没有使用任何索引 */
  /**
    服务器能够满足客户机的请求,并为查询打开了一个只读的不可滚动游标,此标志用于响应COM_STMT_EXECUTE和COM_STMT_FETCH命令
    由二进制协议结果集使用,表示必须使用COM_STMT_FETCH来获取行数据
    @todo Refify "Binary Protocol Resultset" and "COM_STMT_FETCH".
  */
  SERVER_STATUS_CURSOR_EXISTS = 64,
  SERVER_STATUS_LAST_ROW_SENT = 128,  /**< 当只读游标耗尽时,法师该标志用来响应COM_STMT_FETCH 命令*/
  SERVER_STATUS_DB_DROPPED = 256, /**< 删除一个库 */
  SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512,
  SERVER_STATUS_METADATA_CHANGED = 1024,  /**< 在一个 prepeaed 语句重复执行 发现新语句返回不同数量的结果集列,将此标记返回给客户端*/
  SERVER_QUERY_WAS_SLOW = 2048,    /**< 标记语句是否属于慢查询 */
  SERVER_PS_OUT_PARAMS = 4096,   /**< 标记含有输出参数的结果集 */
  /**< 如果多语句事务是只读的,则与SERVER_STATUS_IN_TRANS同时设置。事务提交或者终止时清除 
  由于该标志以OK和EOF数据包的形式发送给客户端,因此该标志指示命令执行结束时的事务状态。*/
  SERVER_STATUS_IN_TRANS_READONLY = 8192,  
  SERVER_SESSION_STATE_CHANGED = (1UL << 14)   /**< 如果启用此状态标志,则表示由于执行了最后一条语句,服务器上的一个状态信息已更改。 */
};

capability_flags_2: 服务权能标志的高16位。与客户端协商通讯方式,各标志位含义如下(参考MySQL源代码/include/mysql_com.h中的宏定义)也可参考源码文档

auth_plugin_data_len: 如果auth_plugin_data_len > 0。组合身份验证插件数据的长度

00: 填充值,标志服务权能标志后八位结束

reserved:保留值都是0

auth-plugin-data-part-2:挑战随机数的第二部分

auth_plugin_name: 认证方法的名称

握手响应:

客户端接收到 handshake 包之后,生成一个响应并发给 server。如果Handshake Packet中的权能标识中带有client_protocol_41标识位,那么客户端将生成的Response为HandShake Response41,否则生成的为HandShake Response320,我们这里就不管HandShake Response320,因为现在的Server基本都会支持这个。

TypeNameDescription
int<4> client_flag Capabilities Flags, CLIENT_PROTOCOL_41 always set.
int<4> max_packet_size maximum packet size   最大消息长度
int<1> character_set client charset a_protocol_character_set, only the lower 8-bits
string[23] filler filler to the size of the handhshake response packet. All 0s.
string<NUL> username login user name
if capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA {
string<length> auth_response opaque authentication response data generated by Authentication Method indicated by the plugin name field.
} else {
int<1> auth_response_length length of auth_response   
string<length> auth_response opaque authentication response data generated by Authentication Method indicated by the plugin name field.
}
if capabilities & CLIENT_CONNECT_WITH_DB {
string<NUL> database initail database for the connection. This string should be interpreted using the character set indicated by character set field.
}
if capabilities & CLIENT_PLUGIN_AUTH {
string<NUL> client_plugin_name the Authentication Method used by the client to generate auth-response value in this packet. This is an UTF-8 string.
}
if capabilities & CLIENT_CONNECT_ATTRS {
int<lenenc> length of all key-values affected rows
string<lenenc> key1 Name of the 1st client attribute
string<lenenc> value1 Value of the 1st client attribute
.. (if more data in length of all key-values, more keys and values parts)
}
int<1> zstd_compression_level compression level for zstd compression algorithm

注:如果客户端和服务器版本不匹配,可能有其他情况发生,如果验证方法不匹配。服务器和客户端进行不同的处理。如AuthSwitchRequest请求,包括验证方法的介绍,请参考源码文档。

接下来为命令阶段:请参考http://hutaow.com/blog/2013/11/06/mysql-protocol-analysis/#1

 

标签:STATUS,string,通信协议,auth,SERVER,源码,MySQL,服务器,客户端
来源: https://www.cnblogs.com/jkin/p/16266536.html

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

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

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

ICode9版权所有