Ubuntu重启MySQL报错Table 'db.table' doesn't exist in engine如何解决
问题成因
该报错核心为InnoDB引擎内部存储的表元数据,与磁盘上的实际物理文件信息校验不匹配,由未完成的OPTIMIZE TABLE操作直接触发:
- InnoDB执行
OPTIMIZE TABLE时的逻辑为:创建临时ibd文件,将原表数据整理后写入临时文件,随后删除原ibd文件、重命名临时文件为正式文件名,同时更新共享表空间ibdata1中的表元信息。如果操作过程中出现磁盘空间不足、IO异常、进程被强制中断、提前重启服务等情况,会导致元数据更新流程中断,重启后就会出现元数据与物理文件不匹配的问题 - 另一种常见触发场景为ibd文件内部记录的表空间ID,与
ibdata1中存储的对应表的空间ID不一致,引擎校验不通过就会抛出表不存在的错误
解决方案
操作前必须先对MySQL数据目录做全量备份,避免操作失误导致数据永久丢失:
cp -rp /var/lib/mysql /var/lib/mysql_bak
方案一:表空间重绑定(适用90%以上场景)
- 登录MySQL,执行删除表操作,注意如果报错表不存在,可以先手动将对应库下的
table.frm、table.ibd移动到其他备份目录,再执行删除:
DROP TABLE db.table;
- 在对应库下创建和原表结构完全一致的空表,可通过
mysqlfrm --diagnostic /备份路径/table.frm命令解析原frm文件得到建表语句,执行创建操作 - 卸载新创建空表的表空间:
ALTER TABLE db.table DISCARD TABLESPACE;
- 将之前备份的原表ibd文件复制回对应数据库目录,修正权限:
cp /备份路径/table.ibd /var/lib/mysql/db/ chown mysql:mysql /var/lib/mysql/db/table.ibd chmod 660 /var/lib/mysql/db/table.ibd
- 导入原表的表空间:
ALTER TABLE db.table IMPORT TABLESPACE;
- 执行查询验证数据是否正常:
SELECT * FROM db.table LIMIT 1;
方案二:强制恢复模式导出重建(方案一失效时使用)
- 停止MySQL服务:
systemctl stop mysql
- 编辑MySQL配置文件
/etc/mysql/my.cnf,在[mysqld]节点下添加强制恢复参数(不要使用大于4的恢复级别,会造成数据不可逆损坏):
innodb_force_recovery = 3
- 启动MySQL服务,此时引擎为只读模式,导出全量数据:
mysqldump -u root -p --all-databases > all_data_bak.sql
- 停止MySQL服务,注释掉配置文件中的
innodb_force_recovery参数,删除原数据目录,重新初始化MySQL:
rm -rf /var/lib/mysql mkdir /var/lib/mysql mysqld --initialize-insecure --user=mysql chown -R mysql:mysql /var/lib/mysql
- 启动MySQL后导入备份数据即可:
mysql -u root -p < all_data_bak.sql
后续注意事项
- 执行
OPTIMIZE TABLE前需要确认磁盘剩余空间不小于目标表大小的2倍 - 避免在业务高峰执行
OPTIMIZE TABLE操作,操作完成确认无报错后再重启服务
内容的提问来源于stack exchange,提问作者xiheya2295
相关产品推荐
相关产品推荐

