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

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

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. two_sum问题

    def two_sum(li, target): for i in range(len(li)): for j in range(i+1, len(li)): if li[i] + li[j] == ...

  2. Codeforces Round #402 (Div. 2) B

    Description Polycarp is crazy about round numbers. He especially likes the numbers divisible by 10k. ...

  3. 洛谷 P1072 Hankson 的趣味题 || 打质数表的分解质因数

    方法就是枚举,根据b0和b1可以大大减小枚举范围,方法类似这个http://blog.csdn.net/hehe_54321/article/details/76021615 将b0和b1都分解质因数 ...

  4. 递推DP URAL 1244 Gentlemen

    题目传送门 /* 题意:给出少了若干卡片后的总和,和原来所有卡片,问少了哪几张 DP:转化为少了的总和是否能有若干张卡片相加得到,dp[j+a[i]] += dp[j]; 记录一次路径,当第一次更新的 ...

  5. 题解报告:hdu 2196 Computer(树形dp)

    Problem Description A school bought the first computer some time ago(so this computer's id is 1). Du ...

  6. Python读取文件行数不对

    对于一个大文件,读取每一个行然后处理,用readline()方法老是读不全,会读到一半就结束,也不报错: 总之处理的行数跟 wc -l 统计的不一样,调试了一下午,改用 with open('xxx. ...

  7. springboot 配置Ehcache

    Ehcache的基本配置说明我就不说了.小编记录一下在springboot中使用Ehcache的使用方法. 第一步:在classpath下引入配置文件ehcache.xml 代码如下: <ehc ...

  8. SpringBoot 2.x (7):拦截器

    类似以前SpringMVC的拦截器,但也有一些区别 SpringBoot的拦截器有两种方式: 第一种方式:过时的方式,适用于SpringBoot1.x的方式 package org.dreamtech ...

  9. 洛谷P2774 方格取数问题(最小割)

    题意 $n \times m$的矩阵,不能取相邻的元素,问最大能取多少 Sol 首先补集转化一下:最大权值 = sum - 使图不连通的最小权值 进行黑白染色 从S向黑点连权值为点权的边 从白点向T连 ...

  10. MY $MYVIMRC

    set nocompatiblesource $VIMRUNTIME/vimrc_example.vim"source $VIMRUNTIME/mswin.vim"behave m ...