MySQL InnoDB文件格式管理

InnoDB文件格式管理
随着InnoDB的发展,数据文件格式有时需要与以前版本的InnoDB不兼容,以支持新特性。为了在升级和降级的情况下管理兼容性,以及运行不同版本MySQL的系统,InnoDB使用命名文件格式。InnoDB目前支持两种命名文件格式,Antelope和Barracuda。

.Antelope是原始的InnoDB文件格式,以前没有一个名字。它支持紧凑和冗余的InnoDB表行格式。

.Barracuda是最新的文件格式。它支持所有InnoDB行格式,包括较新的compressed和dynamic行格式。与compressed和dynamic行格式相关的特性包括压缩表、页外列的高效存储以及高达3072字节的索引键前缀(innodb_large_prefix)。

这将讨论为新的InnoDB表启用InnoDB文件格式,验证MySQL版本之间不同文件格式的兼容性,以及识别正在使用的文件格式。

InnoDB文件格式设置不适用于存储在一般表空间中的表。通用表空间提供对所有行格式和相关特性的支持。

以下文件格式配置参数有新的默认值:
.innodb_file_format默认值修改为Barracuda。之前的默认值是Antelope。

.innodb_large_prefix默认值修改为ON。之前的默认值是OFF。

以下文件格式配置参数已弃用,并可能在将来的版本中删除:
.innodb_file_format

.innodb_file_format_check

.innodb_file_format_max

.innodb_large_prefix

文件格式配置参数用于创建与MySQL 5.1中早期版本的InnoDB兼容的表。现在MySQL 5.1已经结束了它的产品生命周期,不再需要这些参数。

启用文件格式
innodb_file_format配置选项为file-per-table表空间启用一个InnoDB文件格式。

Barracuda是默认的innodb_file_format设置。在早期版本中,默认的文件格式是Antelope。

innodb_file_format配置选项已弃用,可能在将来的版本中被删除。

当你启动mysqld时,你可以在命令行中设置innodb_file_format的值,或者在选项文件中(Unix上是my.cnf, Windows上是my.ini)。你也可以使用SET GLOBAL语句动态地修改它。

SET GLOBAL innodb_file_format=Barracuda;

使用说明
.InnoDB文件格式设置不适用于存储在一般表空间中的表。通用表空间提供对所有行格式和相关特性的支持。

.当使用CREATE table或ALTER table的TABLESPACE [=] innodb_system 表选项在system表空间中存储动态表时,innodb_file_format设置不适用。

.在创建使用动态行格式的表时,innodb_file_format设置会被忽略。

验证文件格式兼容性
InnoDB包含了一些检查来防止可能发生的崩溃和数据损坏,如果你对运行在旧版本的MySQL服务器上的InnoDB数据文件使用新文件格式可能会发生。这些检查发生在服务器启动时,以及用户第一次访问表时。本节描述这些检查,如何控制它们,以及可能出现的错误和警告条件。

向后兼容性
你只需要在使用最新版本的InnoDB (InnoDB的MySQL 5.5或更高版本)和旧版本(MySQL 5.1或更早版本,内置InnoDB而不是InnoDB插件)时考虑向后的文件格式兼容性。为了尽量减少兼容性问题,你可以在所有MySQL 5.1和更早版本的数据库服务器上使用InnoDB插件进行标准化。

一般来说,新版本的InnoDB创建的表或索引在旧版本的InnoDB中无法安全地读取或写入,而不会有崩溃、挂起、错误结果或损坏的风险。InnoDB提供了一种机制来防范这些情况,并有助于保持数据库文件和InnoDB版本之间的兼容性。这种机制可以让你利用InnoDB版本的一些新特性(如性能改进和bug修复),同时通过防止意外使用创建向下不兼容的磁盘文件的新特性,仍然保留使用旧版本InnoDB数据库的选择。

如果某个版本的InnoDB支持一种特定的文件格式(不管这种格式是否是默认的),你就可以查询和更新任何需要这种格式或更早的格式的表。根据所启用的特定文件格式,只有使用新特性创建新表的操作受到限制。相反,如果表空间包含一个使用不支持的文件格式的表或索引,则根本无法访问它,即使是读访问。

将InnoDB表空间“降级”为早期的Antelope文件格式的唯一方法是将数据复制到使用早期格式的新表中。

确定一个已经存在的InnoDB表空间的文件格式最简单的方法是检查它所包含的表的属性,使用SHOW table STATUS命令或者查询表INFORMATION_SCHEMA.TABLES。如果表的Row_format被报告为’Compressed’或’Dynamic’,则包含该表的表空间支持Barracuda格式。

内部细节
每个InnoDB file-per-table表空间(由一个*.ibd文件)文件标记了文件格式标识符。system表空间(由ibdata文件表示)被标记为在一组InnoDB数据库文件中使用的“最高”文件格式,并且当文件被打开时检查这个标记。

