MySQL宕机后能恢复到最后一个完整提交事务,前提是innodb_flush_log_at_trx_commit=1且磁盘write cache禁用;否则可能丢失最近1秒及以上已提交数据。

MySQL宕机后能恢复到哪一刻的数据?
取决于是否开启了 innodb_flush_log_at_trx_commit=1 且磁盘写入未被缓存劫持。InnoDB 的重做日志(ib_logfile0、ib_logfile1)只保证已提交事务的持久性,未提交或刚写入 buffer pool 但还没刷盘的修改,宕机后必然丢失。
- 如果配置为
innodb_flush_log_at_trx_commit=1+ 磁盘禁用 write cache(如hdparm -W0 /dev/sdX),崩溃后可恢复到最后一个完整提交事务 - 若设为
0或2,可能丢失最近 1 秒甚至 1 秒以上的已提交数据 - 重做日志不是备份——它不保存表结构、DDL 操作、或非 InnoDB 表的数据
如何确认重做日志是否还在起作用?
MySQL 启动时会自动执行崩溃恢复(crash recovery),只要 ib_logfile* 文件存在且未被手动删除,就一定会走这个流程。你不需要手动触发,但得知道它有没有真跑起来。
- 查看错误日志中是否有类似
InnoDB: Doing recovery: scanned up to log sequence number XXX的行 - 若出现
InnoDB: The log sequence number in ibdata files does not match,说明日志文件和数据文件不匹配,可能是日志被删过或误复制了旧数据目录 - 启动卡在
Starting crash recovery...超过几分钟,大概率是日志损坏或磁盘 I/O 异常,别等,先停服务查硬件
哪些操作会让重做日志失效?
重做日志只对 InnoDB 表生效,且依赖完整的日志链。以下行为直接绕过或破坏恢复能力:
- 手动删除
ib_logfile0和ib_logfile1后重启 MySQL:InnoDB 会重建日志,但所有未刷盘的提交事务永久丢失 - 用
mysqld --innodb-force-recovery=6启动后导出数据再重建实例:此时重做日志不参与恢复,只是强行读取页,结果不可靠 - 混用 MyISAM 表:MyISAM 没有重做日志,宕机后只能靠
.MYD文件状态,通常损坏即丢失 - 启用了
innodb_fast_shutdown=2关机(默认),会跳过部分刷脏页操作,增加恢复时间但不影响日志有效性;但设为0才真正做完整关闭,日常没必要
恢复后第一件事该检查什么?
别急着上线,先验证数据一致性。重做日志恢复的是物理页变更,不校验逻辑正确性。
- 运行
mysqlcheck --all-databases --check,重点看 InnoDB 表是否报error: record is corrupted - 对比关键业务表的
COUNT(*)和宕机前快照(如果有),数量突变往往意味着部分页没恢复成功 - 检查
SHOW ENGINE INNODB STATUS\G中的LOG部分,确认Log sequence number和Last checkpoint at差值不大(几百 MB 内正常) - 如果应用层有幂等设计,优先重放最近 5 分钟 binlog(需提前开启),比单靠重做日志更准——重做日志不记录 SQL,binlog 才记
重做日志恢复是自动的、底层的、有限度的。它救不了删库,也补不上没开 binlog 的空档。真正可靠的恢复,永远建立在定期备份 + binlog 归档 + 恢复演练的基础上。











