这不是文件丢失,是元数据链接断裂:物理.ibd文件完好,但innodb数据字典中表空间id映射丢失;须停mysql、校验权限、先建空表再discard+import,且依赖innodb_file_per_table=on和字符集一致。

直接回答:这不是文件丢失,是元数据链接断裂
“Missing .ibd file”错误根本不是磁盘上真没了文件——只要你的.ibd还在/www/server/data/your_db/目录下,就说明物理数据完好。真正的问题是InnoDB的数据字典(存在ibdata1里)已经找不到这张表对应的表空间ID(Space ID)映射了。MySQL启动时查不到记录,就报这个错,但其实数据全在。
必须先停服务再操作,否则权限和锁会卡死流程
很多恢复失败,是因为边连着MySQL边拷文件、改权限。MySQL 5.7对.frm和.ibd的属主、权限、时间戳极其敏感,运行中强行覆盖会导致文件被缓存或锁定,后续ALTER TABLE ... IMPORT TABLESPACE必报错。
- 在宝塔面板里点“停止”MySQL,别只
kill -9进程 - 确认进程已退出:
ps aux | grep mysqld应无残留 - 检查文件权限:
ls -l /www/server/data/your_db/your_table.*,确保两个文件都属mysql:mysql - 如果权限不对,立刻执行:
chown mysql:mysql /www/server/data/your_db/your_table.frm /www/server/data/your_db/your_table.ibd
恢复分两步:先重建结构壳,再嫁接真实数据
不能直接把.ibd扔进去就完事。MySQL需要一个“空壳表”来承载它,而这个壳必须和原.ibd的Space ID一致——但你没法手动改ID,所以得靠“discard + import”机制让MySQL自己对齐。
- 用原库名创建数据库:
CREATE DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; - 进库后建同名空表(字段数可暂不匹配,引擎必须
ENGINE=InnoDB):CREATE TABLE your_table (id INT) ENGINE=InnoDB; - 停MySQL,把备份来的
.frm覆盖到/www/server/data/your_db/your_table.frm,再chown mysql:mysql - 启动MySQL,执行
SHOW CREATE TABLE your_table,根据输出补全字段定义(注意字符集、NOT NULL、自增等细节) - 删掉旧表,用完整结构重建一遍;然后执行:
ALTER TABLE your_table DISCARD TABLESPACE; - 把原始
.ibd文件拷进来覆盖,再chown mysql:mysql - 最后执行:
ALTER TABLE your_table IMPORT TABLESPACE;
最容易被忽略的致命细节:innodb_file_per_table 和字符集
innodb_file_per_table=ON是前提,MySQL 5.7默认开启,但如果被手动关过,.ibd文件就不存在,整个流程无效。另外,.frm里记录的字符集如果和建表语句不一致(比如utf8 vs utf8mb4),IMPORT会静默失败,日志里只写“Failed to open table”,必须比对SHOW CREATE TABLE输出和mysqld错误日志里的警告行。











