InnoDB
支持表驻留在 每个文件表空间 中的页面级压缩。该功能称为 透明页面压缩。页面压缩通过指定 COMPRESSION
属性与 CREATE TABLE
或 ALTER TABLE
启用。支持的压缩算法包括 Zlib
和 LZ4
。
支持的平台
页面压缩需要稀疏文件和 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 或更高版本
给定 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
:文件的实际大小,表示磁盘上分配的空间量。
在 Unix-like 系统上,ls -l
显示文件的明显大小(等同于 tablespace_name
.ibdFILE_SIZE
)。要查看磁盘上分配的实际空间量(等同于 ALLOCATED_SIZE
),使用 du --block-size=1
。 tablespace_name
.ibd--block-size=1
选项以字节为单位打印分配的空间量,以便与 ls -l
输出进行比较。
使用 SHOW CREATE TABLE
查看当前页面压缩设置(Zlib
、Lz4
或 None
)。表可能包含具有不同压缩设置的页面。
在以下示例中,从 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=None
和OPTIMIZE TABLE
。 -
如果压缩算法在两个服务器上都可用,那么压缩表空间可以在Linux和Windows服务器之间复制。
-
当将压缩表空间文件从一个主机移到另一个主机时,需要使用保留稀疏文件的实用程序来保留页压缩。
-
在Fusion-io硬件上使用NVMFS可能比其他平台上实现更好的页压缩,因为NVMFS旨在利用 punch hole 功能。
-
使用页压缩功能与大型
InnoDB
页大小和相对较小的文件系统块大小可能会导致写入放大。例如,最大InnoDB
页大小为64KB,文件系统块大小为4KB,可能会改善压缩,但也可能增加缓冲池的需求,从而增加I/O和潜在的写入放大。