error 1812 表明表空间文件(.ibd)与数据字典记录“人户分离”,即磁盘存在.ibd但mysql无法识别,常见于误删、异常关机或手动移动文件;此时应优先验证.ibd完整性,再通过discard/import tablespace重建映射,而非直接删表或使用alter tablespace。

孤立表空间文件的典型表现:ERROR 1812 和 "Tablespace is missing for table"
当你看到 ERROR 1812 (HY000): Tablespace is missing for table `db`.`tbl`,基本可以判定是孤立 .ibd 文件——即磁盘上存在该表的 .ibd 文件,但 MySQL 数据字典里没有对应记录,或记录已损坏。这不是数据丢失,而是“连接断了”。常见于非正常关机、手动移动文件、误删 .frm(MySQL 5.7)或元数据被清空(MySQL 8.0+)。别急着删文件,先确认它是否真的完整:ls -lh /var/lib/mysql/db/tbl.ibd 看大小是否合理(空表通常几 KB,有数据则至少几十 KB),再用 file tbl.ibd 检查是否为 InnoDB 数据文件(输出含 InnoDB data file)。
DISCARD/IMPORT TABLESPACE 是唯一安全的重建路径
对孤立 .ibd 文件,ALTER TABLE ... DISCARD TABLESPACE + IMPORT TABLESPACE 是唯一能绕过数据字典校验、强制重关联的原生方案。前提是表必须启用 innodb_file_per_table=ON(MySQL 5.6+ 默认开启),且 .ibd 文件未被截断或覆盖。
- 执行前确保表结构仍存在:
SHOW CREATE TABLE db.tbl\G能成功返回;若失败,需先从备份或.frm(5.7)/ 数据字典(8.0)恢复建表语句 -
DISCARD会删除当前内存中对该表空间的引用,并清空数据字典里的空间 ID 映射,但不碰磁盘上的.ibd文件 -
IMPORT要求.ibd文件权限为mysql:mysql,且文件大小不能变——哪怕只多 1 字节,InnoDB 都会拒绝导入并报Tablespace checksum mismatch - 导入后立即执行
SELECT COUNT(*) FROM db.tbl验证可读性;若卡住或报Corrupted page found,说明.ibd本身物理损坏,此路不通
innodb_force_recovery=6 是读取结构的临时跳板
当 .frm 丢失(MySQL 5.7)或建表语句不可考时,你得靠 innodb_force_recovery 让 MySQL 启动并读出结构定义。但注意:innodb_force_recovery=6 不是修复命令,它只是让 InnoDB 忽略所有校验强行加载——此时你只能 SELECT 或 SHOW CREATE TABLE,任何写操作(包括 ALTER)都会被拒绝。
- 必须在
my.cnf中设置并重启 mysqld:innodb_force_recovery = 6;服务起来后立刻导出结构:mysqldump --no-data db tbl > tbl.sql - 导出完成后**必须注释掉该配置并重启**,否则服务永远只读,且后续崩溃风险极高
- 级别 1–4 有时就够用;盲目设为 6 可能导致
SHOW CREATE TABLE返回空或错误结构(比如列顺序错乱),建议逐级尝试 - MySQL 8.0+ 无
.frm文件,结构全存数据字典,若字典损坏,innodb_force_recovery也救不回结构,只能靠备份或 binlog 回滚
别碰 ALTER TABLESPACE,它对孤立 .ibd 文件无效
ALTER TABLESPACE 只管理通用表空间(general tablespace)或 undo 表空间,和单个 .ibd 文件完全无关。试图对普通表执行 ALTER TABLESPACE ts_name REBUILD 会直接报错 ERROR 1064。网上有些教程混淆了概念,把“重建表空间”等同于“修复孤立 .ibd”,这是错的。真正要做的,永远是重建 .ibd 与数据字典之间的映射关系,而不是修改表空间本身。
最易被忽略的点是:IMPORT TABLESPACE 前,必须确保 .ibd 文件的 Space ID 与表当前期望的 ID 一致。MySQL 5.7 之后默认关闭 innodb_file_per_table 时,Space ID 由系统分配且不可控;而独立表空间下,ID 写死在 .ibd 文件头里——所以文件绝不能用文本编辑器打开、不能用 cp 复制后直接替换(部分 cp 实现会重写 inode 时间戳但不动内容,可接受;但 rsync 或 GUI 拷贝可能触发重写,风险高)。稳妥做法是用 dd if=orig.ibd of=new.ibd bs=1M 块拷贝。











