能成功,但必须满足硬性前提:源库需在同会话执行FLUSH TABLES...FOR EXPORT后立即复制.cfg和.ibd文件并立刻UNLOCK TABLES;目标表结构须字节级一致且为空;IMPORT前需确认版本、页大小、字符集等完全匹配。

能,但必须满足硬性前提,否则 ALTER TABLE ... IMPORT TABLESPACE 会直接报错或崩溃,不是“快不快”的问题,而是“能不能成功”的问题。
源库执行 FLUSH TABLES table_name FOR EXPORT 时为什么必须立刻复制文件?
这步操作会加全局读锁、刷脏页、重置 undo log,并生成 table_name.cfg(含校验元数据)和冻结的 table_name.ibd。但这个“冻结状态”只在当前会话保持——一旦会话断开或执行 UNLOCK TABLES 之前手动退出,.cfg 就失效,.ibd 也可能被后续写入污染。
- 必须在同个 MySQL 客户端会话里执行
FLUSH ... FOR EXPORT,然后立刻用scp或rsync拷贝两个文件,中间不能有延迟 - 拷贝完成后,**必须立即执行
UNLOCK TABLES**,否则所有 DDL/DML 会被卡住,show processlist里会出现一堆Waiting for table flush -
.cfg文件不可手动生成或修改,它是二进制校验文件,缺失或损坏会导致Tablespace mismatch
目标库执行 ALTER TABLE ... DISCARD TABLESPACE 前要确认什么?
这一步删掉目标表现有的 .ibd,为挂载新文件腾位置。但前提是:目标表结构必须和源表**字节级一致**,连隐式属性都不能差。
- 用
SHOW CREATE TABLE table_name在两边对比,重点看:ENGINE=InnoDB、CHARSET、COLLATE、ROW_FORMAT、STATS_PERSISTENT、是否启用加密(ENCRYPTION='Y') - 目标表不能有数据,也不能是临时表;如果原表有外键,导入前需设
SET foreign_key_checks = 0 - 执行
DISCARD后,ls /var/lib/mysql/db_name/应只剩table_name.frm(或.sdi,MySQL 8.0+),.ibd必须消失 - 若提示
Operation not permitted,八成是文件属主没改对:拷贝后必须chown mysql:mysql table_name.{ibd,cfg}
IMPORT TABLESPACE 失败最常见的三个原因
报错信息往往很短,但背后条件严苛。最常踩的坑就这三个:
-
Tablespace mismatch:源/目标 MySQL 主版本不一致(比如 8.0.30 → 8.0.33 可能行,但 5.7 → 8.0 绝对不行),或innodb_page_size不同(默认 16KB,改过就不能互迁) -
Can't find record in 'table_name':目标表结构和源表不一致,特别是AUTO_INCREMENT值、隐藏列、全文索引、GIS 类型、虚拟列——这些特性不支持 TTS,建表时就得避开 -
Failed to open the tablespace:文件权限不对(mysql用户无读权限)、.ibd被截断、或目标库开启了innodb_force_recovery(必须关掉)
真正耗时的从来不是拷贝文件,而是验证一致性:版本、页大小、字符集、行格式、表结构细节。漏掉任意一项,前面所有操作都白做。


















