MySQL InnoDB 透明页压缩(Page Compression)

MySQL InnoDB支持数据压缩,有两种数据压缩方式,第一种为表压缩,通常也称之为行格式压缩,另外一种是页压缩(Page Compression),又叫做透明页压缩(Transparent Page Compression),是一种页面级别的数据压缩,页压缩对操作系统及文件系统有一定的要求。本文主要介绍页压缩的原理及使用方法。

页压缩只支持InnoDB独立表空间:file-per-table

页压缩需要操作系统具有稀疏文件(sparse file)或者文件打孔技术(hole punching)的支持,目前支持这种功能的主流操作系统如下:

  • Windows NTFS
  • RHEL 7 内核 3.10.0-123 及更高版本
  • Ubuntu 14.0.4 LTS 内核 3.13 及更高版本
  • Ubuntu 12.0.4 LTS 内核 3.2 及更高版本
  • Debian 7 内核 3.2 及更高版本

1. 页压缩语法

在create table或者alter table时,加上 COMPRESSION  子句,支持的压缩算法主要有Zlib 和 LZ4。

开启页压缩:
CREATE TABLE t1 (c1 INT) COMPRESSION="zlib";

ALTER TABLE t1 COMPRESSION="zlib";
OPTIMIZE TABLE t1;

禁用页压缩:
ALTER TABLE t1 COMPRESSION="None";
OPTIMIZE TABLE t1;

2. 页压缩原理

当一个页被写入磁盘时,InnoDB使用指定的压缩算法对该页进行压缩,然后将压缩后的数据写入磁盘,此时打孔机制会将压缩后的页尾空闲块进行释放,以减少磁盘空间占用。如果压缩失败,则按照原样写入数据。

在Linux操作系统中,文件系统块大小是打孔的单位尺寸,因此,页压缩后的数据必须小于等于InnoDB页大小减去文件系统块大小的值,才能使页压缩生效。举个例子,InnoDB页大小16K,文件系统块大小4K,页数据必须被压缩到小于等于12K,才能使用打孔机制,减少磁盘空间占用。

在Windows操作系统中,稀疏文件基于NTFS文件系统压缩功能实现,打孔单位尺寸为NTFS压缩单元尺寸,这个尺寸是NTFS簇大小的16倍。NTFS簇大小与压缩单元大小对应关系如下表:

NTFS簇大小NTFS压缩单元大小
512Bytes8KB
1KB16KB
2KB32KB
4KB64KB

同样的,只有当压缩后的数据小于等于InnoDB页大小减去压缩单元的大小时,才能使页压缩生效。默认的NTFS簇大小4KB,压缩单元大小64KB,这就意味着NTFS默认配置下,无法使用页压缩。因此,如果要想页压缩在NTFS文件系统上生效,需要设置NTFS簇大小为512Bytes,此时压缩单元大小为8KB,设置InnoDB页大小为默认的16KB,或者更大的32KB、64KB,才能使页压缩生效。

3. 页压缩的元数据

系统表 INNODB_SYS_TABLESPACES 存储了页压缩相关的元数据,其主要字段含义如下:

INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES

  1. FS_BLOCK_SIZE:文件系统块尺寸,打孔单元的大小。
  2. FILE_SIZE:表示未压缩文件的尺寸。
  3. ALLOCATED_SIZE:在磁盘上分配的文件的实际尺寸。

使用页压缩功能后,ls命令显示的大小是未压缩的大小,而实际的大小使用du命令查看。

  • ls -l tablespace_name.ibd,显示FILE_SIZE大小
  • du --block-size=1 tablespace_name.ibd,显示ALLOCATED_SIZE大小

4. 页压缩的限制和使用注意事项

  1. 如果文件系统块大小或者压缩单元大小乘以2大于innodb页大小时,页压缩将自动失效。
  2. 共享表空间(系统表空间,临时表空间,通用表空间)中的表不支持页压缩。
  3. undo log 和 redo log 表空间不支持页压缩。
  4. 空间索引 R-tree 页 不支持页压缩。
  5. 行格式压缩过的表(ROW_FORMAT=COMPRESSED),不支持页压缩。
  6. 在InnoDB崩溃恢复过程中,更新的页面将以未压缩的形式写出。
  7. 在一个不支持压缩算法的服务器上加载页压缩后的表空间,会导致I/O错误。
  8. 使用一个较大的innodb页大小,比如64KB,文件系统块大小4KB,这样的配置能够提高压缩效果,但是同时也会导致写放大,需要更大的buffer pool,增加I/O消耗。

文章评论

0条评论