系统实践

Docker 中 MySQL 的备份、恢复与恢复验证

从 2017 年的一组导入导出命令出发,整理一套更可靠的 MySQL 容器逻辑备份流程:导出、校验、恢复和验证缺一不可。

· 约 5 分钟阅读 · 更新于 2026年7月16日 · 近 30 天 10 次浏览

原文章使用的 Docker 文档封面图

本文最初发布于 2017 年。旧文解决了一个关键问题:如何从 MySQL 容器把 SQL 导出到宿主机,以及为什么恢复时要用 -i 而不是 -it。新版保留这个经验,并补上凭据、压缩、校验和恢复验证。

先理解重定向发生在哪里

下面的 > 是宿主机 Shell 执行的,所以 SQL 文件会写到宿主机当前目录,而不是容器里:

docker exec mysql mysqldump -u backup_user -p app_db > app_db.sql

不要把数据库密码直接写进命令历史。交互执行时可以只写 -p,让客户端提示输入;自动任务则应使用权限受限的配置文件或秘密管理机制。

一次可恢复的逻辑备份

先确认容器名和数据库状态:

docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
docker exec mysql mysqladmin ping -u backup_user -p

对于以 InnoDB 为主的普通业务库,可以这样导出:

docker exec mysql mysqldump \
  -u backup_user -p \
  --single-transaction \
  --routines \
  --events \
  --triggers \
  --set-gtid-purged=OFF \
  app_db \
  | gzip > app_db-$(date +%F).sql.gz

--single-transaction 能减少 InnoDB 逻辑备份期间的锁影响,但它不是所有存储引擎、所有一致性要求的万能方案。生产库需要结合数据量、引擎、复制和恢复目标设计备份策略。

备份后立即做三项检查

test -s app_db-$(date +%F).sql.gz
gzip -t app_db-$(date +%F).sql.gz
shasum -a 256 app_db-$(date +%F).sql.gz > app_db-$(date +%F).sql.gz.sha256

这只能证明文件存在、压缩包可读且以后能检查传输损坏,不能证明数据库一定可以恢复。

恢复到独立测试库

先创建一个不影响生产的目标库:

docker exec -it mysql mysql -u root -p \
  -e 'CREATE DATABASE IF NOT EXISTS app_db_restore CHARACTER SET utf8mb4;'

再进行恢复:

gunzip -c app_db-2026-07-16.sql.gz \
  | docker exec -i mysql mysql -u root -p app_db_restore

这里必须使用 docker exec -i,不能使用 -it。标准输入来自管道,不需要伪终端;旧文里记录的 cannot enable tty mode on non tty input 正是由此造成。

恢复成功不等于验证完成

至少检查:

docker exec mysql mysql -u root -p app_db_restore \
  -e 'SHOW TABLES;'

docker exec mysql mysql -u root -p app_db_restore \
  -e 'SELECT COUNT(*) FROM 关键表;'

更可靠的流程还应包含:

  • 抽查关键表行数、时间范围和业务约束。
  • 检查存储过程、事件、触发器和视图。
  • 用测试应用连接恢复库,跑一次核心读取流程。
  • 定期在独立环境演练,而不是等事故发生才第一次恢复。
  • 将备份复制到与数据库主机故障域不同的位置,并设置保留周期。

什么时候不只用 mysqldump

mysqldump 适合可读、通用的逻辑备份,但大数据库可能耗时较长、恢复较慢。MySQL 官方也建议评估 MySQL Shell dump utilities,它支持并行导出、压缩和进度展示。若要求更短的恢复时间、增量恢复或时间点恢复,还需要结合物理备份与二进制日志。

备份工作的完成标准不是“生成了一个 SQL 文件”,而是“在目标时间内恢复出了可用的数据”。

参考:MySQL 官方的使用 mysqldump 备份恢复 SQL 格式备份Docker 部署下的备份说明