Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1734184
  • 博文数量: 107
  • 博客积分: 1715
  • 博客等级: 上尉
  • 技术积分: 3168
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-18 18:42
个人简介

阿里巴巴DBA,原去哪儿网DBA。专注于MySQL源码研究、DBA运维、CGroup虚拟化及Linux Kernel源码研究等。 github:https://github.com/HengWang/ Email:king_wangheng@163.com 微博 :@王恒-Henry QQ :506437736

文章分类

全部博文(107)

文章存档

2014年(2)

2013年(38)

2012年(67)

分类: Mysql/postgreSQL

2013-03-10 17:37:05

目的

       基于《MySQL数据结构分析--protocol》对MySQL中Server端的协议格式和网络封装的详细分析和说明,本文对MySQL客户端命令格式和网络结构封装进行分析,深入理解MySQL服务器和客户端之间的通信协议。

数据结构

       MySQL客户端涉及的数据结构较多,其中主要包括MYSQL客户端数据结构、MYSQL_RES客户端结果数据结构、MYSQL_BIND客户端绑定信息数据结构、MYSQL_STMT客户端SQL语句数据结构、MYSQL_FIELD客户端字段信息数据结构、MYSQL_ROW客户端数据每行数据结构、MYSQL_ROWS客户端数据行结果集数据结构(MYSQL_ROW的链式结构)、MYSQL_DATA客户端数据内容数据结构。

       这些数据结果,在客户端发送SQL命令或者接收执行结果时,分别用于绑定和存储输入参数和输出结果,是客户端和服务器端交互时重要的数据结构。

       数据结构的定义参考源码文件include\mysql.h,其中定义了所有这些数据结构,以及相关的辅助数据结构。

格式

MySQL客户端的格式主要包括网络传输格式和命令格式两种,这些内容在源码文件sql-common\client.c中。以下分别对这两种格式进行分析。

MySQL客户端网络传输格式:

       MySQL客户端网络传输结构的封装主要分为两种,一种是简单命令网络传输结构、一种是高级命令网络传输结构。简单命令传输仅仅传输命令类型和命令参数,而高级命令传输需要传输命令的类型、命令头信息、以及命令参数。网络传输通过调用cli_advanced_command()函数进行发送,通过输入的header和header_len参数区分两种封装格式,分别调用net_write_command()函数进行实际的packet写处理。

       简单命令网络传输结构具体如下所示:

 


图1 简单命令网络传输结构

 

       高级命令网络传输结构具体如下所示:

 


图2 高级命令网络传输结构

 

MySQL客户端命令格式:

       MySQL客户端命令按照功能分为两种:一种是解析服务器端的协议,一种是封装客户端命令发送至服务器端。其中解析服务器端的协议主要根据服务器端的协议格式,进行解析出对应字段的信息,并存储在客户端相应的数据结构中。由于客户端解析服务器端的协议是服务器端协议封装的逆操作,因此不再赘述。

       由于大多数客户端发送的信息是命令,因此大多直接调用net_write_command()函数进行网络写处理,而没有真正的packet封装,故不再赘述。因此,以下内容对客户端复杂packet封装进行分析。

change_user_packet封装格式

       在send_change_user_packet()函数中,packet的内容不是简单的命令和简单的参数,而是根据客户端的版本不同和数据长度的不同,对packet数据进行封装。根据客户端版本的和数据长度的不同,有以下四种packet的封装格式:

客户端协议版本4.1:

 


图3数据长度为0的封装格式

 


图4数据长度不为0的封装格式

 

各个字段的含义根据字段名可知,不再赘述。数据长度为0时,数据存储长度0,而数据长度不为0时,存储相应的数据内容。此外如果客户端支持plugin,那么封装plugin_name进行发送。

客户端协议之前版本:

 


图5 数据长度为0的封装格式

 


图6 数据长度不为0的封装格式

 

       与客户端协议4.1封装结构不同的是chaset_num字段,这个字段在4.1协议中存储字符集类型。除此之外,与客户端协议4.1一致。

client_reply_packet封装格式

       在send_client_reply_packet()函数中,MySQL对回复packet进行封装。根据客户端协议的不同,分为以下两种格式。具体格式如下所示:

客户端协议版本4.1:

 


图7 客户端协议版本4.1的封装格式

 

       从封装格式可知,client_flag用于存储客户端的标志位,max_packet_size用于存储packet包的最大长度,chaset_num用于存储字符集类型,之后23个字节预留,user_name表示用户名,data_len和data分别用于表示密码的长度和密码,db表示数据库名,plugin_name表示客户端插件名。

客户端协议之前版本:

 


图8 客户端协议之前版本封装格式

 

       与客户端协议版本4.1不同的是,client_flag标志位占2个字节,max_packet_size占3个字节,而密码信息通过固定占用9个字节存储。

结论

       通过MySQL客户端传输格式和命令格式的分析,结合《MySQL数据结构分析--protocol》中服务器端的协议分析,对MySQL客户端和服务器端的通信协议有深入的理解。
参考
       1、《MySQL数据结构分析--protocol》 http://blog.chinaunix.net/uid-26896862-id-3494785.html    

阅读(5322) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~