使用 gobackup 自动将 MySQL 数据库备份到七牛云私有空间

文章目录

    现在后台开发和运维都是我一个人,所以服务器上的 MySQL 数据库备份也只能自己来做了。
    由于服务分散在多台服务器上,并且有几十个数据库需要备份,手动备份实在是太麻烦了。
    需要一套自动化的备份流程。定时将数据库导出,并存储到云存储空间中,例如七牛云存储或者阿里云 OSS 上。

    备份方案的选择

    我昨天纠结了半天,到底用什么方案或者工具来做数据库的自动备份:

    • 手写 shell 脚本。这个很麻烦,因为数据库太多,不同服务对应的云存储还不一样。逻辑复杂,不适合用 shell 脚本来写。
    • Python 脚本。本来是都开始动手要写了,但是登录了一台服务器,发现居然是 Ubuntu 18.04 系统,Python 版本只有 3.6,实在是太老了,AWS S3 的 boto3 库连 python 3.8 都不支持了。升级 Python 版本又麻烦,索性放弃了。
    • Golang 开发。这个变成了一个可行的方案,而且 golang 的 S3 SDK 也支持比较好。但是我在起名字的时候,发现 gobackup 这个名字已经被占用了,而且功能还非常完善,跟我的需求完全一致。。。

    就是下面这个 gobackup 项目:

    https://github.com/gobackup/gobackup

    Ruby China 社区的服务器就是用 gobackup 来备份数据库的,然后上传到阿里云 OSS 上。
    哈哈,还开发个球,直接用现成的工具就行了,省时省力,不重复造轮子 🤣

    gobackup 中 mysql 数据库的备份原理是什么

    其实就是调用 mysqldump 命令来导出数据库,然后把导出的 SQL 文件打包压缩,最后上传到云存储空间。

    mysql 安装在 docker 容器中,如何备份

    有些情况下,MySQL 被安装到了 Docker 容器中,这种情况下,如何通过 gobackup 来备份 MySQL 数据库呢?

    从 gobackup 的文档看,官方有提供 docker 镜像:

    https://gobackup.github.io/docker

    We builded a Docker image for GoBackup. You can use it to run GoBackup in a container.

    参考:

    https://hub.docker.com/r/huacnlee/gobackup

    Dockerfile 内容:

    RUN |1 VERSION=latest /bin/sh -c apk add   curl   ca-certificates   openssl   postgresql-client   mariadb-connector-c   mysql-client   mariadb-backup   redis   mongodb-tools   sqlite   tar   gzip   pigz   bzip2   coreutils   lzip   xz-dev   lzop   xz   zstd   libstdc++   gcompat   icu   tzdata   &&   rm -rf /var/cache/apk/* # buildkit
    

    看来是在 docker 容器中安装了 mysql-client,然后通过 mysqldump 来备份 mysql 数据库的。

    安装

    curl -sSL https://gobackup.github.io/install | sh
    

    说实话,我对这种直接执行安装脚本的方式,非常担心,生怕里面有 bug 导致服务器文件被删。。。
    所以,我大致看了一下安装脚本的脚本逻辑,发现它其实就是下载 gobackup 的二进制文件,然后放到 /usr/local/bin 目录下。

    https://github.com/gobackup/gobackup/blob/main/install

    也可以 release 页面下载对应的二进制文件 gobackup-linux-amd64.tar.gz (仅有 10M),然后解压到 /usr/local/bin 目录下即可。

    安装完成,确认:

    > gobackup --version
    gobackup version 2.16.0
    

    配置文件

    先用开发机本地的数据库做测试,确认 gobackup 能正常备份

    首先创建目录:

    mkdir ~/.gobackup
    

    创建配置文件:~/.gobackup/gobackup.yml

    models:
      my_app:
        compress_with:
          type: tgz
        storages:
          local:
            type: local
            keep: 20
            path: /data/backups
        databases:
          my_app:
            database: myproject_db
            type: mysql
            host: localhost
            port: 3306
            username: xxx
    		password: password
        archive:
          includes:
            - /var/www/my_app/uploads
            - /var/www/my_app/shared/ssl
    

    这个还挺贴心的,还支持把指定的目录一起打包归档。非常适合服务器的一些配置文件和上传文件的备份。确实有经验。

    Web 界面跑起来

    > gobackup run
    2025/10/25 14:00:26 [Config] Load config from default path.
    2025/10/25 14:00:26 [Config] Other users are able to access /home/xxx/.gobackup/gobackup.yml with mode -rw-r--r--
    2025/10/25 14:00:26 [Config] Config file: /home/xxx/.gobackup/gobackup.yml
    2025/10/25 14:00:26 [Config] Config loaded, found 1 models.
    2025/10/25 14:00:26 [API] You are running with insecure API server. Please don't forget setup `web.password` in config file for more safety.
    2025/10/25 14:00:26 [API] Starting API server on port http://0.0.0.0:2703
    

    浏览器访问 http://localhost:2703 能看到 gobackup 的 Web 界面。感觉有点鸡肋啊。
    需要点击页面里的执行备份按钮,才能执行备份任务。

    gobackup

    这个执行测试还行,生产环境中,我不需要这个 Web 界面,得看看怎么禁用掉。
    找到了方法,使用命令行方式执行备份任务即可:

    gobackup perform
    

    这样就是执行一次备份任务,并且不启动 Web 界面。

    备份的目录结构

    执行了两次备份任务,并且将其中一次备份做了解压缩,查看 /data/backups 目录的结构:

    > tree /data/backups/
    /data/backups/
    ├── 2025.10.25.14.05.39.tar.gz
    ├── 2025.10.25.14.14.14.tar.gz
    └── my_app
        ├── archive.tar
        └── mysql
            └── my_app
                └── myproject_db.sql
    
    3 directories, 4 files
    

    可以看到:

    • 备份文件是以时间戳命名的 tar.gz 文件
    • 在解压后的目录中,有 mysql 目录,里面是 mysqldump 导出的 SQL 文件
    • archive.tar 是打包的 archive 配置,例如上传文件和配置文件的归档文件

    解压确认了一下,文件内容都是完整的。

    定时任务配置

    参考:

    https://gobackup.github.io/schedule

    有两种方式:

    1. 使用系统的 cron 定时任务,调用 gobackup perform 命令,在指定的时间执行一次。
    2. 使用 gobackup 自带的 schedule 功能,在 gobackup.yml 配置文件中,添加 schedule 配置。需要使用 gobackup start 命令来启动服务。如果 docker 中不带 crontab 的话,就只能用这种方式了。

    不同的备份时间粒度

    因为每个 model 可以设置独立的 schedule 配置,所以可以实现不同的备份时间粒度。
    例如,重要的数据库,可以设置为每小时备份一次;不太重要的数据库,可以设置为每天备份一次; 有的一个月备份一次都可以。

    即便是 perform 命令,也是可以指定 model 名称的, 参考 help:

    > gobackup -h perform
    NAME:
       gobackup perform
    
    USAGE:
       gobackup perform [command options] [arguments...]
    
    OPTIONS:
       --model value, -m value [ --model value, -m value ]  Model name that you want perform
       --config value, -c value                             Special a config file
       --help, -h                                           show help (default: false)
    

    上传到七牛云私有空间

    配置文件中,添加七牛云的存储配置,替换掉 local 存储配置:

    models:
      my_app:
        compress_with:
          type: tgz
        storages:
          kodo:
            type: kodo
            keep: 2
            bucket: private-bucket-name
            region: cn-south-1
            path: backups/myproject_db
            access_key_id: <七牛的 Access Key>
            secret_access_key: <七牛的 Secret Key>
            storage_class: LINE  # 可选参数,默认 STANDARD,这个 LINE 是低频存储,节省成本
        databases:
          my_app:
            database: myproject_db
            type: mysql
            host: localhost
            port: 3306
            username: xxx
            password: password
        archive:
          includes:
            - /var/www/my_app/uploads
            - /var/www/my_app/shared/ssl
    

    限制备份文件的保留数量

    主要是为了节省云存储的成本,参考官方文档:

    https://gobackup.github.io/configuration/storages#cycling

    可以通过 keep 参数,来限制备份文件的保留数量,超过数量的备份文件会被自动删除。

    不知道云存储的备份文件,是否也会被自动删除?需要测试一下。测试了一下确实可以,例如 keep: 3,上传到 S3 的备份文件也只会保留最新的 3 个,超过的会被删除。

    如果用 perform 命令执行备份任务,日志中会有类似如下的删除备份文件的日志:

    2025/10/25 15:43:19 [Cycler] Removed 2025.10.25.15.41.10.tar.gz
    

    到此,基本功能算是测试完成了。其他的通知功能,openssl 加密功能,暂时用不上, 先不测试了。

    今天周六,还是不着急上线到生产环境,怕出问题,等下周一再说吧。

    安全问题

    • 代码示例中是直接把密码拼到命令行(-ppassword),这会在系统进程列表中可见,存在泄露风险。若担心安全性,可考虑使用 my.cnf 配置文件或其他更安全的凭证传递方式(在 mysqldump 支持的范围内)或仅在受控环境中运行。
    • 七牛云还是使用一个独立的私有存储空间,不配置公网访问域名的。(其他云存储也是这样)避免和其他服务混用,降低风险。因为有些公网可以访问的私有空间,还是存在被前端接口误用的风险。
    • 如果用 start 模式,需要配置 web.password,避免未授权访问。最好不要开放这个端口,在阿里云防火墙中屏蔽掉这个端口的访问。毕竟专业的运维,不需要这个 WEB 界面。

    没有 Linode Bucket 的支持

    目前 gobackup 官方并没有支持 Linode Bucket 的存储方式,只有 AWS S3 兼容的存储方式。

    得测试一下 gobackup 是否能通过 S3 兼容的方式,来上传到 Linode Bucket 上。

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式