innodb_force_recovery 常无效,因 ibdata1 损坏导致数据字典或 undo 页无法解析,即使设至最高级 6 仍会启动失败;此时应优先备份、安全关机、再通过 discard/import 单表恢复。

别设 innodb_force_recovery 后直接 dump —— 大部分情况下它根本启不起来,或者启了也导不出数据。
为什么 innodb_force_recovery 常常无效
报错里出现 ibdata1 is corrupt 或 The log sequence number in ibdata1 does not match,说明 InnoDB 的系统表空间已无法自洽。此时 innodb_force_recovery 不是“修复开关”,而是让 MySQL 跳过某些崩溃恢复步骤强行加载——但前提是底层页结构还能被识别。一旦 ibdata1 的数据字典页、事务系统页或 undo 段头损坏,哪怕设到 6 级,mysqld 也会在初始化阶段直接 abort。
- 级别 1–2:可能跳过损坏索引记录,但若数据字典页(如
SYS_TABLES)损坏,连表名都读不出来 - 级别 3:禁用 undo 回滚,但若 ibdata1 中的 space_id 映射表已乱,后续
IMPORT TABLESPACE仍会失败 - 级别 4 及以上:InnoDB 主动禁用 insert buffer、purge thread,甚至拒绝 DML;
mysqldump执行SELECT时直接报错ERROR 2013 (HY000)
启动前必须做的三件事
盲目加参数重启只会延长宕机时间,还可能触发二次写损坏。
- 确认
datadir路径(宝塔里看「数据库 → 配置文件」,通常是/www/server/data),然后立刻执行:cp -r /www/server/data /www/server/data.bak_$(date +%s) - 检查
ps aux | grep mysqld,确保没残留进程;否则systemctl start mysqld会静默失败 - 编辑
/etc/my.cnf,在[mysqld]下只加这一行:innodb_fast_shutdown = 0,保存后运行systemctl start mysqld—— 这步是让 InnoDB 尝试安全刷脏页并重建日志,不是为了启动业务库,而是为后续操作创造可预测状态
设了 innodb_force_recovery 但 mysqldump 卡住怎么办
卡在某张表(比如 wordpress.wp_posts)不往下走,大概率是该表对应的 ibd 文件页校验失败,或其元数据在 ibdata1 中已不可解析。
- 不要反复尝试更高级别:每升一级都增加数据不一致风险,且 5/6 级下
mysqldump --single-transaction会失效,改用--lock-tables=false并接受部分表跳过 - 换路径:停止 mysqld,进
/www/server/data,看业务库子目录(如wordpress/)下是否有完整的.ibd文件 —— 如果有,且你记得或能反推建表语句,就放弃全库 dump,转为单表重建 - 验证
.ibd是否可用:用mysqlfrm --server=root@localhost:3306 --diagnostic /www/server/data/wordpress/wp_posts.ibd尝试解析结构;失败则说明页头损坏,需用十六进制编辑器查偏移0x38处的space_id是否为全 0 或异常值
真正起作用的其实是 DISCARD + IMPORT 流程
当 innodb_force_recovery 启动失败或 dump 出错,唯一可控的出路是绕过 ibdata1 的元数据依赖,用物理文件重建单表。
- 前提:MySQL 能以任意方式启动(哪怕只有
mysql系统库),且业务库目录下.ibd文件存在、大小合理(非 0 字节) - 新建空库和空表:
CREATE DATABASE recover_db; USE recover_db; CREATE TABLE wp_posts (...) ENGINE=InnoDB;—— 表结构必须与原表一致,字段顺序、类型、索引都不能错 - 执行:
ALTER TABLE wp_posts DISCARD TABLESPACE;,删掉新表的.ibd;再把原/www/server/data/wordpress/wp_posts.ibd复制过来 - 关键一步:导入前必须关闭外键检查:
SET FOREIGN_KEY_CHECKS=0;,否则IMPORT直接报错;导入后立即FLUSH TABLES; - 最后执行:
ALTER TABLE wp_posts IMPORT TABLESPACE;—— 成功则数据可查;失败常见于ERROR 1808,说明.ibd内部页 checksum 不通过,此时只能逐页跳过损坏段,没有通用解法
最麻烦的不是命令记不住,是 ibdata1 损坏后你无法判断哪部分元数据还可信。日志里那句 Corrupted page found at space id X, page no Y 才是真正该盯住的位置,而不是无脑调高 innodb_force_recovery 级别。











