2019独角兽企业重金招聘Python工程师标准>>>
InnoDB的数据文件格式(File-Format)
在早期的InnoDB版本中,由于文件格式只有一种,因此不需要为此文件格式命名。随着InnoDB引擎的发展,开发出了不兼容早期版本的新文件格式,用于支持新的功能。为了在升级和降级情况下帮助管理系统的兼容性,以及运行不同的MySQL版本,InnoDB开始使用命名的文件格式。
目前,InnoDB只支持两种文件格式:Antelope 和 Barracuda。
- Antelope: 先前未命名的,原始的InnoDB文件格式。它支持两种行格式:COMPACT 和 REDUNDANT。MySQL5.6的默认文件格式。可以与早期的版本保持最大的兼容性。不支持 Barracuda 文件格式。
- Barracuda: 新的文件格式。它支持InnoDB的所有行格式,包括新的行格式:COMPRESSED 和 DYNAMIC。与这两个新的行格式相关的功能包括:InnoDB表的压缩,长列数据的页外存储和索引建前缀最大长度为3072字节(innodb_large_prefix)。
启用文件格式
innodb_file_format 配置可以启用InnoDB文件格式。默认值为Antelope。
有三种方式可以修改 innodb_file_format 参数的值:
- 在命令行启动mysqld的时候
- 在my.cnf文件中
- 通过 SET GLOBAL 语句动态修改
mysql> SET GLOBAL innodb_file_format=Barracuda;
Query OK, 0 rows affected (0.00 sec)
尽管MySQL推荐使用 Barracuda 文件格式,但是MySQL5.6的默认文件格式是 Antelope。
查看当前使用的文件格式
当使用 innodb_file_format 参数启用不同的文件格式后,只有新创建的表会使用此文件格式。
有两种方式可以查看表使用的文件格式:
- 通过 SHOW TABLE STATUS 命令
- 通过 InnoDB INFORMATION_SCHEMA 查看指定的表或表空间的文件格式
mysql> SHOW TABLE STATUS\G
*************************** 1. row ***************************Name: t1Engine: InnoDBVersion: 10Row_format: CompactRows: 0Avg_row_length: 0Data_length: 16384
Max_data_length: 0Index_length: 16384Data_free: 0Auto_increment: 1Create_time: 2014-11-03 13:32:10Update_time: NULLCheck_time: NULLCollation: latin1_swedish_ciChecksum: NULLCreate_options:Comment:mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1'\G
*************************** 1. row ***************************TABLE_ID: 44NAME: test/t1FLAG: 1N_COLS: 6SPACE: 30FILE_FORMAT: AntelopeROW_FORMAT: Compact
ZIP_PAGE_SIZE: 0mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE NAME='test/t1'\G
*************************** 1. row ***************************SPACE: 30NAME: test/t1FLAG: 0FILE_FORMAT: AntelopeROW_FORMAT: Compact or RedundantPAGE_SIZE: 16384
ZIP_PAGE_SIZE: 0
修改文件格式
设置了指定文件格式的InnoDB表空间文件(.idb文件)被用来创建表和索引。可以通过重建表和表中索引的方式修改文件格式。重建表及其索引的最简单的方法是在要修改的表上执行下面命令:
ALTER TABLE t ROW_FORMAT=format_name;
InnoDB表的行格式
接下来介绍这些行格式支持的功能,以及如何选择正确的行格式。
InnoDB行存储概述
InnoDB表的数据存储在页(page)中,每个页可以存放多条记录。这些页以树形结构组织,这颗树称为B树索引。表中数据和辅助索引都是使用B树结构。维护表中所有数据的这颗B树索引称为聚簇索引,通过主键来组织的。聚簇索引的叶子节点包含行中所有字段的值,辅助索引的叶子节点包含索引列和主键列。
变长字段是个例外,例如对于BLOB和VARCHAR类型的列,当页不能完全容纳此列的数据时,会将此列的数据存放在称为溢出页(overflow page)的单独磁盘页上,称这些列为页外列(off-page column)。这些列的值存储在以单链表形式存在的溢出页列表中,每个列都有自己溢出页列表。某些情况下,为了避免浪费存储空间和消除读取分隔页,列的所有或前缀数据会存储在B+树索引中。
设置表的行格式
可在 CREATE TABLE 和 ALTER TABLE 语句的 ROW_FORMAT 子句指定表的行格式。例如:
CREATE TABLE t1 (f1 int unsigned) ROW_FORMAT=DYNAMIC ENGINE=INNODB;
InnoDB的ROW_FORMAT取值包含:COMPACT, REDUNDANT, DYNAMIC 和 COMPRESSED。对于InnoDB表,默认的行格式为:COMPACT。
InnoDB表中行的物理结构由行格式决定。更多信息查看:Physical Row Structure of InnoDB Tables
COMPACT 和 REDUNDANT 行格式
对于 COMPACT 和 REDUNDANT 行格式,InnoDB将变长字段(VARCHAR, VARBINARY, BLOB 和 TEXT)的前786字节存储在B+树节点中,其余的数据存放在溢出页中。InnoDB也会将大于等于786字节的固定长度字段转换为变长字段,以便能够在页外存储。例如,一个类型为 char(255) 的列,若此列字符集的最大字节长度超过3个字节,则它可能超过786字节,就像字符集 utf8mb4。
使用Antelope文件格式,若字段的值小于等于786字节,不需要溢出页,因为字段的值都在B+树节点中,所以会降低I/O操作。这对于相对较短的BLOB字段有效,但可能由于B+树节点存储过多的数据而导致效率低下。
为了保持与先前InnoDB版本的兼容性,MySQL5.6创建的表默认文件格式为 COMPACT。
DYNAMIC 和 COMPRESSED 行格式
要想使用这两种文件格式,变量 innodb_file_format 的值必须设置为:Barracuda,同时必须开启 innodb_file_per_table 功能。(Barracuda文件格式也支持 COMPACT 和 REDUNDANT 行格式。)
当创建表时指定行格式为 DYNAMIC 或 COMPRESSED,InnoDB可以将边长字段的值全部存储在溢出页中,而聚簇索引页中只包含指向溢出页的长度为20字节的指针。跟 COMPACT 行格式一样,InnoDB也会将长度大于等于786字节的定长字段转换为边长字段。
列是否存储到溢出页取决于页的大小和行的大小。若行太长,InnoDB会将最长的列存储到溢出页中,直到聚簇索引记录能够放在B+树页中。长度小于等于40字节的 TEXT 和 BLOB 列存储在B+树页中。
若行的全部数据都能存放在索引页中,则 DYNAMIC 格式可以跟 COMPACT 和 REDUNDANT 格式保持同样的效率,但是 DYNAMIC 格式避免了长的列将大量字节数据填充到B+树节点中的问题。跟 COMPACT 格式将一部分数据存储在溢出页中相比,将过长列的数据完全存放在溢出页中更高效。
对于页外存储,COMPRESSED 格式跟 DYNAMIC 类似,不同的是,COMPRESSED 格式可以将表和索引的数据进行压缩。
相关阅读
- InnoDB File-Format Management
- InnoDB Row Storage and Row Formats