浅谈MySQL压缩协议细节--从源码层面
压缩协议属于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压缩协议细节--从源码层面的更多相关文章
- 浅谈MySQL load data local infile细节 -- 从源码层面
相信大伙对mysql的load data local infile并不陌生,今天来巩固一下这里面隐藏的一些细节,对于想自己动手开发一个mysql客户端有哪些点需要注意的呢? 首先,了解一下流程: 3个 ...
- 浅谈mysql主从复制的高可用解决方案
1.熟悉几个组件(部分摘自网络)1.1.drbd —— DRBD(Distributed Replicated Block Device),DRBD号称是 "网络 RAID" ...
- 浅谈mysql innodb缓存策略
浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb buffe ...
- 浅谈mysql配置优化和sql语句优化【转】
做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...
- 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载
浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...
- 浅谈状态压缩DP
浅谈状态压缩DP 本篇随笔简单讲解一下信息学奥林匹克竞赛中的状态压缩动态规划相关知识点.在算法竞赛中,状压\(DP\)是非常常见的动规类型.不仅如此,不仅是状压\(DP\),状压还是很多其他题目的处理 ...
- 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景
浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...
- 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)
在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...
- C#轻量级通通讯组件StriveEngine —— C/S通信开源demo(2) —— 使用二进制协议 (附源码)
前段时间,有几个研究ESFramework通信框架的朋友对我说,ESFramework有点庞大,对于他们目前的项目来说有点“杀鸡用牛刀”的意思,因为他们的项目不需要文件传送.不需要P2P.不存在好友关 ...
随机推荐
- LeetCode(112) Path Sum
题目 Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...
- LeetCode(107) Binary Tree Level Order Traversal II
题目 Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from l ...
- windows中阿里的自动化测试macaca安装配置
一.环境配置 node cnpm环境安装 安卓环境配置 参考文档https://macacajs.github.io/zh/environment-setup 全局安装macaca-cli macac ...
- Linux下制作不用密码可立即登录的SSH用户
一.客户端建立两把钥匙 (1)本例以客户端的monkey用户为例,首先切换到~/.ssh目录下,如果没有该目录的话,需要进行新建 cd ~ mkdir .ssh chmod 700 .ssh cd ~ ...
- 利用visual studio 搜索替换功能清除项目中javascript文件的debugger;
在做web项目中,写js代码时候,会有一堆的debugger;,当时又懒得删,后面就多起来了,在vs的编辑器里面,其查找替换功能支持正则和整个项目/解决方案替换,这样就很容易删掉debugger;,方 ...
- ntdsutil 清理弃用服务器-----待验证
例子是这样的: 一个森林里有两个树,mm.com和cc.com,分别有dc www.mm.com和vdc.cc.com, cc.com域的控制器崩溃,不想恢复,要彻底删除这个域,由于vdc.cc.co ...
- Centos6虚拟主机的实现
centos6上虚拟主机的实现 实现虚拟主机有三种方式:基于IP的实现.基于端口的实现.基于FQDN的实现 一.基于IP的实现 1.先创建三个站点: mkdir /app/site1 mkdir ...
- [uiautomator篇] python uiautomatorDemo
#coding=utf-8 """ @version: 1.0 @author: @prerequisite: based on Python 2.7 @usage: 1 ...
- win10关闭防火墙命令
NetSh Advfirewall set allprofiles state off #关闭防火墙 Netsh Advfirewall show allprofiles #查看防火墙状态
- redis介绍和安装(一)
Redis介绍:redis是一个key-value存储系统. 和Memcached类似,它支持存储的value类型相对更多,包括 string(字符串). list(链表).set(集合).zset( ...