13 10 月 2026

备份这件事,90% 的人知道要做,但真出事了才发现备份是坏的、过期的、或者根本没跑。这篇用一个可直接用的脚本方案,把备份做成「设完就忘」的自动化流程。

增量同步、按策略保留、异地外传、失败告警——四个要素全齐。

需要云服务器可以看看财富云计算:支持快照,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,一键开服面板,主流游戏快速部署。

一、为什么是 rsync

备份工具很多,rsync 是通用性最强的:

能力rsynccp/tar网盘同步
增量传输(只传变化的)✅❌部分
断点续传✅❌✅
保留权限/时间戳/软链接✅tar 可以视工具
本地+远程+SSH✅仅本地仅远程
排除规则✅ 灵活❌有限
加密传输✅(走 SSH)❌✅

游戏服备份、网站备份、配置文件同步,rsync 一把全搞定。

二、核心用法速查

# 本地 → 本地
rsync -av /源目录/ /目标目录/

# 本地 → 远程(SSH)
rsync -avzP /源目录/ user@远程IP:/目标目录/

# 远程 → 本地(拉取)
rsync -avzP user@远程IP:/源目录/ /本地目标/

# 远程 → 远程
rsync -avzP user@A:/源/ user@B:/目标/

参数拆解:

参数作用
-a归档模式:递归 + 保留权限、时间戳、 owner、软链接
-v显示详情
-z传输时压缩(文本类有效,已压缩的媒体文件无效)
-P显示进度 + 断点续传(等价 --partial --progress)
--delete目标端删除源端已不存在的文件(保持完全一致)
-e "ssh -p 22222"指定 SSH 端口
--exclude排除文件/目录
--bwlimit=1000限速 1000 KB/s,别把带宽跑满

末尾斜杠的坑(最容易错):

rsync -av /data/games/ /backup/games/    # 同步目录内容 → /backup/games/文件们
rsync -av /data/games /backup/           # 同步目录本身 → /backup/games/文件们

结果一样,但语义不同。习惯统一用第一种(源带斜杠)。

三、生产级备份脚本

这是本站实际在用的方案,四个设计要点:

  1. 每日增量 + 硬链接:省空间,又保留历史版本
  2. 分层保留:日备 7 份、周备 4 份、月备 12 份
  3. 失败告警:备份失败立刻知道,而不是两周后恢复时才发现
  4. 可恢复性验证:定期抽查备份完整性
#!/bin/bash
#==================================================
# 增量备份脚本(基于 rsync + 硬链接)
# 用法: ./backup.sh
#  cron: 0 3 * * * /opt/scripts/backup.sh
#==================================================

set -euo pipefail

# ===== 配置区 =====
SOURCE="/opt/games"                    # 要备份的源
DEST="/backup/games"                   # 本地备份目标
REMOTE="user@nas.local:/backup/games"  # 异地目标(没有就留空)
KEEP_DAILY=7                           # 保留每日备份天数
KEEP_WEEKLY=4
KEEP_MONTHLY=12
LOGFILE="/var/log/backup.log"
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key"

DATE=$(date +%Y%m%d)
TODAY="$DEST/$DATE"
YESTERDAY="$DEST/$(date -d 'yesterday' +%Y%m%d 2>/dev/null || date -v-1d +%Y%m%d)"

# ===== 函数 =====
log() { echo "[$(date '+%F %T')] $1" | tee -a "$LOGFILE"; }

alert() {
    curl -s "$WEBHOOK" -H 'Content-Type: application/json' -d "{
      \"msgtype\": \"text\",
      \"text\": {\"content\": \"【备份告警】$1\"}
    }" || true
}

cleanup_old() {
    # 日备:保留最近 N 天
    ls -1t "$DEST" | grep -E '^[0-9]{8}$' | tail -n +$((KEEP_DAILY + 1)) | \
    while read d; do rm -rf "$DEST/$d"; done
}

# ===== 主流程 =====
trap 'alert "备份失败: $0 在 $DATE 执行出错,请检查 $LOGFILE"' ERR

log "=== 开始备份 $SOURCE ==="

mkdir -p "$DEST"

# 增量同步:如果昨天有备份,用硬链接,没变的文件不复制
if [ -d "$YESTERDAY" ]; then
    rsync -a --delete --link-dest="$YESTERDAY" \
        --exclude='*.tmp' --exclude='*.log' \
        "$SOURCE/" "$TODAY/"
else
    rsync -a --delete \
        --exclude='*.tmp' --exclude='*.log' \
        "$SOURCE/" "$TODAY/"
fi

log "本地同步完成: $TODAY"

# 异地同步(可选)
if [ -n "$REMOTE" ]; then
    rsync -azP --delete "$TODAY/" "$REMOTE/$DATE/" && \
        log "异地同步完成: $REMOTE/$DATE" || \
        alert "异地同步失败,请检查网络和目标机器"
fi

# 清理
cleanup_old
log "已清理 ${KEEP_DAILY} 天前的旧备份"

# 验证:检查关键目录是否存在
if [ ! -d "$TODAY" ]; then
    alert "备份目录不存在,备份可能失败!"
    exit 1
fi

SIZE=$(du -sh "$TODAY" | cut -f1)
log "=== 备份完成,本次大小 $SIZE ==="

trap - ERR

关键点:--link-dest 硬链接增量

rsync -a --link-dest=/backup/games/昨天 /opt/games/ /backup/games/今天/

