17.9.2 InnoDB 页面压缩
InnoDB
支持页面级别的压缩,用于在文件-per-表存储空间中的表。这个特性称为透明页面压缩。页面压缩通过在CREATE TABLE
或ALTER TABLE
中指定COMPRESSION
属性来启用。支持的压缩算法包括Zlib
和LZ4
。
支持的平台
页面压缩需要稀疏文件和洞穿支持。页面压缩在 Windows NTFS 和以下子集的 MySQL 支持 Linux 平台上工作,其中 kernel 级别提供洞穿支持:
-
RHEL 7 及其衍生版本,使用 kernel 版本 3.10.0-123 或更高
-
OEL 5.10 (UEK2) kernel 版本 2.6.39 或更高
-
OEL 6.5 (UEK3) kernel 版本 3.8.13 或更高
-
OEL 7.0 kernel 版本 3.8.13 或更高
-
SLE11 kernel 版本 3.0-x
-
SLE12 kernel 版本 3.12-x
-
OES11 kernel 版本 3.0-x
-
Ubuntu 14.0.4 LTS kernel 版本 3.13 或更高
-
Ubuntu 12.0.4 LTS kernel 版本 3.2 或更高
-
Debian 7 kernel 版本 3.2 或更高
Linux 发行版中的所有文件系统可能不支持洞穿。
当页面被写入时,它将使用指定的压缩算法进行压缩。压缩后的数据将被写入磁盘,where the hole punching mechanism 将从页面末尾释放空白块。如果压缩失败,数据将以原样写出。
在 Linux 系统上,文件系统块大小是用于 hole punching 的单位大小。因此,页面压缩只能工作,如果页面数据可以被压缩到小于或等于 InnoDB
页面大小减去文件系统块大小的大小。例如,如果 innodb_page_size=16K
,并且文件系统块大小为 4K,页面数据必须压缩到小于或等于 12K,以使 hole punching 可以工作。
在 Windows 系统上,基于 NTFS 压缩的稀疏文件基础结构。hole punching 大小是 NTFS 压缩单元,它是 NTFS 集群大小的 16 倍。集群大小和压缩单元见以下表格:
Table 17.13 Windows NTFS 集群大小和压缩单元
Cluster Size | Compression Unit |
---|---|
512 字节 | 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 的 cluster size,并且innodb_ page_size
至少要大于压缩单元的两倍。例如,在 Windows 上启用页面压缩,可以将文件系统创建为 cluster size 为 512 字节(压缩单元为 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
后,写入表空间的操作不再使用页面压缩。要解压现有页面,您必须使用OPTIMIZE TABLE
重建表后设置COMPRESSION=None
。
ALTER TABLE t1 COMPRESSION="None";
OPTIMIZE TABLE t1;
页面压缩元数据可以在信息_schema的INNODB_TABLESPACES
表中找到,以下列出几个重要的列:
-
FS_BLOCK_SIZE
: 文件系统块大小,这是用于填充洞的单位大小。 -
FILE_SIZE
: 文件的明显大小,这表示未压缩文件的最大大小。 -
ALLOCATED_SIZE
: 文件的实际大小,这是磁盘上分配的空间量。
在Unix-类系统上,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
)。一个表可能包含不同压缩设置的页面。
以下示例中,员工表的页面压缩元数据从信息架构INNODB_TABLESPACES
表中检索。
# 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
员工表的页面压缩元数据显示,文件大小为23068672字节,而实际文件大小(带有页面压缩)为19415040字节。文件系统块大小为4096字节,这是用于填充洞的块大小。
Identifying 表 Using Page Compression
要确定启用了页面压缩的表,可以检查信息架构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
,则页面压缩被禁用。 -
页面压缩不支持在共享表空间中存储的表,包括系统表空间、临时表空间和一般表空间。
-
页面压缩不支持undo日志表空间。
-
页面压缩不支持redo日志页。
-
R-树页,用于 spatial索引,不会被压缩。
-
属于压缩表的页(
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和潜在的写入放大。