在客户端和mysql服务端建立连接之后最主要的目的就是执行命令(建立连接过程详见mysql通信协议 -- 连接创建),mysql执行语句都通过文本协议(COM_QUERY)开始,mysql服务端视情况返回不通的packet,分别有下面几种情况(备注:本文所有图片都摘自官方文档):ERR_Packet
OK_Packet
LOCAL INFILE Request
Text Resultset
ERR_Packet:
数据包内容大概就包括错误码、sql状态和错误信息,比较简单(见下图)
OK_Packet:
OK包表示语句执行成功,会根据建立连接时交换的信息返回一些服务器状态、session状态等,其实只要返回OK_Packet其实就表示成功了,像我们平时关注较多的影响行数、插入时最后插入的id值在这都会返回,不管是什么语句类型,最终要么返回OK_Packet要么就是ERR_Packet。
值得注意是从5.7.5开始,OK_Packet也可用于EOF_Packet,不会直接发送老的EOF_Packet,OK_Packet和EOF_Packet利用header区别,mysql为了和老版本客户端兼容,如果需要使用带EOF标志的OK_Packet,需要客户端连接时声明CLIENT_DEPRECATE_EOF标志,OK_Packet和EOF_Packet区别方式和包格式如下:OK: header = 0 and length of packet > 7
EOF: header = 0xfe and length of packet < 9
LOCAL INFILE Request:
如果客户端发送LOAD DATA LOCAL INFILE....命令来导入数据,就将触发该协议包,需要客户端返回LOCAL INFILE Data进行响应,直到最后客户端返回一个空包为止,整个流程见下图:
Text Resultset
用途是返回查询结果,这个协议包是该文章中最复杂的一个,也是最需要理解的,该协议包分为两部分,由元数据(字段信息)、行数据组成。
元数据部分以字段计数的数据包开头,后跟字段定义的数据包,每个字段一个数据包,如果未设置CLIENT_DEPRECATE_EOF,则以EOF_Packet结束。
行数据部分也是元数据部分类似,每行一个数据包,最后以EOF_Packet结束。
现在来说说字段元数据和行数据两部分的数据包,行数据包很简单,一行一个packet, 每个字段值都是以字符串类型发送,类型都为 string,如果数据为空则为0xFB,而元数据包含库名、表名、字段类型、字段长度、字符集等信息见下图:
mysql执行语句协议的内容大概就这么多,稍微复杂的就是数据返回这块,还有一次性返回大量数据的情况留到后面再介绍,同样通过脚本来验证,由于比较多,排版比较丑,就不直接在这贴了,在我github上请自行点击下载,同样也只是做了今天内容的验证,后面逐步进阶