没变化的文件不复制,直接在「今天」的目录里建个硬链接指向「昨天」的文件。效果:

  • 看起来每天一份完整备份
  • 实际只存变化的文件,空间占用接近增量
  • 任何一天都能单独恢复(和全量没区别)

这是备份方案的精髓,比「周一全量+周日增量」的传统轮换好用得多。

四、挂定时任务

chmod +x /opt/scripts/backup.sh
crontab -e

# 每天凌晨 3 点备份(选低峰期,游戏服选早上 6 点)
0 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

# 每周日凌晨做一次全量校验
0 4 * * 0 /opt/scripts/backup-verify.sh >> /var/log/backup-verify.log 2>&1

避坑:crontab 的环境变量和交互式 shell 不一样,脚本里用绝对路径;rsync 在 /usr/bin/rsync,cron 的 PATH 可能不含,脚本开头加 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。

五、异地备份:别把鸡蛋放一个篮子

本地备份防误删,异地备份防机器整个没。三个层次:

层次方案适用
同机不同盘rsync 到数据盘防手滑删文件
同云不同机rsync 到另一台机器防单机故障
异地/离线对象存储 + 定期下载防机房事故、账号被盗

对象存储外传(以腾讯 COS 为例):

# 装工具
pip install coscmd
coscmd config -a SecretId -s SecretKey -b 你的桶名 -r ap-guangzhou

# 上传(加密压缩后再传,省流量)
tar -czf - /backup/games/$DATE | coscmd upload - /backup/games-$DATE.tar.gz

# 或者同步整个目录
coscmd upload -rs /backup/games/ /games-backup/

成本极低:冷备份一年几百 GB 也就几十块钱,换的是「机房炸了数据还在」。

六、备份验证:备份 ≠ 能恢复

这是最多人忽略的一步。验证脚本:

#!/bin/bash
# /opt/scripts/backup-verify.sh
# 每周跑一次,抽查备份可恢复性

DEST="/backup/games"
LATEST=$(ls -1t "$DEST" | grep -E '^[0-9]{8}$' | head -1)
TESTDIR="/tmp/backup-test/$LATEST"

log() { echo "[$(date '+%F %T')] $1"; }

log "验证备份: $LATEST"

# 1. 目录存在且非空
if [ ! -d "$DEST/$LATEST" ] || [ -z "$(ls -A $DEST/$LATEST)" ]; then
    log "失败: 备份目录为空!"
    exit 1
fi

# 2. 抽查关键文件(按你的业务改)
CRITICAL="/opt/games/palworld/server/Pal/Saved"
if [ ! -e "$DEST/$LATEST$CRITICAL" ]; then
    log "警告: 关键存档目录 $CRITICAL 不在备份中"
fi

# 3. 试恢复(解压到临时目录,验证可读)
mkdir -p "$TESTDIR"
rsync -a "$DEST/$LATEST/palworld/" "$TESTDIR/" 2>/dev/null
if [ $? -eq 0 ]; then
    log "恢复测试通过: $TESTDIR"
    rm -rf "$TESTDIR"
else
    log "失败: 无法从备份恢复!"
    exit 1
fi

log "验证完成"

手动恢复演练(每季度做一次):

# 模拟灾难:把备份恢复到临时位置
rsync -a /backup/games/20261013/ /tmp/restore-test/

# 检查文件完整性、权限、大小
ls -la /tmp/restore-test/palworld/server/Pal/Saved/

# 清理
rm -rf /tmp/restore-test/

真出事时你是想不起来的——提前演练过,恢复就是肌肉记忆。

七、常见问题

Q:--delete 会不会把源上误删的也删了备份?
会,所以这是「镜像同步」语义。要防误删,用 --backup --backup-dir=删除的文件存这里,被删的文件先进备份目录而不是直接消失。

Q:rsync 慢,几个 G 传半天?
加 -z 压缩(存档类压缩比高);确认带宽没被占满;--bwlimit 别设太小;同机房内传最快。

Q:备份把游戏服搞卡了?
rsync 读大量小文件时 IO 高。加 --bwlimit、避开玩家高峰期、或者用 ionice -c3 降低 IO 优先级:

ionice -c3 rsync -a /opt/games/ /backup/games/

Q:硬链接方案,改了一个文件,所有历史版本都变?
不会。rsync 检测到文件变化会复制新文件并断开硬链接,历史版本保持原样。这正是硬链接方案精妙的地方。

Q:备份要加密吗?
传公网必须加密(走 SSH 的 rsync 本身就是加密的;传对象存储用 gpg 或服务端加密)。存本地的敏感数据也建议加密,硬盘丢了数据不泄露。

八、备份策略速查表

数据类型频率保留异地
游戏服存档每天 1–2 次7 天日备 + 4 周备每周外传
网站数据库每天14 天每周外传
网站文件每周4 周每月外传
配置文件每次改动后永久(进 Git)Git 远程
整机快照每周3–4 份看厂商支持

最终建议:本地增量备份(防手滑)+ 每周对象存储外传(防灾难)+ 每季度恢复演练(防备份失效)。三件事做到,数据安全就真的闭环了。

更多运维教程见财富云计算知识库:crontab 计划任务、备份策略、系统重装、日志管理全系列。需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,支持快照。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:服务器端口安全:最小化开放原则与攻击面管理
  2. 下一篇:日志集中管理与 journald 实战:查日志、防撑爆磁盘
发表评论 13