此文已由作者王慎为授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

MySQL 5.7中包括了很多让人耳目一新的新特性,其中就包括了InnoDB Transparent Page Compression,姑且称之为InnoDB透明页压缩。其实透明页压缩这个东西,早就关注过,其用到了sparse file和hole punching技术,但一直没能将这两种技术跟InnoDB压缩联系起来。最近花了点时间了解了下。

熟悉InnoDB的同学都知道,InnoDB从MySQL 5.1版本开始就支持压缩,提供zlib压缩算法,是记录压缩(record compress),曾大概看过InnoDB这部分相关的源码,逻辑比较复杂,如果对InnoDB page的组织结构不了解,相信很难看出个所以然,该压缩是页感知的(page aware),即需要知道页里面记录是怎么保存的。与之相反,MySQL 5.7最新支持的压缩是页透明的(page transparent),当然,页首尾的元数据是不压缩的,不关心这个页里面保存的是什么内容,可以理解为页/块压缩(page/block compress,本文将块和页混用)。

假设有个16KB的InnoDB页P1,通过块压缩为11KB,如果表空间使用的文件系统在mkfs时指定block size为4KB,那么只需要使用3个文件块来保存11KB的数据,节省1个文件块即4KB的空间。那么是不是说InnoDB下个页P2的数据直接从所节省的这4KB开始写入吗,答案是否定的。

InnoDB透明页压缩不会改变表文件的结构,我们可以理解为每页都占据了文件中4个块的大小,页压缩后的最终大小不会影响每个页在表文件中的起始偏移位置。即第k个页的数据,还是从表文件第4*k个块开始写入。问题来了,为什么不呢,因为压缩页经过修改后,再次压缩后的大小是不可知的,可能本来压缩后的大小为11KB,再次压缩就变成15KB了,那么仍需要4K文件块来保存,如果文件第4*n+3个块已经被写入了P2的数据,P1再次压缩后多出来4K数据就没地方放了。

从上段描述来看,不管P1被压缩成什么熊样,P2仍然需要从表文件的第4*n+4个偏移块开始写入数据,这种压缩并没有改变文件逻辑大小。虽然压缩后,IO是小了,但4KB的IO相比16KB的IO并不能带来多大的性能提升。然并卵!

怎样才能节省被压缩后释放的空间呢,这就需要用到文件系统/操作系统内核层面的技术 - sparse file,简单来说,sparse file是这样的文件, file 1大小是12KB,但是其实只占用首尾2个文件块共8KB的磁盘空间,中间4KB由于没有真实数据,并未分配磁盘空间,或者本来已经分配了,但又被回收了,像是中间被挖了个洞(punch hole)。这被挖的4KB,可以被文件系统用来分配给其他文件保存数据。如果中间4KB的数据被用户填上了呢,没事,文件系统分配一个新的空闲快给file 1即可。关于sparse file更详细的介绍参见参考文献。当然这可能会导致数据库IO不连续。

通过上面的描述,相信很容易就能够将sparse file技术应用到InnoDB透明页压缩上。不再赘述,只放一张图。

为什么InnoDB要另辟蹊径,采用新的压缩方案,不再原来的压缩实现上进行优化呢,可能有以下两点原因:

首先,原有的记录级压缩,代码实现复杂的,需要基于不同的页类型采用不同的处理方式,需要熟悉InnoDB的索引和页结构,代码封装性较差,添加新的压缩算法或进行性能优化提升较费劲,所以一直仅支持zlib。在这个基础上进行优化提高较困难。这个观点得到MySQL官方的验证,详见参考文献中的官方描述。

其次,相对于原来的记录级压缩,新方案更加灵活,因为压缩算法是保持在InnoDB页的元数据中,理论上可以做到同个表中不同页采用了不同的压缩算法,比如根据不同页类型来决定是否压缩,采用某种压缩算法(当然目前MySQL官方还没这么做)。现实中,也会存在同个表包括多种压缩算法的场景,因为用户可以动态修改压缩算法(也可以启动和关闭压缩),而动态修改并不是说把已经压缩的页马上使用新的压缩算法重新压一次,而是对新产生或更新的页起作用,这就会导致有些页是不压缩的,有些页是采用zlib,有些采用lz4。吐槽下,为什么InnoDB还不支持snappy或quicklz呢。

参考文献:

http://dev.mysql.com/worklog/task/?id=7696

http://mysqlserverteam.com/innodb-transparent-page-compression/

http://mysqlserverteam.com/innodb-transparent-pageio-compression/

https://wiki.archlinux.org/index.php/Sparse_file

网易云免费体验馆,0成本体验20+款云产品!

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 Java web 服务启动时Xss溢出异常处理笔记
【推荐】 谈谈iOS开发如何写个人中心这类页面--静态tableView页面的编写
【推荐】 云计算节点故障自动化运维服务设计

