直接拷贝.ibd文件报错“Tablespace is missing for table”是因为InnoDB不信任外部文件,必须通过FLUSH TABLES ... FOR EXPORT生成配套.cfg文件,并用IMPORT TABLESPACE显式导入,且要求源目标表结构、字符集、ROW_FORMAT等完全一致。
为什么直接拷贝 ibd 文件会报错 Tablespace is missing for table
因为 InnoDB 默认不信任外部导入的 .ibd 文件——它只认自己管理的表空间元数据。即使你把 table.ibd 和 table.frm(或 table.sdi)都拷过去了,MySQL 启动时发现数据字典里没有对应记录,就会拒绝加载,报这个错误。
可传输表空间(Transportable Tablespaces)就是为解决这个问题设计的:它要求你先“标记”表为可导出状态,生成一致的 .ibd 快照,并导出配套的元数据文件(.cfg),再在目标库中用 IMPORT TABLESPACE 命令显式告诉 InnoDB:“这张表的数据我带来了,请校验并接入字典”。
必须满足:源表和目标表结构完全一致(包括字符集、ROW_FORMAT、PAGE_COMPRESSED 等)
源表必须是独立表空间(
innodb_file_per_table=ON),且不能是分区表的子分区(MySQL 8.0.23+ 支持分区级传输).cfg文件不可手动生成或修改,必须由FLUSH TABLES ... FOR EXPORT产生
执行 FLUSH TABLES t FOR EXPORT 后要立刻做三件事
这条命令会让表进入只读状态,并冻结其元数据快照(用于生成 .cfg)。但它不会自动释放锁,也不代表你可以马上拷文件——稍有延迟就可能因其他事务写入导致 .cfg 和 .ibd 不一致。
立即用
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或网络中断后没校验)Failed to open the tablespace file ... because it is not a valid InnoDB data file→ MySQL 版本跨度过大(如从 5.7 导出,8.0.22 以下版本无法导入),或开启了innodb_checksum_algorithm=crc32但目标库是strict_crc32
修复方式不是重试,而是回退到源库重新 FLUSH ... FOR EXPORT,并确认目标库 CREATE TABLE 语句与 SHOW CREATE TABLE 输出完全一致(连注释都不能多)。
