文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  导入 InnoDB 表

17.6.1.3 导入 InnoDB 表

本节介绍如何使用可移植表空间功能导入表,该功能允许导入位于每个表一个文件表空间中的表、分区表或单个表分区。您可能需要导入表的原因有很多

  • 在非生产 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设置。有关相关信息,请参见定义表的行格式

导入表

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

  1. 在目标实例上,创建一个与您要导入的表具有相同定义的表。(您可以使用 SHOW CREATE TABLE 语法获取表定义。)如果表定义不匹配,则在您尝试导入操作时将报告架构不匹配错误。

    mysql> USE test;
    mysql> CREATE TABLE t1 (c1 INT) ENGINE=INNODB;
  2. 在目标实例上,丢弃刚创建的表的表空间。(在导入之前,您必须丢弃接收表的表空间。)

    mysql> ALTER TABLE t1 DISCARD TABLESPACE;
  3. 在源实例上,运行 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 文件将被删除,因为锁被释放。

  4. .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 数据静止加密”

  5. 在源实例上,使用 UNLOCK TABLES 释放由 FLUSH TABLES ... FOR EXPORT 语句获取的锁

    mysql> USE test;
    mysql> UNLOCK TABLES;

    UNLOCK TABLES 操作还会删除 .cfg 文件。

  6. 在目标实例上,导入表空间

    mysql> USE test;
    mysql> ALTER TABLE t1 IMPORT TABLESPACE;
导入分区表

此示例演示如何导入分区表,其中每个表分区驻留在每个表表空间中。

  1. 在目标实例上,创建一个与您要导入的分区表具有相同定义的分区表。(您可以使用 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
  2. 在目标实例上,丢弃分区表的表空间。(在导入操作之前,您必须丢弃接收表的表空间。)

    mysql> ALTER TABLE t1 DISCARD TABLESPACE;

    分区表的三个表空间 .ibd 文件将从 /datadir/test 目录中丢弃。

  3. 在源实例上,运行 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 只能对表运行,不能对单个表分区运行。

  4. .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 数据静止加密”

  5. 在源实例上,使用 UNLOCK TABLES 释放由 FLUSH TABLES ... FOR EXPORT 获取的锁

    mysql> USE test;
    mysql> UNLOCK TABLES;
  6. 在目标实例上,导入分区表的表空间

    mysql> USE test;
    mysql> ALTER TABLE t1 IMPORT TABLESPACE;
导入表分区

此示例演示如何导入单个表分区,其中每个分区驻留在每个表表空间文件中。

在以下示例中,将导入一个四分区表的两个分区(p2p3)。

  1. 在目标实例上,创建一个与您要从其导入分区的分区表具有相同定义的分区表。(您可以使用 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
  2. 在目标实例上,丢弃您要从源实例导入的分区。(在导入分区之前,您必须从接收的分区表中丢弃相应的分区。)

    mysql> ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;

    要丢弃的两个分区的表空间 .ibd 文件将从目标实例上的 /datadir/test 目录中删除,留下以下文件

    mysql> \! ls /path/to/datadir/test/
    t1#p#p0.ibd  t1#p#p1.ibd
    注意

    当在子分区表上运行 ALTER TABLE ... DISCARD PARTITION ... TABLESPACE 时,允许使用分区和子分区表名。当指定分区名时,该分区的子分区将包含在操作中。

  3. 在源实例上,运行 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 只能对表运行,不能对单个表分区运行。

  4. 将分区 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 数据静止加密”

  5. 在源实例上,使用 UNLOCK TABLES 释放由 FLUSH TABLES ... FOR EXPORT 获取的锁

    mysql> USE test;
    mysql> UNLOCK TABLES;
  6. 在目标实例上,导入表分区 p2p3

    mysql> 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 ... TABLESPACEALTER 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.mysqlserver.cn/doc/refman/en/innodb-troubleshooting.html