InnoDB透明页压缩与稀疏文件的更多相关文章

  1. InnoDB页压缩技术

    Ⅰ.想起一个报错 1.1 创建表报错 (root@localhost) [(none)]> create tablespace ger_space add datafile 'ger_space ...

  2. MySQL · 引擎特性 · InnoDB 数据页解析

    前言 之前介绍的月报中,详细介绍了InnoDB Buffer Pool的实现细节,Buffer Pool主要就是用来存储数据页的,是数据页在内存中的动态存储方式,而本文介绍一下数据页在磁盘上的静态存储 ...

  3. 第17章 内存映射文件(3)_稀疏文件(Sparse File)

    17.8 稀疏调拨的内存映射文件 17.8.1 稀疏文件简介 (1)稀疏文件(Sparse File):指的是文件中出现大量的0数据,这些数据对我们用处不大,但是却一样的占用空间.NTFS文件系统对此 ...

  4. InnoDB 数据表压缩原理与限制

    http://liuxin1982.blog.chinaunix.net/uid-24485075-id-3523032.html 压缩理念 通过提高CPU利用率和节约成本,降低数据库容量及I/O负载 ...

  5. 14.5.4 InnoDB File-Per-Table Tablespaces 每个表一个文件

    14.5.4 InnoDB File-Per-Table Tablespaces 每个表一个文件 从历史上看, 所有的InnoDB 表和索引是存储在system 表空间, 这个整体的方法是针对机器专注 ...

  6. Linux下稀疏文件的存储方式

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  7. InnoDB数据页结构

    前言 ​ 关于数据库我们知道是通过内存对磁盘进行操作的,也知道数据会落实到磁盘上,但是数据在磁盘上的存储结构可能大家还不是很清楚. ​ MySQL服务器上负责对表中的数据的读取和写入的工作的部分是存储 ...

  8. InnoDB存储引擎的表空间文件,重做日志文件

    存储引擎文件:因为MySQL表存储引擎的关系,每个存储引擎都会有自己的文件来保存各种数据.这些存储引擎真正存储了数据和索引等数据. 表空间文件 InnoDB存储引擎在存储设计上模仿了Oracle,将存 ...

  9. SQL Server ->> Sparse File(稀疏文件)

    Sparse File(稀疏文件)不是SQL Server的特性.它属于Windows的NTFS文件系统的一个特性.如果某个大文件中的数据包含着大量“0数据”(这个应该从二进制上看),这样的文件就可以 ...

随机推荐

  1. Hdu 5451 Best Solver (2015 ACM/ICPC Asia Regional Shenyang Online) 暴力找循环节 + 递推

    题目链接: Hdu  5451  Best Solver 题目描述: 对于,给出x和mod,求y向下取整后取余mod的值为多少? 解题思路: x的取值为[1, 232],看到这个指数,我的心情是异常崩 ...

  2. SpringMVC-核心配置文件spring-mvc.xml

    @Spring-MVC.xml @MVC的注解驱动 Bean模式 上面源码的配置我们看到了,其中映射器和适配器的注解模式是过时的所以我们需要重新配置一下. <!-- 配置处理器映射器 --> ...

  3. Suricata的性能

    不多说,直接上干货! 见官网 https://suricata.readthedocs.io/en/latest/performance/index.html Docs » 7. Performanc ...

  4. Windows下降权MYSQL和apche的运行级别(普通用户权限运行)

    1.MYSQL的降权运行  新建立一个用户比如mysql  net user mysql microsoft /add  net localgroup users mysql /del  不属于任何组 ...

  5. Docker DOC

    Docker DOC docker是提供给开发或管理人员的容器化部署项目工具 在linux上运行docker 常用命令 docker 安装 #先更新yum yum update; #设置docker仓 ...

  6. AJPFX关于Swing组件的总结

    默认布局管理器是流式布局(FlowLayout) 按钮的建立: jb1=new JButton("香蕉") 面板的建立:jp1=new JPanel(); 设置JFrame的标题: ...

  7. poj1862 Stripies

    思路: 简单贪心. 实现: #include <iostream> #include <cstdio> #include <algorithm> #include ...

  8. 应用程序员眼中的数据库管理系统:API+数据库语言

    应用程序员眼中的数据库管理系统:API+数据库语言 sqlite3_open_v2 https://www.cnblogs.com/cchust/p/5121559.html

  9. MATLAB GUI制作快速入门

    创建空白的GUI在MATLAB命令行中输入guide新建GUI,选择Blank GUI (Default),点击确定后就生成了一个空白的GUI制作界面,如下图所示 图1制作GUI的具体过程简单加法器将 ...

  10. centos7 搭建双网卡bond1(主备模式)实例

    前景须知: 在redhat6 中网卡叫bond,在redhat7及centos7中改名team,此处只记录centos7中双网卡主备搭建过程. 应用情景:实现网络的高可用,防止一条网线或交换机故障影响 ...