创建一个压缩表,或者一个带有ROW_FORMAT=DYNAMIC的表,更新对应file-per-table .ibd文件的文件头和InnoDB数据字典中的表类型,其中包含Barracuda文件格式的标识符。从那以后,这个表就不能在不支持Barracuda文件格式的InnoDB版本中使用了。为了防止异常行为,InnoDB会在打开表时进行兼容性检查。(在很多情况下,ALTER TABLE语句会重新创建一个表,从而改变它的属性。)

一般的表空间,也用*.ibd文件表示,支持Antelope和Barracuda文件格式。

ib文件集的定义
为了避免混淆,为了讨论的目的,我们将术语“ib文件集”定义为InnoDB作为一个单元管理的操作系统文件集。ib文件集合包括以下文件:

.系统表空间(一个或多个ibdata文件),包含内部系统信息(包括内部目录和undo信息),可能包括用户数据和索引。

.零个或多个单表表空间(也称为“file per table”文件,命名为*.ibd文件)。

.InnoDB日志文件;通常有两个,ib_logfile0和ib_logfile1。用于崩溃恢复和备份。

“ib文件集”不包含包含InnoDB表元数据的对应的.frm文件。.frm文件由MySQL创建和管理,有时会与InnoDB中的内部元数据不同步。

多个表(甚至来自多个数据库)可以存储在一个“ib文件集”中。(在MySQL中,“数据库”是表的逻辑集合,其他系统称之为“模式”或“目录”。)

InnoDB启动时的兼容性检查
当InnoDB打开ib文件集时,为了防止可能的崩溃或数据损坏,它会检查是否完全支持ib文件集中正在使用的文件格式。如果系统在崩溃后重新启动,或者“快速关机”(即innodb_fast_shutdown大于零),磁盘上的数据结构(如redo或undo条目,或doublewrite页面)可能对当前软件来说是“太新的”格式。在恢复过程中,如果访问了这些数据结构,可能会对数据文件造成严重的破坏。文件格式的启动检查在任何恢复过程开始之前进行,从而防止新表的一致性问题或MySQL服务器的启动问题。

从版本InnoDB 1.0.1开始,system表空间记录了ib文件集中任何表空间中任何表使用的“最高”文件格式的标识符或标记。这个文件格式标签的检查由配置参数innodb_file_format_check控制,默认是开启的。

如果system表空间中的文件格式标签比当前执行的软件支持的最高版本更新或更高,并且innodb_file_format_check开启,则在服务器启动时会发出以下错误:

InnoDB: Error: the system tablespace is in a
file format that this version doesn't support

mysql> show variables like 'innodb_file_format_check';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_file_format_check | ON    |
+--------------------------+-------+
1 row in set (0.01 sec)

mysql> show variables like 'innodb_file_format';
+--------------------+-----------+
| Variable_name      | Value     |
+--------------------+-----------+
| innodb_file_format | Barracuda |
+--------------------+-----------+
1 row in set (0.02 sec)

也可以设置“innodb_file_format”为文件格式名称。如果当前软件不支持指定的文件格式,这样做可以防止InnoDB启动。它还将“高水位标记”设置为指定的值。如果你手动“降级”ib文件集中的所有表,那么设置innodb_file_format_check的能力(在未来的版本中)是很有用的。如果你随后使用旧版本的InnoDB来访问ib文件集,那么你可以依赖启动时的文件格式检查。

在某些有限的情况下,您可能希望启动服务器并使用ib文件集,该文件集是您正在使用的软件不支持的新文件格式。如果你把配置参数innodb_file_format_check设置为OFF, InnoDB会打开数据库,但会在错误日志中显示如下警告信息:

InnoDB: Warning: the system tablespace is in a
file format that this version doesn't support

这是一个危险的设置,因为它允许恢复过程运行,如果之前的关闭是崩溃或“快速关闭”,可能会破坏数据库。

只有当你确定上一次关闭innodb_fast_shutdown=0时,才应该将innodb_file_format_check设置为OFF,这样基本上没有恢复过程发生。

参数innodb_file_format_check只影响打开数据库时发生的操作,不会影响后续操作。相反,参数innodb_file_format(启用特定的格式)只确定是否可以以启用的格式创建新表,对数据库是否可以打开没有影响。

文件格式标记是一个“高水位标记”,如果创建了一个“更高”格式的表,或者访问一个现有的表进行读或写(假设支持它的格式),那么在服务器启动后,它就会增加。如果你以高于运行软件支持的格式访问一个已经存在的表,系统表空间标签不会更新,但是表级别的兼容性检查会应用(并且会发出错误),如14.10.2.2节“打开表时兼容性检查”所述。每当高水位线更新时,innodb_file_format_check的值也会更新,因此执行SELECT @@innodb_file_format_check;显示当前打开的ib文件集中的表使用的、当前执行软件支持的最新文件格式的名称。

