14.6.1.3 导入 InnoDBtable

本节介绍如何使用“可传输 table 空间”功能导入 table,该功能允许导入 table,分区 table 或每个 table 文件 table 空间中的单个 table 分区。您可能要导入 table 的原因有很多:

  • 在非生产 MySQL 服务器实例上运行报告,以避免在生产服务器上增加额外的负载。

  • 将数据复制到新的副本服务器。

  • 从备份的 table 空间文件中还原 table。

  • 与导入转储文件相比,移动数据是一种更快的方法,这需要重新插入数据和重建索引。

  • 使用适合您的存储要求的存储介质将数据移动到服务器。例如,您可以将忙碌的 table 移至 SSD 设备,或将大 table 移至高容量 HDD 设备。

本节以下主题下介绍了“可移动 table 空间”功能:

Prerequisites
  • 必须启用innodb_file_per_table变量,默认情况下为。

  • table 空间的页面大小必须与目标 MySQL 服务器实例的页面大小匹配。 InnoDB页面大小由innodb_page_size变量定义,该变量是在初始化 MySQL 服务器实例时配置的。

  • 如果 table 具有外键关系,则必须在执行DISCARD TABLESPACE之前禁用foreign_key_checks。另外,您应在同一逻辑时间点导出所有与外键相关的 table,因为更改 table...导入 table 空间不会对导入的数据施加外键约束。为此,请停止更新相关 table,提交所有事务,获取 table 上的共享锁,然后执行导出操作。

  • 从另一个 MySQL 服务器实例导入 table 时,两个 MySQL 服务器实例都必须具有通用状态(GA),并且必须具有相同的版本。否则,必须在将 table 导入到的同一 MySQL 服务器实例上创建 table。

  • 如果 table 是通过在CREATE TABLE语句中指定DATA DIRECTORY子句在外部目录中创建的,则在目标实例上替换的 table 必须使用相同的DATA DIRECTORY子句定义。如果子句不匹配,则报告架构不匹配错误。若要确定源 table 是否使用DATA DIRECTORY子句定义,请使用显示创建 table查看 table 定义。有关使用DATA DIRECTORY子句的信息,请参见第 14.6.1.2 节“在外部创建 table”

  • 如果未在 table 定义中明确定义ROW_FORMAT选项或使用了ROW_FORMAT=DEFAULT,则innodb_default_row_format设置在源实例和目标实例上必须相同。否则,当您尝试导入操作时,将报告架构不匹配错误。使用显示创建 table检查 table 定义。使用SHOW VARIABLES检查innodb_default_row_format设置。有关相关信息,请参见定义 table 格的行格式

Importing Tables

本示例演示如何导入驻留在每个 table 文件 table 空间中的常规非分区 table。

  • 在目标实例上,创建一个与您要导入的 table 具有相同定义的 table。 (您可以使用显示创建 table语法获取 table 定义。)如果 table 定义不匹配,则在尝试导入操作时将报告架构不匹配错误。
mysql> USE test;
mysql> CREATE TABLE t1 (c1 INT) ENGINE=INNODB;
  • 在目标实例上,丢弃刚创建的 table 的 table 空间。 (在导入之前,必须丢弃接收 table 的 table 空间.)
mysql> ALTER TABLE t1 DISCARD TABLESPACE;
  • 在源实例上,运行冲洗 table...Export来静默要导入的 table。停顿 table 时,table 上仅允许只读事务。
mysql> USE test;
mysql> FLUSH TABLES t1 FOR EXPORT;

冲洗 table...Export确保已将对命名 table 的更改刷新到磁盘,以便可以在服务器运行时进行二进制 table 复制。运行冲洗 table...Export时,InnoDB在 table 的架构目录中生成.cfg元数据文件。 .cfg文件包含在导入操作期间用于架构验证的元数据。

  • .ibd文件和.cfg元数据文件从源实例复制到目标实例。例如:
shell> scp /path/to/datadir/test/t1.{ibd,cfg} destination-server:/path/to/datadir/test

释放共享锁之前,必须先复制.ibd文件和.cfg文件,如下一步所述。

Note

如果要从加密的 table 空间导入 table,则InnoDB除了会生成.cfg元数据文件之外,还会生成.cfp文件。 .cfp文件必须与.cfg文件一起复制到目标实例。 .cfp文件包含一个传输密钥和一个加密的 table 空间密钥。导入时,InnoDB使用传输密钥解密 table 空间密钥。有关相关信息,请参见第 14.14 节“ InnoDB 静态数据加密”

