本节介绍如何使用可 传输表空间功能导入表,该功能允许导入驻留在 file-per-table 表空间中的表。您可能想要导入表的原因有很多:
在非生产 MySQL 服务器实例上运行报告以避免对生产服务器施加额外负载。
将数据复制到新的副本服务器。
从备份的表空间文件恢复表。
作为一种比导入转储文件更快的移动数据方式,后者需要重新插入数据并重建索引。
将数据移动到具有更适合您的存储要求的存储介质的服务器。例如,您可以将繁忙的表移动到 SSD 设备,或将大表移动到大容量 HDD 设备。
可传输表空间功能在本节的以下主题下进行了描述:
该
innodb_file_per_table
变量必须启用,默认情况下是启用的。表空间的页面大小必须与目标 MySQL 服务器实例的页面大小相匹配。
InnoDB
页面大小由innodb_page_size
变量定义,该变量在初始化 MySQL 服务器实例时配置。如果表有外键关系,
foreign_key_checks
执行前必须禁用DISCARD TABLESPACE
。此外,您应该在同一逻辑时间点导出所有与外键相关的表,因为该ALTER TABLE ... IMPORT TABLESPACE
功能不会对导入的数据强制执行外键约束。为此,停止更新相关表,提交所有事务,获取表上的共享锁,并执行导出操作。从另一个 MySQL 服务器实例导入表时,两个 MySQL 服务器实例必须具有一般可用性 (GA) 状态并且必须是相同的版本。否则,必须在导入它的同一个 MySQL 服务器实例上创建该表。
如果表是通过在语句中指定
DATA DIRECTORY
子句在数据目录之外创建的CREATE TABLE
,则您在目标实例上替换的表必须使用相同的DATA DIRECTORY
子句定义。如果子句不匹配,则会报告模式不匹配错误。要确定源表是否使用DATA DIRECTORY
子句定义,请使用SHOW CREATE TABLE
查看表定义。有关使用该DATA DIRECTORY
子句的信息,请参阅 第 14.6.1.2 节,“在外部创建表”。
此示例演示如何导入驻留在 file-per-table 表空间中的表。
在目标实例上,创建一个与您要导入的表具有相同定义的表。(您可以使用
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
文件包含在导入操作期间用于模式验证的元数据。将
.ibd
文件和.cfg
元数据文件从源实例复制到目标实例。例如:$> scp /path/to/datadir/test/t1.{ibd,cfg} destination-server:/path/to/datadir/test
.ibd
文件和.cfg
文件必须在释放共享锁之前复制,如下一步所述 。在源实例上,用于 释放语句
UNLOCK TABLES
获取的锁 :FLUSH TABLES ... FOR EXPORT
mysql> USE test; mysql> UNLOCK TABLES;
在目标实例上,导入表空间:
mysql> USE test; mysql> ALTER TABLE t1 IMPORT TABLESPACE;
Transportable Tablespaces功能仅支持驻留在 file-per-table 表空间中的表 。驻留在系统表空间中的表不支持它。系统表空间中的表不能被停顿。
DISCARD TABLESPACE
不支持分区表,也就是说不支持导入分区表。如果您ALTER TABLE ... DISCARD TABLESPACE
在分区表上运行,将返回以下错误:ERROR 1031 (HY000): Table storage engine for 'part' doesn't have this option。FLUSH TABLES ... FOR EXPORT
具有FULLTEXT
索引的表不支持,因为无法刷新全文搜索辅助表。导入带FULLTEXT
索引的表后,运行OPTIMIZE TABLE
重建FULLTEXT
索引。或者,在导出操作之前删除FULLTEXT
索引,并在目标实例上导入表后重新创建索引。
.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
可能很有用。在 Windows 上,
InnoDB
以小写形式在内部存储数据库、表空间和表名称。为避免在 Linux 和 Unix 等区分大小写的操作系统上出现导入问题,请使用小写名称创建所有数据库、表空间和表。完成此操作的一种简便方法是 在创建数据库、表空间或表之前 添加lower_case_table_names=1
到or文件的[mysqld]
部分 :my.cnf
my.ini
[mysqld] lower_case_table_names=1
以下信息描述了在表导入过程中写入错误日志的内部信息和消息。
何时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。
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
.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.6/en/innodb-troubleshooting.html