mysql> SELECT @@innodb_file_format_check;
+----------------------------+
| @@innodb_file_format_check |
+----------------------------+
|                          1 |
+----------------------------+
1 row in set (0.00 sec)

打开表时检查兼容性
当第一次访问表时,InnoDB(包括一些InnoDB 1.0之前的版本)会检查存储表的表空间的文件格式是否完全支持。这种检查可以防止使用“太新”数据结构的表出现崩溃或损坏。

使用某个版本支持的任何文件格式的所有表都可以读或写(假设用户有足够的权限)。设置系统配置参数innodb_file_format可以防止创建使用特定文件格式的新表,即使给定的版本支持这种文件格式。这样的设置可以用来保持向后兼容性,但它不会阻止访问任何使用支持的格式的表。

如果在创建表时使用了新的文件格式,那么5.0.21之前的MySQL版本不能可靠地使用新版本创建的数据库文件。为了防止各种错误或损坏,InnoDB在打开文件时(例如,第一次访问一张表时)会检查文件格式的兼容性。如果当前运行的InnoDB版本不支持InnoDB数据字典中表类型标识的文件格式,MySQL报告如下错误:

ERROR 1146 (42S02): Table 'test.t1' doesn't exist

InnoDB也会在错误日志中写入一条消息:

InnoDB: table test/t1: unknown table type 33

MySQL 4.1之前的InnoDB版本在数据库文件中不包含表格式标识符,MySQL 5.0.21之前的版本不包含表格式兼容性检查。因此,如果在5.0.21之前的InnoDB版本中使用了较新的文件格式的表,则无法确保操作是正确的。

InnoDB 1.0及更高版本的文件格式管理能力(表空间标记和运行时检查)允许InnoDB尽快验证运行版本的软件能够正确处理数据库中存在的表。

如果你允许InnoDB打开一个包含它不支持的文件格式的数据库(通过设置参数innodb_file_format_check为OFF),本节描述的表级检查仍然适用。

在使用InnoDB插件的MySQL 5.1之前的版本中强烈建议用户不要使用包含Barracuda文件格式表的数据库文件。可以使用Antelope格式重建这样的表。

识别正在使用的文件格式
如果您使用innodb_file_format配置选项启用不同的文件格式,则更改仅适用于新创建的表。此外,当您创建一个新表时,包含该表的表空间被标记为支持表特性所需的“最早”或“最简单”文件格式。例如,如果您启用了Barracuda文件格式,并创建了一个不使用Dynamic或Compressed行格式的新表,那么包含该表的新表空间将被标记为使用Antelope文件格式。

很容易识别给定表使用的文件格式。如果SHOW TABLE STATUS报告的行格式是Compact或Redundant,则表使用Antelope文件格式。如果SHOW TABLE STATUS报告的行格式是Compressed或Dynamic,则表使用Barracuda文件格式。


mysql> SHOW TABLE STATUS\G
*************************** 1. row ***************************
           Name: big_table
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 3370592
 Avg_row_length: 205
    Data_length: 694140928
Max_data_length: 0
   Index_length: 0
      Data_free: 3145728
 Auto_increment: 3326977
    Create_time: 2023-07-06 18:05:18
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb4_general_ci
       Checksum: NULL
 Create_options:
        Comment:

您还可以使用InnoDB INFORMATION_SCHEMA表识别给定表或表空间使用的文件格式。例如:

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='undo/big_table'\G
*************************** 1. row ***************************
     TABLE_ID: 488
         NAME: undo/big_table
         FLAG: 33
       N_COLS: 25
        SPACE: 487
  FILE_FORMAT: Barracuda
   ROW_FORMAT: Dynamic
ZIP_PAGE_SIZE: 0
   SPACE_TYPE: Single
1 row in set (0.00 sec)


mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE NAME='undo/big_table'\G
*************************** 1. row ***************************
         SPACE: 487
          NAME: undo/big_table
          FLAG: 33
   FILE_FORMAT: Barracuda
    ROW_FORMAT: Dynamic
     PAGE_SIZE: 16384
 ZIP_PAGE_SIZE: 0
    SPACE_TYPE: Single
 FS_BLOCK_SIZE: 4096
     FILE_SIZE: 708837376
ALLOCATED_SIZE: 708841472
1 row in set (0.00 sec)

修改文件格式
每个InnoDB表空间文件(名称匹配*.ibd)都被标记为用于创建其表和索引的文件格式。修改文件格式的方法是重新创建表及其索引。重建表及其索引的最简单方法是在每个想要修改的表上使用以下命令:

ALTER TABLE t ROW_FORMAT=format_name;

如果您正在修改文件格式以降级到较旧的MySQL版本,则可能存在表存储格式的不兼容性,需要额外的步骤。

发表评论

电子邮件地址不会被公开。