VPS 服务器数据备份方案:数据库 Dump + rsync 增量同步
2026/7/8大约 2 分钟
VPS 服务器数据备份方案:数据库 Dump + rsync 增量同步
VPS 上运行多个 Docker 服务时,只同步容器目录并不等于完成备份。数据库需要一致性的逻辑导出,配置、证书和附件则适合用 rsync 增量同步。
备份分层
| 层次 | 方法 | 内容 |
|---|---|---|
| 数据库 | mysqldump、pg_dumpall | 业务数据、账号、权限 |
| 文件 | rsync -az | 配置、证书、附件、SQLite |
| 验证 | 清单、大小、抽样恢复 | 确认备份可用 |
不要把正在写入的数据库文件当作普通文件复制。MySQL 和 PostgreSQL 优先生成 dump;SQLite 则先停止写入或使用应用备份功能。
目录规划
backup/<server>/
├── app/
├── authentik/
├── proxy/
└── db-dump/手动备份
BACKUP="$HOME/backup/server-1"
mkdir -p "$BACKUP"/{app,authentik,proxy,db-dump}
ssh root@<server> \
"docker exec <mysql-container> mysqldump -uroot -p'<password>' \
--all-databases --single-transaction --routines --events" \
> "$BACKUP/db-dump/mysql-all.sql"
ssh root@<server> \
"docker exec <postgres-container> pg_dumpall -U <db-user>" \
> "$BACKUP/db-dump/postgres-all.sql"
rsync -az --delete --info=progress2 root@<server>:/opt/1panel/ "$BACKUP/app/"
rsync -az --delete root@<server>:/etc/<service>/ "$BACKUP/proxy/"密码不要硬编码在公开脚本中,使用权限受限的环境文件、SSH 配置或 Docker secret。
自动化脚本
#!/usr/bin/env bash
set -euo pipefail
SERVER="root@<server>"
BACKUP="$HOME/backup/server-1"
mkdir -p "$BACKUP"/{app,authentik,proxy,db-dump}
ssh "$SERVER" "docker exec <mysql-container> mysqldump -uroot -p'<password>' --all-databases --single-transaction" \
> "$BACKUP/db-dump/mysql-all.sql"
ssh "$SERVER" "docker exec <postgres-container> pg_dumpall -U <db-user>" \
> "$BACKUP/db-dump/postgres-all.sql"
rsync -az --delete --timeout=60 "$SERVER:/opt/1panel/" "$BACKUP/app/"
rsync -az --delete --timeout=60 "$SERVER:/root/<app>/" "$BACKUP/authentik/"
rsync -az --delete --timeout=60 "$SERVER:/etc/<service>/" "$BACKUP/proxy/"
test -s "$BACKUP/db-dump/mysql-all.sql"
test -s "$BACKUP/db-dump/postgres-all.sql"
echo BACKUP_OK可以用 cron 每天凌晨执行:
0 3 * * * /Users/<user>/bin/backup-server.sh建议保留 7 份日备份和 4 份周备份,并把备份盘与服务器分离。rsync --delete 只解决镜像同步,不提供历史版本;重要数据还应保留带日期的 dump。
恢复演练
scp "$BACKUP/db-dump/mysql-all.sql" root@<server>:/tmp/
ssh root@<server> \
"docker exec -i <mysql-container> mysql -uroot -p'<password>' < /tmp/mysql-all.sql"
rsync -az "$BACKUP/app/" root@<server>:/opt/1panel/恢复后检查登录、数据库连接、证书、附件和反向代理。只有成功恢复过一次,备份才算真正可用。
常见坑
- named volume 不一定在项目目录,需要单独导出或做数据库 dump。
rsync --delete方向写反会删除备份或源端文件。- 只备份数据库而漏掉密钥、证书和应用配置,恢复时仍无法启动。
- 只看同步命令退出码不够,还要检查 dump 非空并定期恢复演练。
