Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

17.9.2 InnoDB 页面压缩

InnoDB 支持表驻留在 每个文件表空间 中的页面级压缩。该功能称为 透明页面压缩。页面压缩通过指定 COMPRESSION 属性与 CREATE TABLEALTER TABLE 启用。支持的压缩算法包括 ZlibLZ4

支持的平台

页面压缩需要稀疏文件和 hole punching 支持。页面压缩在 Windows 的 NTFS 上支持,并在以下 MySQL 支持的 Linux 平台上支持,其中内核级别提供 hole punching 支持:

  • RHEL 7 及其衍生版本,使用内核版本 3.10.0-123 或更高版本

  • OEL 5.10 (UEK2) 内核版本 2.6.39 或更高版本

  • OEL 6.5 (UEK3) 内核版本 3.8.13 或更高版本

  • OEL 7.0 内核版本 3.8.13 或更高版本

  • SLE11 内核版本 3.0-x

  • SLE12 内核版本 3.12-x

  • OES11 内核版本 3.0-x

  • Ubuntu 14.0.4 LTS 内核版本 3.13 或更高版本

  • Ubuntu 12.0.4 LTS 内核版本 3.2 或更高版本

  • Debian 7 内核版本 3.2 或更高版本

Note

给定 Linux 发行版的所有可用文件系统可能不支持 hole punching。

页面压缩的工作原理

当一页被写入时,它将使用指定的压缩算法进行压缩。压缩后的数据将被写入磁盘,其中 hole punching 机制释放页面末尾的空块。如果压缩失败,数据将以原始形式写入。

Linux 上的 Hole Punching 大小

在 Linux 系统上,文件系统块大小是 hole punching 的单位大小。因此,页面压缩仅在页面数据可以压缩到小于或等于 InnoDB 页大小减去文件系统块大小时生效。例如,如果 innodb_page_size=16K,文件系统块大小为 4K,则页面数据必须压缩到小于或等于 12K 才能使 hole punching 生效。

Windows 上的 Hole Punching 大小

在 Windows 系统上,基于 NTFS 压缩的基础设施 hole punching 大小是 NTFS 压缩单元,该单元是 NTFS 集群大小的 16 倍。集群大小和压缩单元如下表所示:

表 17.14 Windows NTFS 集群大小和压缩单元

Cluster Size Compression Unit
512 Bytes 8 KB
1 KB 16 KB
2 KB 32 KB
4 KB 64 KB

页面压缩在 Windows 系统上仅在页面数据可以压缩到小于或等于 InnoDB 页大小减去压缩单元大小时生效。

默认的 NTFS 集群大小为 4KB,对应的压缩单元大小为 64KB。这意味着对于 Windows NTFS 的默认配置,页面压缩没有任何益处,因为最大 innodb_page_size 也为 64KB。

要使页面压缩在 Windows 上生效,文件系统必须使用小于 4K 的集群大小,并且 innodb_page_size 必须至少是压缩单元大小的两倍。例如,要使页面压缩在 Windows 上生效,可以使用 512 Bytes 的集群大小(对应的压缩单元大小为 8KB),并将 InnoDB 初始化为 innodb_page_size 值为 16K 或更高。

启用页面压缩

要启用页面压缩,请在 CREATE TABLE 语句中指定 COMPRESSION 属性。例如:

CREATE TABLE t1 (c1 INT) COMPRESSION="zlib";

您也可以在 ALTER TABLE 语句中启用页面压缩。然而,ALTER TABLE ... COMPRESSION 只更新表空间压缩属性。设置新压缩算法后对表空间的写入将使用新设置,但要将新压缩算法应用于现有页面,必须使用 OPTIMIZE TABLE 重建表。

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

禁用页面压缩

要禁用页面压缩,使用 ALTER TABLE 设置 COMPRESSION=None。设置 COMPRESSION=None 后对表空间的写入将不再使用页面压缩。要解压缩现有页面,必须在设置 COMPRESSION=None 后使用 OPTIMIZE TABLE 重建表。

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

页面压缩元数据

