压缩协议属于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函数:

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

浅谈MySQL压缩协议细节--从源码层面的更多相关文章

  1. 浅谈MySQL load data local infile细节 -- 从源码层面

    相信大伙对mysql的load data local infile并不陌生,今天来巩固一下这里面隐藏的一些细节,对于想自己动手开发一个mysql客户端有哪些点需要注意的呢? 首先,了解一下流程: 3个 ...

  2. 浅谈mysql主从复制的高可用解决方案

    1.熟悉几个组件(部分摘自网络)1.1.drbd     —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...

  3. 浅谈mysql innodb缓存策略

    浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb buffe ...

  4. 浅谈mysql配置优化和sql语句优化【转】

    做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...

  5. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  6. 浅谈状态压缩DP

    浅谈状态压缩DP 本篇随笔简单讲解一下信息学奥林匹克竞赛中的状态压缩动态规划相关知识点.在算法竞赛中,状压\(DP\)是非常常见的动规类型.不仅如此,不仅是状压\(DP\),状压还是很多其他题目的处理 ...

  7. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景   Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...

  8. 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)

    在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...

  9. C#轻量级通通讯组件StriveEngine —— C/S通信开源demo(2) —— 使用二进制协议 (附源码)

    前段时间,有几个研究ESFramework通信框架的朋友对我说,ESFramework有点庞大,对于他们目前的项目来说有点“杀鸡用牛刀”的意思,因为他们的项目不需要文件传送.不需要P2P.不存在好友关 ...

随机推荐

  1. 排序算法C语言实现——堆排序

    /*堆排nlog(n)*//*堆排复杂度分析1.建堆((n*log(n))/2)    循环n/2次,每次调用HeapAdjust函数    HeapAdjust内部循环log(n)2.调整堆(((n ...

  2. 几条sql语句(exists)

    通常exists后的子查询是需要和外面的表建立关联关系的,如 select count(*) from a where exists (select 'x' from b where a.id = b ...

  3. 在 Yii2 项目中使用 Composer 添加 FontAwesome 字体资源

    2014-06-21 19:05 原文 简体 繁體 2,123 次围观 前天帮同事改个十年前的网站 bug,页面上一堆 include require 不禁让人抱头痛哭.看到 V2EX 上的讨论说,写 ...

  4. Leetcode 335.路径交叉

    路径交叉 给定一个含有 n 个正数的数组 x.从点 (0,0) 开始,先向北移动 x[0] 米,然后向西移动 x[1] 米,向南移动 x[2] 米,向东移动 x[3] 米,持续移动.也就是说,每次移动 ...

  5. 九度oj 题目1016:火星A+B

    题目描述:     读入两个不超过25位的火星正整数A和B,计算A+B.需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数.例如:地球上的10进制数2,在火星上记为“1,0”,因为 ...

  6. NOI2015 荷马史诗 【k-哈夫曼树】

    题目 追逐影子的人,自己就是影子 --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛> ...

  7. 定时任务-Quartz

    Quartz Quartz w3c教程 参考:https://blog.csdn.net/lkl_csdn/article/details/73613033 Quartz 的使用 https://ww ...

  8. 转 DOS 8.3 文件名命名规则

    http://www.360doc.com/content/10/0813/14/73007_45757514.shtml DOS 8.3 文件名命名规则 经常看到命令行或者其它软件在显示目录的时候出 ...

  9. unity的List构造函数在IOS平台存在缺陷

    当迩使用一个int[]或者string[]类似的数组时,以数组来初始化List对象,有可能在IOS平台上会出现初始化对象为空,比如 , }; List<int> listTest = ne ...

  10. Phantomjs和Casperjs,后台网页抓取和交互

    var casper = require('casper').create({ verbose: true, logLevel: 'debug', pageSettings: { loadImages ...