InnoDB Plugin新特性:压缩表

Plugin的一个重要的特性就是增加了压缩存储。对于数据中有很多Long column(包括TEXT BLOB或者大VARCHAR)的场景能够大幅节约空间,并提升效率。

1. 谁需要压缩?

在InnoDB中,是以16K的页(Page)为基本的存储单位的。我们知道,InnoDB是的数据是在Clustered index中存储的,在Secondary index中仅存储对应数据的PK。Clustered index和Secondary index都是B-Tree结构的,所以对InnoDB数据页和索引页的压缩很大程度上就是对B-Tree节点页的压缩

在InnoDB中,除了B-Tree节点页,还有一类数据页(Page),称为“overflow page”。当需要存储Long column时,如果当前页能够完全存储全部字段时,则存储在当前页中;如果当前页不足以存储全部,则InnoDB选择最长的字段,将其存储到一个单独的页中,我们称这样的页为“overflow page”,而原数据页仅仅需存储一个20Bytes的指针。参考下图:

InnoDB_overflow_page

所以InnoDB除了有上面的B-Tree页外,InnoDB还存储overflow页。事实上,需要压缩的数据页也就是这两类,InnoDB为了获得更好的效率,针对这两类数据页的压缩是使用不同的策略的。

2. 如何压缩B-Tree页

未来尽可能多的避免压缩、解压带来的额外消耗,InnoDB在压缩后的B-Tree页中新增了一个modification log区,通过记录当前的页的修改日志,来避免频繁压缩解压(参考左图)。

InnoDB_Page_compression

当modification log空间不足时,才进行解压并应用这些Log,然后再压缩回去。如果必要,这里可能会出现B-Tree页的分裂。

3. 如何压缩over-flow页

overflow的压缩页面则相对简单,仅包含一个页面头(header),页面尾(Trailer)中间就是压缩数据。试想,如果存储的Long Column是能够高度压缩的内容(例如文本,Xml等),这样将节省很多的存储空间,进而能够节省I/O。(参考下图)InnoDB_over_page_2

4. 压缩的算法是什么

压缩使用的是zlib library中的LZ77算法。

5. 压缩和Buffer Pool

当使用压缩存储的页面,当Buffer Pool载入后,会将其解压。这时,该页面在Buffer Pool中同时存在“压缩版”和“解压版”。当Buffer Pool需要驱逐这些页的时候,有两种情况会发生:如果InnoDB认为当前应用是IO-Bound,相比CPU还有额外能力来做解压操作,则InnoDB选择仅驱逐页面的“解压版”;否则InnoDB会将页面的两个版本同时驱逐出去。也就是说Buffer Pool会是下图的状态:

Compress_Buffer_Pool

6. 如何创建一个压缩数据表

原理是复杂的,操作其实很简单:

CREATE TABLE name (column1 INT PRIMARY KEY) ENGINE=InnoDB
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=4;

这里创建了一个,压缩后页面大小为4K(默认为8K)的压缩数据表。

参考文献:InnoDB Plugin User Guide

(全文完)

In:

3 responses to “InnoDB Plugin新特性:压缩表”

  1. […] plugin 官方手册 innodb plugin 特性 innodb compression  woes inodb compression:when more is lesss This entry was posted in […]

  2. Mablevi

    周兄,你好。
    想请教一下:当使用compressed格式的话,指定Key_block_size 一般为多少才合适?
    看了 http://venublog.com/2008/04/25/innodb-plugin-row-format-performance/ 的作者,测试下来8k比4k好。这里的8K还是4K 是不是针对1个page 16K 来讲的?

    用compressed 的话,从文中看出主要是为压缩 溢出页 的大小,从而减少IO,要是表里都是小字段。不会产生溢出页,有必要没有必要用compressed文件格式。

    最后一点是,这个文件格式和buffer pool 大小有关系吗?从刚才的网址的文章里得出的结果是:
    当整个数据文件的大小 小于 buffer pool 用默认的compact 反而好,而用compressed更差;
    当整个数据文件的大小 大于 buffer pool 用compressed 好。

    求解。

  3. (1) 没有绝对的说8K就优于或者劣于4K,否则为什么不设成默认的呢?
    (2) 一般来说,较小的页更适合OLTP的应用,之类应用单挑记录相对较小,一次读取相对离散
    (3) 8K好还是4K好,需要用你自己的场景测试
    (4) 压缩是针对任何页面,不光是溢出的。不溢出的的场景一样可以大大受益,原因在于,压缩后,同样的内存可以缓存更多的数据
    (5) 压缩和BP大小关系不大。因为压缩的一个重要好处就是内存利用更高了(同样的内存存储更多的数据),所以如果你的内存大于实际数据量,这个好处也就没有了,而且压缩会带来额外的CPU消耗。

Leave a Reply

Your email address will not be published. Required fields are marked *