本节介绍如何使用可移植表空间功能导入表,该功能允许导入位于每个表一个文件表空间中的表、分区表或单个表分区。您可能需要导入表的原因有很多
在非生产 MySQL 服务器实例上运行报表,以避免在生产服务器上增加负载。
将数据复制到新的副本服务器。
从备份的表空间文件恢复表。
作为比导入转储文件更快的移动数据的方式,转储文件需要重新插入数据和重建索引。
将数据移动到存储介质更适合您的存储需求的服务器。例如,您可能将繁忙的表移动到 SSD 设备,或将大型表移动到高容量 HDD 设备。
可移植表空间功能在本节的以下主题中进行了介绍
必须启用
innodb_file_per_table变量,默认情况下已启用。表空间的页面大小必须与目标 MySQL 服务器实例的页面大小匹配。
InnoDB页面大小由innodb_page_size变量定义,该变量在初始化 MySQL 服务器实例时配置。如果表存在外键关系,则在执行
DISCARD TABLESPACE之前必须禁用foreign_key_checks。此外,您应该在时间上相同逻辑点导出所有外键相关表,因为ALTER TABLE ... IMPORT TABLESPACE不会对导入的数据强制执行外键约束。为此,请停止更新相关表,提交所有事务,获取表的共享锁,并执行导出操作。从另一个 MySQL 服务器实例导入表时,两个 MySQL 服务器实例都必须具有通用可用性 (GA) 状态,并且版本必须相同。否则,必须在与导入表相同的 MySQL 服务器实例上创建表。
如果表是在外部目录中创建的,方法是在
CREATE TABLE语句中指定DATA DIRECTORY子句,那么您在目标实例上替换的表必须使用相同的DATA DIRECTORY子句定义。如果子句不匹配,则会报告模式不匹配错误。要确定源表是否使用DATA DIRECTORY子句定义,请使用SHOW CREATE TABLE查看表定义。有关使用DATA DIRECTORY子句的信息,请参见第 17.6.1.2 节,“在外部创建表”。如果在表定义中未明确定义
ROW_FORMAT选项或使用了ROW_FORMAT=DEFAULT,则源实例和目标实例上的innodb_default_row_format设置必须相同。否则,当您尝试导入操作时,会报告模式不匹配错误。请使用SHOW CREATE TABLE检查表定义。请使用SHOW VARIABLES检查innodb_default_row_format设置。有关相关信息,请参见定义表的行格式。
此示例演示如何导入驻留在每个表表空间中的文件的常规非分区表。
在目标实例上,创建一个与您要导入的表具有相同定义的表。(您可以使用
SHOW CREATE TABLE语法获取表定义。)如果表定义不匹配,则在您尝试导入操作时将报告架构不匹配错误。mysql> USE test; mysql> CREATE TABLE t1 (c1 INT) ENGINE=INNODB;在目标实例上,丢弃刚创建的表的表空间。(在导入之前,您必须丢弃接收表的表空间。)
mysql> ALTER TABLE t1 DISCARD TABLESPACE;在源实例上,运行
FLUSH TABLES ... FOR EXPORT使您要导入的表静止。当表处于静止状态时,仅允许对该表进行只读事务。mysql> USE test; mysql> FLUSH TABLES t1 FOR EXPORT;FLUSH TABLES ... FOR EXPORT确保对命名表的更改被刷新到磁盘,以便在服务器运行时可以制作二进制表副本。当运行FLUSH TABLES ... FOR EXPORT时,InnoDB会在表的架构目录中生成一个.cfg元数据文件。该.cfg文件包含在导入操作期间用于架构验证的元数据。注意执行
FLUSH TABLES ... FOR EXPORT的连接在操作运行期间必须保持打开状态;否则,当连接关闭时,.cfg文件将被删除,因为锁被释放。将
.ibd文件和.cfg元数据文件从源实例复制到目标实例。例如$> scp /path/to/datadir/test/t1.{ibd,cfg} destination-server:/path/to/datadir/test必须在释放共享锁之前复制
.ibd文件和.cfg文件,如下一步骤所述。注意如果您要从加密的表空间导入表,
InnoDB除了生成.cfg元数据文件之外,还会生成一个.cfp文件。该.cfp文件必须与.cfg文件一起复制到目标实例。该.cfp文件包含一个传输密钥和一个加密的表空间密钥。在导入时,InnoDB使用传输密钥来解密表空间密钥。有关相关信息,请参阅 第 17.13 节“InnoDB 数据静止加密”。在源实例上,使用
UNLOCK TABLES释放由FLUSH TABLES ... FOR EXPORT语句获取的锁mysql> USE test; mysql> UNLOCK TABLES;UNLOCK TABLES操作还会删除.cfg文件。在目标实例上,导入表空间
mysql> USE test; mysql> ALTER TABLE t1 IMPORT TABLESPACE;
此示例演示如何导入分区表,其中每个表分区驻留在每个表表空间中。
在目标实例上,创建一个与您要导入的分区表具有相同定义的分区表。(您可以使用
SHOW CREATE TABLE语法获取表定义。)如果表定义不匹配,则在您尝试导入操作时将报告架构不匹配错误。mysql> USE test; mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 3;在
/目录中,每个三个分区都有一个表空间datadir/test.ibd文件。mysql> \! ls /path/to/datadir/test/ t1#p#p0.ibd t1#p#p1.ibd t1#p#p2.ibd在目标实例上,丢弃分区表的表空间。(在导入操作之前,您必须丢弃接收表的表空间。)
mysql> ALTER TABLE t1 DISCARD TABLESPACE;分区表的三个表空间
.ibd文件将从/目录中丢弃。datadir/test在源实例上,运行
FLUSH TABLES ... FOR EXPORT使您要导入的分区表静止。当表处于静止状态时,仅允许对该表进行只读事务。mysql> USE test; mysql> FLUSH TABLES t1 FOR EXPORT;FLUSH TABLES ... FOR EXPORT确保对命名表的更改被刷新到磁盘,以便在服务器运行时可以制作二进制表副本。当运行FLUSH TABLES ... FOR EXPORT时,InnoDB会为表的每个表空间文件在表的架构目录中生成.cfg元数据文件。mysql> \! ls /path/to/datadir/test/ t1#p#p0.ibd t1#p#p1.ibd t1#p#p2.ibd t1#p#p0.cfg t1#p#p1.cfg t1#p#p2.cfg这些
.cfg文件包含在导入表空间时用于架构验证的元数据。FLUSH TABLES ... FOR EXPORT只能对表运行,不能对单个表分区运行。将
.ibd和.cfg文件从源实例架构目录复制到目标实例架构目录。例如$>scp /path/to/datadir/test/t1*.{ibd,cfg} destination-server:/path/to/datadir/test必须在释放共享锁之前复制
.ibd和.cfg文件,如下一步骤所述。注意如果您要从加密的表空间导入表,
InnoDB除了生成.cfg元数据文件之外,还会生成一个.cfp文件。该.cfp文件必须与.cfg文件一起复制到目标实例。该.cfp文件包含一个传输密钥和一个加密的表空间密钥。在导入时,InnoDB使用传输密钥来解密表空间密钥。有关相关信息,请参阅 第 17.13 节“InnoDB 数据静止加密”。在源实例上,使用
UNLOCK TABLES释放由FLUSH TABLES ... FOR EXPORT获取的锁mysql> USE test; mysql> UNLOCK TABLES;在目标实例上,导入分区表的表空间
mysql> USE test; mysql> ALTER TABLE t1 IMPORT TABLESPACE;
此示例演示如何导入单个表分区,其中每个分区驻留在每个表表空间文件中。
在以下示例中,将导入一个四分区表的两个分区(p2 和 p3)。
在目标实例上,创建一个与您要从其导入分区的分区表具有相同定义的分区表。(您可以使用
SHOW CREATE TABLE语法获取表定义。)如果表定义不匹配,则在您尝试导入操作时将报告架构不匹配错误。mysql> USE test; mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 4;在
/目录中,每个四个分区都有一个表空间datadir/test.ibd文件。mysql> \! ls /path/to/datadir/test/ t1#p#p0.ibd t1#p#p1.ibd t1#p#p2.ibd t1#p#p3.ibd在目标实例上,丢弃您要从源实例导入的分区。(在导入分区之前,您必须从接收的分区表中丢弃相应的分区。)
mysql> ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;要丢弃的两个分区的表空间
.ibd文件将从目标实例上的/目录中删除,留下以下文件datadir/testmysql> \! ls /path/to/datadir/test/ t1#p#p0.ibd t1#p#p1.ibd注意当在子分区表上运行
ALTER TABLE ... DISCARD PARTITION ... TABLESPACE时,允许使用分区和子分区表名。当指定分区名时,该分区的子分区将包含在操作中。在源实例上,运行
FLUSH TABLES ... FOR EXPORT使分区表静止。当表处于静止状态时,仅允许对该表进行只读事务。mysql> USE test; mysql> FLUSH TABLES t1 FOR EXPORT;FLUSH TABLES ... FOR EXPORT确保对命名表的更改被刷新到磁盘,以便在实例运行时可以制作二进制表副本。当运行FLUSH TABLES ... FOR EXPORT时,InnoDB会为表的每个表空间文件在表的架构目录中生成.cfg元数据文件。mysql> \! ls /path/to/datadir/test/ t1#p#p0.ibd t1#p#p1.ibd t1#p#p2.ibd t1#p#p3.ibd t1#p#p0.cfg t1#p#p1.cfg t1#p#p2.cfg t1#p#p3.cfg这些
.cfg文件包含在导入操作期间用于架构验证的元数据。FLUSH TABLES ... FOR EXPORT只能对表运行,不能对单个表分区运行。将分区
p2和分区p3的.ibd和.cfg文件从源实例架构目录复制到目标实例架构目录。$> scp t1#p#p2.ibd t1#p#p2.cfg t1#p#p3.ibd t1#p#p3.cfg destination-server:/path/to/datadir/test必须在释放共享锁之前复制
.ibd和.cfg文件,如下一步骤所述。注意如果您要从加密的表空间导入分区,
InnoDB除了生成.cfg元数据文件之外,还会生成一个.cfp文件。该.cfp文件必须与.cfg文件一起复制到目标实例。该.cfp文件包含一个传输密钥和一个加密的表空间密钥。在导入时,InnoDB使用传输密钥来解密表空间密钥。有关相关信息,请参阅 第 17.13 节“InnoDB 数据静止加密”。在源实例上,使用
UNLOCK TABLES释放由FLUSH TABLES ... FOR EXPORT获取的锁mysql> USE test; mysql> UNLOCK TABLES;在目标实例上,导入表分区
p2和p3mysql> USE test; mysql> ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;注意当在子分区表上运行
ALTER TABLE ... IMPORT PARTITION ... TABLESPACE时,允许使用分区和子分区表名。当指定分区名时,该分区的子分区将包含在操作中。
仅支持 可移植表空间 特性针对驻留在每个表表空间中的表。它不支持驻留在系统表空间或通用表空间中的表。共享表空间中的表无法静止。
FLUSH TABLES ... FOR EXPORT不支持具有FULLTEXT索引的表,因为无法刷新全文搜索辅助表。在导入具有FULLTEXT索引的表后,运行OPTIMIZE TABLE来重建FULLTEXT索引。或者,在导出操作之前删除FULLTEXT索引,并在目标实例上导入表后重新创建索引。由于
.cfg元数据文件的限制,在导入分区表时,不会报告分区类型或分区定义差异的架构不匹配。将报告列差异。
除了包含立即添加或删除的列的表之外,
ALTER TABLE ... IMPORT TABLESPACE不需要.cfg元数据文件来导入表。但是,在没有.cfg文件的情况下导入时,不会执行元数据检查,并将发出类似于以下内容的警告Message: InnoDB: IO Read error: (2, No such file or directory) Error opening '.\ test\t.cfg', will attempt to import without schema verification 1 row in set (0.00 sec)仅在没有预期架构不匹配并且表不包含任何立即添加或删除的列的情况下,才应考虑在没有
.cfg元数据文件的情况下导入表。在崩溃恢复场景中(其中元数据不可访问),在没有.cfg文件的情况下导入的能力可能很有用。尝试使用
ALGORITHM=INSTANT添加或删除了列的表,但在没有.cfg文件的情况下导入,可能会导致未定义的行为。在 Windows 上,
InnoDB在内部以小写形式存储数据库、表空间和表名。为了避免在区分大小写的操作系统(如 Linux 和 Unix)上出现导入问题,请使用小写名称创建所有数据库、表空间和表。确保以小写形式创建名称的一种便捷方法是在初始化服务器之前将lower_case_table_names设置为 1。(禁止使用与初始化服务器时使用的设置不同的lower_case_table_names设置启动服务器。)[mysqld] lower_case_table_names=1在对子分区表运行
ALTER TABLE ... DISCARD PARTITION ... TABLESPACE和ALTER TABLE ... IMPORT PARTITION ... TABLESPACE时,允许使用分区和子分区表名。指定分区名称时,该分区的子分区将包含在操作中。
以下信息描述了在表导入过程中写入错误日志的内部机制和消息。
在目标实例上运行 ALTER TABLE ... DISCARD TABLESPACE 时
表以 X 模式锁定。
表空间与表分离。
在源实例上运行 FLUSH TABLES ... FOR EXPORT 时
要刷新以供导出的表以共享模式锁定。
清除协调器线程停止。
脏页同步到磁盘。
表元数据写入二进制
.cfg文件。
此操作的预期错误日志消息
[Note] InnoDB: Sync to disk of '"test"."t1"' started.
[Note] InnoDB: Stopping purge
[Note] InnoDB: Writing table metadata to './test/t1.cfg'
[Note] InnoDB: Table '"test"."t1"' flushed to disk在源实例上运行 UNLOCK TABLES 时
删除二进制
.cfg文件。释放对要导入的表或表的共享锁,并重新启动清除协调器线程。
此操作的预期错误日志消息
[Note] InnoDB: Deleting the meta-data file './test/t1.cfg'
[Note] InnoDB: Resuming purge在目标实例上运行 ALTER TABLE ... IMPORT TABLESPACE 时,导入算法对每个要导入的表空间执行以下操作
检查每个表空间页面的损坏情况。
更新每个页面的空间 ID 和日志序列号 (LSN)。
验证标志并更新标头页面的 LSN。
更新 B 树页。
将页面状态设置为脏,以便将其写入磁盘。
此操作的预期错误日志消息
[Note] InnoDB: Importing tablespace for table 'test/t1' that was exported
from host 'host_name'
[Note] InnoDB: Phase I - Update all pages
[Note] InnoDB: Sync to disk
[Note] InnoDB: Sync to disk - done!
[Note] InnoDB: Phase III - Flush changes to disk
[Note] InnoDB: Phase IV - Flush complete
您还可能收到关于丢弃表空间的警告(如果您丢弃了目标表的表空间)以及一条消息,指出由于缺少 .ibd 文件而无法计算统计信息。
[Warning] InnoDB: Table "test"."t1" tablespace is set as discarded.
7f34d9a37700 InnoDB: cannot calculate statistics for table
"test"."t1" because the .ibd file is missing. For help, please refer to
https://dev.mysqld.com.cn/doc/refman/en/innodb-troubleshooting.html