Press "Enter" to skip to content

使用Docker部署,定期自动备份MySQL数据库

我们已经有了从云服务器取回文件的方案,现在的核心需求是:在服务器端,定期、自动地导出 Docker 中的 MySQL 数据,压缩并保存到指定目录(挂载卷)。

考虑到需要“简单、稳定、现成”的方案,且接受部署一个新的 Docker 容器,强烈推荐使用专门的 Docker 备份镜像。因为成熟的镜像已经封装好了 mysqldumpcrontab(定时任务)、gzip(压缩)以及过期备份自动清理(Retention)的逻辑。

这里推荐使用业界非常流行且轻量的镜像:fradelg/mysql-cron-backup (或者类似的变体)。

解决方案架构

你将在服务器上创建一个独立的 docker-compose.yml 来管理备份服务。因为你有 2个 MySQL 实例,最简单稳定的做法是起 2个轻量级备份容器,分别对应两个数据库实例。这样互不干扰,配置清晰。

操作步骤

1. 准备工作:确认网络

由于备份容器需要连接到现有的 MySQL 容器,它们需要能够互相通信。

  • 情况 A:如果你现有的 MySQL 都在同一个 Docker 网络中(比如 my-network),你只需把备份容器加入该网络。
  • 情况 B:如果你现有的 MySQL 直接映射端口到了宿主机的 3306/3307,你也可以让备份容器通过宿主机的 IP 访问(不推荐,走 Docker 网络更安全)。

假设你现有的两个 MySQL 容器名分别为 mysql_container_1mysql_container_2,且它们都在名为 app_net 的网络中。

2. 创建备份服务的 Docker Compose

在服务器上新建一个目录,例如 /opt/db-backups,并在其中创建 docker-compose.yml

version: '3'

services:
  # --- 备份第一个 MySQL 实例 ---
  backup-db-1:
    image: fradelg/mysql-cron-backup
    container_name: backup-worker-1
    depends_on:
      - mysql_container_1 # 确保能找到目标容器(如果不在同一个compose文件可忽略此行,但必须在同网络)
    volumes:
      # 将容器内的备份目录映射到宿主机的物理路径
      - ./data/db1:/backup
    environment:
      # 数据库连接信息
      - MYSQL_HOST=mysql_container_1  # 现有 MySQL 容器的服务名或容器名
      - MYSQL_PORT=3306
      - MYSQL_USER=root               # 建议创建一个只读权限的备份专用账号,省事则用root
      - MYSQL_PASS=your_password_1
      # 要备份的数据库名称,多个数据库用空格隔开,备份所有库填 *
      - MYSQL_DATABASE=db_name_a db_name_b
      # 压缩选项
      - GZIP_LEVEL=9                  # 最高压缩比
      # 定时任务 (Cron 表达式)
      - CRON_TIME=0 3 * * *           # 每天凌晨 3:00 执行
      # 保留策略
      - MAX_BACKUPS=7                 # 本地只保留最近 7 个备份文件,自动删除旧的
      - INIT_BACKUP=0                 # 启动容器时是否立即备份一次 (0=否, 1=是)
    networks:
      - app_net                       # 必须与你的 MySQL 容器在同一个网络

  # --- 备份第二个 MySQL 实例 ---
  backup-db-2:
    image: fradelg/mysql-cron-backup
    container_name: backup-worker-2
    volumes:
      - ./data/db2:/backup
    environment:
      - MYSQL_HOST=mysql_container_2
      - MYSQL_PORT=3306
      - MYSQL_USER=root
      - MYSQL_PASS=your_password_2
      - MYSQL_DATABASE=other_db_x
      - GZIP_LEVEL=9
      - CRON_TIME=0 3 * * *           # 也可以设置不同时间错峰备份
      - MAX_BACKUPS=7
    networks:
      - app_net

# 定义网络(声明这是一个外部已存在的网络)
networks:
  app_net:
    external: true

3. 部署并验证

  1. 启动服务:
    docker-compose up -d
    
  2. 测试备份:
    你可以手动进入容器触发一次备份,或者修改 INIT_BACKUP=1 重启容器来测试配置是否正确。
    # 手动执行一次脚本进行测试
    docker exec backup-worker-1 /backup.sh
    
  3. 查看结果:
    检查宿主机的 ./data/db1 目录,你应该能看到类似 db_name_a-20231027-0300.sql.gz 的文件。

为什么选择这个方案?

  1. 解耦与隔离:两个 MySQL 对应两个备份容器,如果其中一个数据库挂了或者配置变了,不会影响另一个的备份任务。
  2. 简单稳定:使用的是 mysqldump 原生工具,加上简单的 Shell 脚本控制,没有复杂的逻辑,极不容易出错。
  3. 功能齐全
    • 定时:内置 Cron,不需要配置宿主机的 Crontab。
    • 压缩:直接生成 .gz 文件,节省带宽和空间。
    • 轮转MAX_BACKUPS 参数非常关键,它能防止你的磁盘被无限增长的备份文件填满,自动清理旧文件。
  4. 无状态:容器坏了删掉重开即可,配置都在 docker-compose.yml 里。

总结建议

直接使用 fradelg/mysql-cron-backup 的 Docker Compose 方案。这是最符合“简单、稳定、现成”标准的做法,几行配置就能搞定两个数据库的定时备份、压缩和自动清理。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注