页面压缩元数据位于 Information Schema INNODB_TABLESPACES 表中,以下列中:

  • FS_BLOCK_SIZE:文件系统块大小,用于 hole punching 的单位大小。

  • FILE_SIZE:文件的明显大小,表示文件的最大大小,未压缩。

  • ALLOCATED_SIZE:文件的实际大小,表示磁盘上分配的空间量。

Note

在 Unix-like 系统上,ls -l tablespace_name.ibd 显示文件的明显大小(等同于 FILE_SIZE)。要查看磁盘上分配的实际空间量(等同于 ALLOCATED_SIZE),使用 du --block-size=1 tablespace_name.ibd--block-size=1 选项以字节为单位打印分配的空间量,以便与 ls -l 输出进行比较。

使用 SHOW CREATE TABLE 查看当前页面压缩设置(ZlibLz4None)。表可能包含具有不同压缩设置的页面。

在以下示例中,从 Information Schema INNODB_TABLESPACES 表中检索 employees 表的页面压缩元数据。

# Create the employees table with Zlib page compression

CREATE TABLE employees (
    emp_no      INT             NOT NULL,
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no)
) COMPRESSION="zlib";

# Insert data (not shown)

# Query page compression metadata in INFORMATION_SCHEMA.INNODB_TABLESPACES

mysql> SELECT SPACE, NAME, FS_BLOCK_SIZE, FILE_SIZE, ALLOCATED_SIZE FROM
       INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME='employees/employees'\G
*************************** 1. row ***************************
SPACE: 45
NAME: employees/employees
FS_BLOCK_SIZE: 4096
FILE_SIZE: 23068672
ALLOCATED_SIZE: 19415040

employees 表的页面压缩元数据显示,文件的明显大小为 23068672 字节,而实际文件大小(带页面压缩)为 19415040 字节。文件系统块大小为 4096 字节,是 hole punching 使用的块大小。

标识使用页面压缩的表

要标识启用页面压缩的表,可以检查 Information Schema TABLES 表的 CREATE_OPTIONS 列中是否定义了 COMPRESSION 属性:

mysql> SELECT TABLE_NAME, TABLE_SCHEMA, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES 
       WHERE CREATE_OPTIONS LIKE '%COMPRESSION=%';
+------------+--------------+--------------------+
| TABLE_NAME | TABLE_SCHEMA | CREATE_OPTIONS     |
+------------+--------------+--------------------+
| employees  | test         | COMPRESSION="zlib" |
+------------+--------------+--------------------+

SHOW CREATE TABLE 也显示 COMPRESSION 属性,如果使用了该属性。

页面压缩限制和使用注意事项

  • 如果文件系统块大小(或 Windows 上的压缩单元大小)* 2 > innodb_page_size,则禁用页面压缩。

  • 页面压缩不支持共享表空间中的表,包括系统表空间、临时表空间和通用表空间。

  • 页面压缩不支持撤销日志表空间。

  • 页面压缩不支持重做日志页面。

  • R-tree 页,用于空间索引,不被压缩。

  • 属于压缩表(ROW_FORMAT=COMPRESSED)的页面保持不变。

  • 在恢复期间,更新的页面以未压缩形式写出。

  • 在不支持压缩算法的服务器上加载页面压缩表空间将导致 I/O 错误。

  • 在降级到不支持页压缩的早期MySQL版本之前,请取消压缩使用页压缩功能的表。要取消压缩表,请运行 ALTER TABLE ... COMPRESSION=NoneOPTIMIZE TABLE

  • 如果压缩算法在两个服务器上都可用,那么压缩表空间可以在Linux和Windows服务器之间复制。

  • 当将压缩表空间文件从一个主机移到另一个主机时,需要使用保留稀疏文件的实用程序来保留页压缩。

  • 在Fusion-io硬件上使用NVMFS可能比其他平台上实现更好的页压缩,因为NVMFS旨在利用 punch hole 功能。

  • 使用页压缩功能与大型 InnoDB 页大小和相对较小的文件系统块大小可能会导致写入放大。例如,最大 InnoDB 页大小为64KB,文件系统块大小为4KB,可能会改善压缩,但也可能增加缓冲池的需求,从而增加I/O和潜在的写入放大。