MySQL 5.7容器启停与崩溃恢复机制

docker stop 正常停 → 不会 crash recovery;kill -9 / 异常宕机 → 重启必做 crash recovery

一、两种 stop 的区别

  1. docker stop(默认 10s 优雅关闭)
  • MySQL 收到 SIGTERM,走正常 shutdown:
    • 停止新连接,回滚活跃事务
    • 脏页全部刷盘,写 checkpoint
    • 正常关闭 redo/undo log
  • 重启时 error log:Database was shut down normally无 crash recovery
  1. docker stop -t 0 /kill -9 / 容器被强杀
  • 直接断电,不走正常 shutdown
    • 内存脏页未刷盘、checkpoint 未写
    • redo log 有未完成事务
  • 重启时 error log:Database was not shut down normally强制进入 crash recovery

二、MySQL 5.7 InnoDB 恢复机制

  • 正常关闭:跳过 redo 重放,直接启动。
  • 异常关闭:必须执行 crash recovery
    1. 重放 redo log(前滚已提交未刷盘数据)
    2. 回滚未提交事务
    3. 清理 undo/purge 等MySQL。

三、容器场景常见现象

  • docker-compose down / docker stop无 crash recovery,启动快。
  • kill -9 $(pidof mysqld) / 宿主机断电:必 crash recovery,启动慢(取决于 redo 大小与负载)。
  • 日志特征(crash recovery):
InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Doing recovery: scanned up to log sequence number ...

四、如何避免不必要的 crash recovery

  1. Always use docker stop(给足时间,如 -t 300)。
  2. 不要在事务高峰期强杀容器。
  3. 关键环境配置 innodb_fast_shutdown=0(正常关闭时全量刷盘,更安全)。

innodb_fast_shutdown=0 详解(MySQL5.7 容器适配)

一、参数取值含义

1. innodb_fast_shutdown 三个值

  • 1(默认):快速关闭不刷全量脏页、只做最小化关闭,速度快,重启大概率触发 crash recovery
  • 2:最快速直接丢弃缓冲池脏页,相当于异常宕机,重启必走崩溃恢复
  • 0完整优雅关闭停机时做三件事:
    1. 停止新事务、回滚活跃事务
    2. 把缓冲池所有脏页全部刷到磁盘
    3. 清空 undo 日志、完成 purge 清理、落地所有事务状态

二、设为 0 的核心效果

  1. docker stop 正常停机后,重启绝对不会进 crash recovery
  2. 停机耗时变长(脏页越多、数据量越大,关得越慢)
  3. 数据一致性最高,适合生产容器、主从、定时重启场景

三、容器环境关键配置要点

1. my.cnf 配置写入

[mysqld]
innodb_fast_shutdown = 0
# 建议配套加这两个,适配优雅停机
innodb_buffer_pool_dump_at_shutdown = 1
innodb_buffer_pool_load_at_startup = 1

2. docker stop 必须加长超时

因为 0 关闭慢,默认 10 秒会超时,超时后 Docker 直接发 kill -9,等于白设!

# 给300秒优雅关闭时间
docker stop -t 300 mysql57

docker-compose 也要改:

services:
  mysql:
    image: mysql:5.7
    stop_grace_period: 300s

四、优缺点总结

✅ 优点

  • 正常 stop 重启无 crash recovery,启动快、无日志恢复开销
  • 数据落地完整,减少索引碎片、redo 日志残留
  • 主从架构不易出现 relay log 崩溃、事务不一致

❌ 缺点

  • 关机等待时间明显增加
  • 大内存、大表、高脏页场景,停机可能要几分钟

五、最佳实践建议

生产 MySQL5.7 容器必设 innodb_fast_shutdown=0 + stop_grace_period: 300s

彻底解决「正常 stop 重启还自动 crash recovery」的问题。

Categories: 数据库运维