把数据只存在 VPS 本地等于把鸡蛋放在一个篮子里——磁盘故障、误删、账号出问题,都可能让备份和网站数据一起消失。将备份自动推送到对象存储(如 AWS S3、Cloudflare R2、Backblaze B2、阿里云 OSS 等),是既廉价又可靠的异地备份方案。本文演示用 mysqldump+tar 打包、rclone 上传、crontab 定时,并配置保留策略,帮你建立全自动的异地备份流程。

本文要点

  • mysqldump 备份数据库 + tar 打包网站目录
  • rclone 统一管理各大对象存储,配置一次通用所有服务商
  • crontab 定时每天自动执行备份
  • 自动清理旧备份,控制存储成本

安装并配置 rclone

rclone 是统一管理对象存储的命令行工具,支持 S3、R2、B2、OSS、COS 等数十种服务商:

# 安装 rclone
curl https://rclone.org/install.sh | bash

# 验证安装
rclone version

配置远端(以 Cloudflare R2 为例)

# 启动交互式配置向导
rclone config

# 按提示操作:
# n → 新建远端
# 名称填:r2backup
# 类型选:s3(R2 兼容 S3 协议)
# provider 选:Cloudflare
# 填写 access_key_id、secret_access_key
# endpoint 填:https://<账户ID>.r2.cloudflarestorage.com
# 其余保持默认,最后 q 退出

# 测试连接
rclone lsd r2backup:

# 列出 Bucket 内文件
rclone ls r2backup:mybucket/

其他对象存储配置

AWS S3、阿里云 OSS、Backblaze B2 等配置方式类似,只需在 rclone config 时选择对应 provider 并填写 AK/SK 与 endpoint。官方文档 rclone.org 有各平台详细说明。

编写备份脚本

创建脚本 /usr/local/bin/backup.sh

#!/bin/bash
set -euo pipefail

# ---- 配置区 ----
DB_USER="root"
DB_PASS="数据库密码"
DB_NAME="myapp"
SITE_DIR="/var/www/html"
REMOTE="r2backup:mybucket/vps-backup"
BACKUP_DIR="/tmp/backups"
DATE=$(date +%Y-%m-%d)
# ----------------

mkdir -p "$BACKUP_DIR"

# 1. 备份数据库
echo "==> Dumping database..."
mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" \
  | gzip > "$BACKUP_DIR/db_${DATE}.sql.gz"

# 2. 备份网站目录
echo "==> Archiving site..."
tar czf "$BACKUP_DIR/site_${DATE}.tar.gz" "$SITE_DIR"

# 3. 上传到对象存储
echo "==> Uploading to remote..."
rclone copy "$BACKUP_DIR/" "$REMOTE/" \
  --include "*_${DATE}.*" --progress

# 4. 清理本地临时文件
rm -f "$BACKUP_DIR/db_${DATE}.sql.gz" "$BACKUP_DIR/site_${DATE}.tar.gz"

echo "==> Backup done: $DATE"
# 赋予可执行权限并测试
chmod +x /usr/local/bin/backup.sh
/usr/local/bin/backup.sh

配置 crontab 定时执行

# 编辑 root 的 crontab
crontab -e

# 添加以下行:每天凌晨 3 点执行备份,日志写到文件
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

时区注意

crontab 使用系统时区。先用 timedatectl 确认时区,若服务器为 UTC,则凌晨 3 点 UTC 对应北京时间上午 11 点。按需调整时间或设置 CRON_TZ=Asia/Shanghai

设置保留策略(自动清理旧备份)

rclone 支持按时间删除远端旧文件,将以下命令加入备份脚本或单独定时执行:

# 删除远端 30 天前的备份
rclone delete r2backup:mybucket/vps-backup \
  --min-age 30d --include "*.gz"
保留策略参数说明
7 天--min-age 7d适合每日备份,只保留近一周
30 天--min-age 30d适合重要数据,保留近一个月
保留 N 份配合脚本逻辑按文件数量删除最旧的

小结

  • mysqldump 压缩备份数据库,tar 打包网站目录
  • rclone 一次配置,支持几乎所有主流对象存储服务商
  • crontab 定时自动执行,配合日志文件便于排查
  • 保留策略控制存储成本,避免备份文件无限堆积
  • 定期演练恢复流程,确认备份文件确实可用

常见问题

rclone 支持哪些对象存储?

rclone 支持 AWS S3、Cloudflare R2、Backblaze B2、阿里云 OSS、腾讯云 COS、Google Cloud Storage 等数十种服务商,配置方式高度统一。

mysqldump 备份时会锁表影响业务吗?

对 InnoDB 引擎,加 --single-transaction 参数可在不锁表的情况下备份:mysqldump --single-transaction -u root -p dbname。建议在业务低峰期执行。

如何验证备份文件是否完好?

定期从对象存储下载备份文件并尝试恢复到测试数据库:gunzip < db_DATE.sql.gz | mysql -u root -p testdb。能正常恢复才算真正有效的备份。

脚本执行报错 command not found,如何排查?

crontab 运行环境的 PATH 比交互式 Shell 少。在脚本开头加 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,或使用绝对路径调用命令。