现在后台开发和运维都是我一个人,所以服务器上的 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 界面。感觉有点鸡肋啊。 需要点击页面里的执行备份按钮,才能执行备份任务。

这个执行测试还行,生产环境中,我不需要这个 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
有两种方式:
- 使用系统的 cron 定时任务,调用 gobackup perform 命令,在指定的时间执行一次。
- 使用 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 聊聊, 查看更多联系方式