必须先查错误日志最开头几行,盯住innodb:开头的error行;如出现“database page corruption on disk”才是真损坏,需逐级尝试innodb_force_recovery=1~6导出数据后重建实例。

直接看错误日志最开头几行,盯住 InnoDB: 开头的 ERROR 行——它不是辅助信息,而是启动失败的判决书;跳过这步就设 innodb_force_recovery,大概率白忙活还丢数据。
怎么快速定位日志里的真损坏线索
别从日志末尾翻,MySQL 启动失败时,真正致命的错误总在日志最靠前(通常是第 1~5 行)。重点搜这些关键词:
-
InnoDB: Database page corruption on disk→ 物理页损坏,innodb_force_recovery是唯一逃生通道 -
The log sequence number in ibdata1 does not match→ redo log 和数据文件 LSN 不一致,常见于强制 kill 后重启;通常删掉ib_logfile0和ib_logfile1就能恢复,不用开 recovery -
Failed to initialize transaction sub-system→ undo log 或事务系统初始化失败,大概率只需重建日志,不是数据损坏 -
Unable to lock ./ibdata1→ 更可能是残留进程、权限不足或文件被占用,不是 InnoDB 损坏 -
Table 'xxx' is marked as crashed→ MyISAM 表坏了,该用mysqlcheck --repair,跟 InnoDB 无关
为什么 innodb_force_recovery 设错值反而读不出表
innodb_force_recovery 不是“修复开关”,而是逐级跳过恢复步骤的只读逃生通道。数值越大,跳过的逻辑越多,内部状态越不一致:
- 设为
1:忽略损坏页,仍可能读出大部分表 - 设为
3:跳过事务回滚,是导出数据最常用的安全级 - 设为
4及以上:禁止所有写操作(DROP TABLE都报ERROR 1036 (HY000): Table is read only),且可能跳过索引加载,导致SELECT报错或返回空 - 跳着设(比如直接
=6):InnoDB 可能连系统表都加载不了,mysql连得上但SHOW DATABASES返回空
必须从 1 开始逐级试,每次改完都要彻底停服务再重启,不能靠“重启 MySQL”面板按钮——它常不重载配置。
mysqldump 导出失败的三个硬坑
就算 innodb_force_recovery = 3 成功启动,mysqldump 仍大概率卡死、漏表或断连,因为默认行为会触发锁机制,而 recovery 模式下锁不可用:
- 必须加
--skip-lock-tables,否则mysqldump会无限等锁超时 -
--single-transaction对一致性有帮助,但在 recovery 模式下不一定生效,尤其当 undo log 被跳过时 - 全库导出失败?立刻切到单库:
mysqldump -u root -p 库名 > db.sql;某张表导不出?换SELECT ... INTO OUTFILE或用mysqlpump
导出成功后别急着关 recovery 模式继续用——此时 InnoDB 内部结构已处于不一致状态,下次启动大概率二次崩溃。必须清空 innodb_force_recovery、删掉 ibdata1 和 ib_logfile*、重建实例。











