MySQL崩溃恢复启动时,错误日志关键提示是“Database was not shutdown normally!”或“Starting crash recovery from checkpoint LSN=...”,表明已进入恢复流程;真正完成标志是出现“mysqld: ready for connections”,而非“Recovery completed”。

崩溃恢复启动时错误日志的关键提示
MySQL服务重启后若触发崩溃恢复,错误日志(如 /var/lib/mysql/hostname.err)会立即输出明确信号。最直接的判断依据是出现 Database system was interrupted; will perform recovery 或 Database was not shutdown normally! 这类语句——它不是警告,而是确认已进入恢复流程。
此时日志还会标注检查点位置,例如:Starting crash recovery from checkpoint LSN=123456789。这个 LSN 值就是 InnoDB 从 redo log 中开始扫描的起点,后续所有重做操作都以此为界,不是从头读整个日志文件。
- 正常关闭不会触发恢复,日志里只有
Shutdown completed,无任何 “recovery” 字样 - 若看到
InnoDB: Database page corruption on disk,说明物理页损坏,自动恢复大概率失败,需人工介入 - 恢复过程不打印进度百分比,但会按阶段输出计数,如
Recovering X transactions、Rolling back Y transactions
重做阶段(Redo)在日志中的体现
重做阶段对应日志中大量以 Applying log record 或 Replaying log 开头的行,通常紧随检查点提示之后。InnoDB 实际执行的是“物理重放”:把 redo log 中记录的数据页偏移量和字节值,原样写回 buffer pool 或刷盘。
关键观察点是日志是否出现 redo log parsing completed 或类似表述——这表示扫描结束,开始真正应用;如果卡在该阶段很久,往往意味着 redo log 文件损坏或磁盘 I/O 阻塞。
- 重做不涉及 SQL 解析,所以日志里绝不会出现
UPDATE、INSERT等语句文本 - 若启用
innodb_print_all_deadlocks=ON,可能混入死锁信息,但与恢复无关,别误判 - 重做耗时主要取决于脏页数量和磁盘吞吐,SSD 上通常秒级完成;HDD 上若重做记录超百万条,可能持续数分钟
回滚阶段(Undo)的日志特征与陷阱
回滚阶段日志通常以 Rolling back transaction 或 Undoing log record 开头,每条记录对应一个未提交事务的撤销动作。注意:这里“回滚”不是执行 ROLLBACK 命令,而是根据 undo log 中保存的前镜像(before image)反向修正内存页。
最容易被忽略的是:回滚阶段日志量远少于重做阶段,且不保证顺序输出。InnoDB 可能并发处理多个事务回滚,日志行序不代表执行先后。
- 若日志突然中断在
Rolling back...后无下文,大概率是某事务 undo log 损坏,需设innodb_force_recovery=1启动导出数据 -
innodb_force_recovery值 ≥ 3 时,InnoDB 会跳过回滚阶段,直接启动——此时数据库处于只读状态,且部分数据可能不一致 - 回滚本身不写新日志,但若中途崩溃,下次启动仍会重试,直到成功或报错退出
如何从日志确认恢复是否真正完成
不要依赖“没有新日志输出”来判断恢复结束。真正可靠的标志是出现 mysqld: ready for connections 或 Started mysqld daemon 这类服务就绪提示——它代表恢复流程已退出,主线程开始接受客户端连接。
在此之前,即使看到 Recovery completed,也可能只是某个子阶段结束。完整恢复必须满足两个条件:所有 redo log 应用完毕 + 所有活跃事务状态清理完成。
- 若日志末尾是
Aborting或Crashed,说明恢复失败,需检查磁盘空间、权限、ib_logfile 大小是否匹配配置 - 恢复完成后,
SHOW ENGINE INNODB STATUS\G中的LOG部分会显示最新 LSN,应与错误日志末尾的LSN值一致 - 恢复过程不可中断;强行 kill -9 mysqld 进程会导致 redo log 不完整,下次启动可能陷入无限循环恢复


