mysql> USE test;
mysql> UNLOCK TABLES;
  • 在目标实例上,导入 table 空间:
mysql> USE test;
mysql> ALTER TABLE t1 IMPORT TABLESPACE;
导入分区 table

本示例演示了如何导入分区 table,其中每个 table 分区都位于每个 table 文件 table 空间中。

  • 在目标实例上,创建具有与要导入的分区 table 相同定义的分区 table。 (您可以使用显示创建 table语法获取 table 定义。)如果 table 定义不匹配,则在尝试导入操作时将报告架构不匹配错误。
mysql> USE test;
mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 3;

/datadir/test目录中,三个分区中的每个分区都有一个 table 空间.ibd文件。

mysql> \! ls /path/to/datadir/test/
db.opt  t1.frm  t1#P#p0.ibd  t1#P#p1.ibd  t1#P#p2.ibd
  • 在目标实例上,丢弃分区 table 的 table 空间。 (在导入操作之前,必须丢弃接收 table 的 table 空间.)
mysql> ALTER TABLE t1 DISCARD TABLESPACE;

分区 table 的三个 table 空间.ibd文件从/datadir/test目录中丢弃,剩下以下文件:

mysql> \! ls /path/to/datadir/test/
db.opt  t1.frm
  • 在源实例上,运行冲洗 table...Export来静默要导入的分区 table。停顿 table 时,table 上仅允许只读事务。
mysql> USE test;
mysql> FLUSH TABLES t1 FOR EXPORT;

冲洗 table...Export确保将对命名 table 的更改刷新到磁盘,以便可以在服务器运行时进行二进制 table 复制。运行冲洗 table...Export时,InnoDB在 table 的架构目录中为每个 table 的 table 空间文件生成.cfg元数据文件。

mysql> \! ls /path/to/datadir/test/
db.opt t1#P#p0.ibd  t1#P#p1.ibd  t1#P#p2.ibd
t1.frm  t1#P#p0.cfg  t1#P#p1.cfg  t1#P#p2.cfg

.cfg文件包含用于在导入 table 空间时用于架构验证的元数据。 冲洗 table...Export只能在 table 上运行,不能在单个 table 分区上运行。

  • .ibd.cfg文件从源实例架构目录复制到目标实例架构目录。例如:
shell>scp /path/to/datadir/test/t1*.{ibd,cfg} destination-server:/path/to/datadir/test

释放共享锁之前,必须先复制.ibd.cfg文件,如下一步所述。

Note

如果要从加密的 table 空间导入 table,则InnoDB除了会生成.cfg元数据文件外,还会生成.cfp文件。 .cfp文件必须与.cfg文件一起复制到目标实例。 .cfp文件包含传输密钥和加密的 table 空间密钥。导入时,InnoDB使用传输密钥解密 table 空间密钥。有关相关信息,请参见第 14.14 节“ InnoDB 静态数据加密”

mysql> USE test;
mysql> UNLOCK TABLES;
  • 在目标实例上,导入分区 table 的 table 空间:
mysql> USE test;
mysql> ALTER TABLE t1 IMPORT TABLESPACE;
导入 table 分区

本示例演示了如何导入单个 table 分区,其中每个分区都位于每个 table 文件 table 空间文件中。

在以下示例中,导入了四分区 table 的两个分区(p2p3)。

  • 在目标实例上,创建一个定义与您要从中导入分区的分区 table 相同的分区 table。 (您可以使用显示创建 table语法获取 table 定义。)如果 table 定义不匹配,则在尝试导入操作时将报告架构不匹配错误。
mysql> USE test;
mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 4;

/datadir/test目录中,四个分区中的每个分区都有一个 table 空间.ibd文件。

mysql> \! ls /path/to/datadir/test/
db.opt  t1.frm  t1#P#p0.ibd  t1#P#p1.ibd  t1#P#p2.ibd t1#P#p3.ibd
  • 在目标实例上,丢弃要从源实例导入的分区。 (在导入分区之前,必须从接收到的分区 table 中丢弃相应的分区.)
mysql> ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;

从目标实例上的/datadir/test目录中删除了两个废弃分区的 table 空间.ibd文件,保留了以下文件:

mysql> \! ls /path/to/datadir/test/
db.opt  t1.frm  t1#P#p0.ibd  t1#P#p1.ibd

Note

在子分区 table 上运行ALTER TABLE ...磁盘分区... TABLESPACE时,分区和子分区 table 名称均被允许。指定分区名称后,该分区的子分区将包含在操作中。

  • 在源实例上,运行冲洗 table...Export来静默分区 table。停顿 table 时,table 上仅允许只读事务。
