压缩协议属于mysql通讯协议的一部分,要启用压缩协议传输功能,前提条件客户端和服务端都必须要支持zlib算法,那么,现在有个问题,假如服务端已经默认开启压缩功能,那原生客户端在连接的时候要如何才可启用该功能呢?答案很简单只需要加上-C(注意是大写C)或者--compress=true选项即可,事情看似简单,但是背后的设计却值得大家深入挖掘,启动后到底发生什么事情了,对网络传输性能上的提升到底有什么影响呢?

趁着风和日丽的今天,正适合在西湖边上一边泡着龙井、一边听着音乐、一边晒着太阳来享受一下这里面的真相,好,废话不多说,咱们开始吧。

首先,当客户端加上-C时,就会在Capabilities上添加CLIENT_COMPRESS压缩标志,源码参考sql-common/client.c的default_options变量、option_id变量以及mysql_read_default_options函数:

(PS:后面有出现源码的部分都是引用mysql 5.5.36版本,另外,核心接口部分的源码从5.1到5.6多个版本很少会变)

但这里有个问题,这样是否就成功开启压缩功能呢?不行的,还记得开始的时候提到的必须要客户端和服务端都开启压缩功能才是成功的,那服务端又是什么时候告诉客户端支持压缩呢?那就是在tcp三次握手后,服务端就会给客户端发送一个handshake initialization包,源码参考include/mysql_com.h的CAN_CLIENT_COMPRESS和sql/sql_acl.cc的send_server_handshake_packet函数:

如果在编译源码时没定义HAVE_COMPRESS变量时,那么服务端就不支持压缩,一般情况不会去掉该选项。

接下来,大伙得加快速度,跟上步伐,一起来认识下压缩协议包组成部分,这主要由Compressed Packet header和payload组成,具体如下图所述:

图1 压缩协议组成

从图中可以看出比普通的协议多出3个字节,细心的读者会有个疑问,为什么Sequence Id是带有compressed,其中的作用是?不着急哈,下面会慢慢揭晓为什么会有一个独立的compressed sequence id。

另外,可能细心的读者又有疑问,为什么消息体是Compressed Payload或者Uncompressed Payload?这是因为mysql内部有一个约定,如果查询语句payload小于字节时,对内容不压缩而保持原貌的方式,而mysql此举是为了减少CPU性能开销,源码参考include/my_sys.h的MIN_COMPRESS_LENGTH和mysys/my_compress.c的my_compress函数:

同时,压缩前的长度会设置为。

如果消息体为Compressed Payload时,客户端或服务端交互前,可能会将一个或多个MySQL包文合并压缩成一个数据包再发出去,目的显然而见,为了提升网络传输性能,对于一些网络环境较差的用户会有很大的帮助,刚才有提到过compressed sequence id的问题,如果不使用一个单独的变量来标志的话,那么当一个压缩包里有多个MySQL报文时就不知道怎么确定包序号了,这就是该变量的作用了。

那这里面貌似还会产生一个问题,如果原始报文或拼揍后是32M的话,能否进行压缩呢?答案是不行的,因为mysql一个包文最大长度限制为的第3部分length of payload before compression就可以判断出来,源码参考mysys/my_compress.c的my_uncompress函数:

以上就是今天要分享的小细节,希望对大家理解压缩协议方面的相关细节有所帮助,祝玩得开心!

最新文章

  1. 《深入浅出Windows Phone 8.1 应用开发》基于Runtime框架全新升级版
  2. 一排下去再上来的div
  3. IIs站点的建立
  4. cmakelists 语法学习
  5. 『重构--改善既有代码的设计』读书笔记----Replace Temp with Query
  6. 【学习笔记】【oc】类的包装类 协议 category
  7. POJ 1273 Drainage Ditches(网络流,最大流)
  8. JS的parent对象
  9. MySQL学习笔记(四)—存储过程
  10. 使用MySQLdb操作Mysql数据库
  11. Wannafly挑战赛3 record
  12. 前端学习_01_css网页布局
  13. Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级
  14. FLOAT 和 DOUBLE区别
  15. Debian Jessie升级至Stretch小记
  16. 自动化测试平台的搭建--Jenkins
  17. JavaScript test() 方法
  18. NOIP2018题解
  19. 【转】Example of using the --info linker option
  20. qt creator修改程序编码(解决中文乱码问题)的方法

热门文章

  1. 与LCD_BPP相关的函数
  2. PAT Basic 1041
  3. magic mouse 2 在Mac上灵敏度太低的解决办法
  4. bounds 和frame区别
  5. Ubuntu14.04使用root登陆帐户
  6. 【LeetCode】Pancake Sorting(煎饼排序)
  7. ImportError: No module named ‘MySQLdb'
  8. 九度oj 题目1283:第一个只出现一次的字符
  9. tarjan 缩点 求 scc
  10. 3931: [CQOI2015]网络吞吐量【网络流】