必须严格按四步执行:源库FLUSH TABLES FOR EXPORT锁定并生成.ibd与.cfg文件、拷贝两个文件、目标库先DISCARD TABLESPACE再IMPORT TABLESPACE;缺一不可,因MySQL 8.0+数据字典与表空间ID强绑定,且.cfg含tablespace_id和校验信息,缺失或不匹配均导致“Tablespace is missing”错误。

能迁,但必须严格按四步走:源库 FLUSH + 拷 .ibd/.cfg + 目标库 DISCARD + IMPORT。跳一步或漏一个文件,必然失败。
为什么直接 cp .ibd 会报 “Tablespace is missing for table”
MySQL 8.0+ 的数据字典(Data Dictionary)和 .ibd 文件是强绑定的:每个 .ibd 内嵌一个 tablespace_id,而目标库的字典里只认自己生成的 ID。直接复制过去,InnoDB 启动时发现 ID 不匹配,直接拒绝加载,报错类似:
Tablespace is missing for table 'db.t1' 或 InnoDB: Error: tablespace id in file ./db/t1.ibd is 123, but in data dictionary it is 456
.cfg 文件不是可选附件,它是 FLUSH TABLES FOR EXPORT 生成的“校验身份证”,含源库当时的 tablespace_id、页校验和、schema 指纹。没它,ALTER TABLE ... IMPORT TABLESPACE 必然失败。
FLUSH TABLES FOR EXPORT 后必须立刻做的三件事
这条命令冻结表状态、刷脏页、生成 .cfg,但不自动释放锁——你得在锁持有期间完成全部操作,否则 .ibd 和 .cfg 就可能不一致。
- 立即执行
cp /var/lib/mysql/db/t.{ibd,cfg} /backup/(顺序不重要,但两个文件必须都在锁内拷完) - 立刻执行
UNLOCK TABLES(注意不是FLUSH TABLES;后者会释放锁但不清除导出状态) - 检查 .cfg 是否非空:
stat /backup/t.cfg+head -c 20 /backup/t.cfg;空文件说明导出失败,常见于表正被ALTER或处于崩溃恢复中
目标库 IMPORT TABLESPACE 失败的三个高频原因
即使文件拷对了、结构看着一样,仍可能卡在导入环节。关键看错误日志里具体哪一行报错:
Incorrect key file for table 't'; try to repair it → 表结构不一致,比如源库建表用了 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8,目标库建表时漏了 KEY_BLOCK_SIZE 参数
Cannot continue operation, data file size does not match dictionary → .ibd 被截断或拷贝不完整,常见于 rsync 未加 --partial 或网络中断后没校验
Invalid or missing .cfg file → .cfg 过期(比如源表后续被 ALTER 过),或目标库没先执行 ALTER TABLE db.t1 DISCARD TABLESPACE 就放文件进去(MySQL 会忽略 .ibd,继续用空表结构)
容易被忽略的硬性前提
Transportable Tablespace 不是“能用就行”,而是有明确的物理约束:
源库和目标库的 innodb_page_size 必须完全一致(比如都是 16384);innodb_file_per_table 必须为 ON;字符集、排序规则、ROW_FORMAT、外键约束、字段顺序都得一模一样;分区表只支持 MySQL 8.0.23+ 的分区级迁移;全文索引必须先删,导入后再重建;有外键的表,主子表必须一起迁移且逻辑一致。


