mysql> USE test;
mysql> FLUSH TABLES t1 FOR EXPORT;

冲洗 table...Export确保将对命名 table 的更改刷新到磁盘上,以便可以在实例运行时进行二进制 table 复制。运行冲洗 table...Export时,InnoDB为 table 的架构目录中的每个 table 的 table 空间文件生成.cfg元数据文件。

mysql> \! ls /path/to/datadir/test/
db.opt  t1#P#p0.ibd  t1#P#p1.ibd  t1#P#p2.ibd t1#P#p3.ibd
t1.frm  t1#P#p0.cfg  t1#P#p1.cfg  t1#P#p2.cfg t1#P#p3.cfg

.cfg文件包含在导入操作期间用于架构验证的元数据。 冲洗 table...Export只能在 table 上运行,不能在单个 table 分区上运行。

  • 将分区p2和分区p3.ibd.cfg文件从源实例架构目录复制到目标实例架构目录。
shell> 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文件,如下一步所述。

Note

如果要从加密的 table 空间导入分区,则InnoDB除了会生成.cfg元数据文件之外,还会生成.cfp文件。 .cfp文件必须与.cfg文件一起复制到目标实例。 .cfp文件包含传输密钥和加密的 table 空间密钥。导入时,InnoDB使用传输密钥解密 table 空间密钥。有关相关信息,请参见第 14.14 节“ InnoDB 静态数据加密”

mysql> USE test;
mysql> UNLOCK TABLES;
  • 在目标实例上,导入 table 分区p2p3
mysql> USE test;
mysql> ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;

Note

在子分区 table 上运行更改 table...导入分区...table 空间时,分区和子分区 table 名称均被允许。指定分区名称后,该分区的子分区将包含在操作中。

Limitations
  • 仅位于每个 table 文件 table 空间中的 table 才支持“可移动 table 空间”功能。驻留在系统 table 空间或常规 table 空间中的 table 不支持此功能。共享 table 空间中的 table 不能被静默。

  • 索引为FULLTEXT的 table 不支持冲洗 table...Export,因为无法刷新全文搜索辅助 table。导入具有FULLTEXT索引的 table 后,运行OPTIMIZE TABLE重建FULLTEXT索引。或者,在导出操作之前删除FULLTEXT索引,并在目标实例上导入 table 后重新创建索引。

  • 由于.cfg元数据文件的限制,在导入分区 table 时,不会针对分区类型或分区定义差异报告架构不匹配。报告列差异。

Usage Notes
  • 更改 table...导入 table 空间不需要.cfg元数据文件即可导入 table。但是,在没有.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元数据文件的 table。没有.cfg文件的导入功能在无法访问元数据的崩溃恢复方案中很有用。

  • 在 Windows 上,InnoDB在内部以小写形式存储数据库,table 空间和 table 名。为了避免在区分大小写的 os(例如 Linux 和 Unix)上出现导入问题,请使用小写名称创建所有数据库,table 空间和 table。一种方便的方法是在创建数据库,table 空间或 table 之前,将lower_case_table_names=1添加到my.cnfmy.ini文件的[mysqld]部分中:
[mysqld]
lower_case_table_names=1
Internals

以下信息描述了在 table 导入过程中写入错误日志的内部信息和消息。

在目标实例上运行ALTER TABLE ... DISCARD TABLESPACE时:

  • 该 table 被锁定为 X 模式。

  • table 空间与 table 分离。

在源实例上运行冲洗 table...Export时:

  • 刷新要导出的 table 已锁定为共享模式。

  • 清除协调器线程已停止。

  • 脏页已同步到磁盘。

  • table 元数据将写入二进制.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文件被删除。

  • 释放要导入的一个或多个 table 上的共享锁,并重新启动清除协调器线程。

此操作的预期错误日志消息:

[Note] InnoDB: Deleting the meta-data file './test/t1.cfg'
[Note] InnoDB: Resuming purge

在目标实例上运行更改 table...导入 table 空间时,导入算法将对要导入的每个 table 空间执行以下操作:

  • 检查每个 table 空间页是否损坏。

  • 每页上的空间 ID 和日志序列号(LSN)都会更新。

  • 验证标志,并更新标题页的 LSN。

  • Btree 页面已更新。

  • 页面状态设置为脏,以便将其写入磁盘。

此操作的预期错误日志消息:

[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

Note

您还可能会收到一条警告,告知您 table 空间将被丢弃(如果您丢弃了目标 table 的 table 空间),并且一条消息指出由于缺少.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
http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html