Linux 自动化备份与恢复方案

5次阅读

rsync 增量备份需用 -a 和 –delete 实现真正同步,规避 noatime/fat 权限错误、并发冲突、空间不足及恢复误操作;脚本须加 set -e、flock、空间检查、带时间戳日志;恢复要隔离验证再原子切换;定时任务需错峰、环境配置与日志轮转。

Linux 自动化备份与恢复方案

rsync 做增量备份,别直接上 cp -r

全量复制看着省事,但磁盘和时间都浪费在重复文件上。真正靠谱的自动化备份,核心是 rsync 的增量同步能力——它只传变化的部分,还能保留权限、软链、修改时间。

常见错误现象:rsync: failed to set times on "xxx": Operation not permitted,多因目标文件系统不支持 atime/mtime(比如挂载了 noatime 或是 FAT/exFAT 分区);还有人忽略 --delete 导致备份目录越积越多,实际已失效。

  • 必须加 -a(归档模式),等价于 -rlptgoD,不带它就丢权限、丢时间戳、丢软链
  • --delete 才算真正“同步”,否则源删了文件,备份里还留着,恢复时会出错
  • 如果目标是远程主机,用 rsync -avz --delete /data/ user@host:/backup/data/,注意末尾斜杠:/data/ 表示同步内容,/data 表示同步目录本身
  • 避免在 NFS 或 CifS 挂载点上直接跑 rsync --delete,部分挂载选项会导致删除失败且无提示

备份脚本里必须加 set -e 和锁机制

没人盯着的定时任务,一旦中间出错(比如磁盘满、网络断、权限不足),后续步骤照常执行,结果就是生成一个“看似成功、实则残缺”的备份。更糟的是多个备份任务并发,rsync 写同一目标路径可能损坏快照。

使用场景:每天凌晨 2 点通过 cron 触发,或手动运行调试时也得防误操作。

  • 脚本开头加 set -e,任何命令非零退出立即终止,不继续往下走
  • flock 防并发:flock -n /tmp/backup.lock -c "rsync -a --delete /src/ /dst/",加 -n 是非阻塞,抢不到锁直接退出,比卡住强
  • 备份前检查空间:df -B1 /backup | awk 'NR==2 {if ($5+0 > 90) exit 1}',超 90% 使用率就中止
  • 别把日志重定向到 /var/log/backup.log 就完事,要加时间戳和退出码:rsync ... 2>&1 | tee /var/log/backup-$(date +%Y%m%d).log

恢复时别直接 rsync -a 回原目录

恢复不是备份的逆向操作。直接往生产目录里覆盖,万一路径写反、目标选错,几秒内就能让服务瘫痪。真正的恢复流程必须隔离、验证、再切换。

参数差异:rsync -a 默认保留所有元数据,但恢复时你往往不需要保留原始的属主(比如备份是从 root 备的,恢复到测试机不该强制 chown 成 root)。

  • 先恢复到临时目录:rsync -a --numeric-ids /backup/latest/ /tmp/restore-test/--numeric-ids 避免因用户 ID 不一致导致属主错乱
  • 进临时目录做抽样验证:ls -lR | head -20find . -type f -size +1M | head -5 | xargs sha256sum,确认关键文件存在且未损坏
  • diff -r 对比源备份和临时目录(小数据量可用),大数据量改用 rsync -avn 模拟同步,看有没有漏文件
  • 确认无误后,用 mv 替换(原子操作),而不是 rsync --delete 往原目录硬刷

systemd 定时器比 cron 更可靠,但得处理日志轮转

cron 启动的脚本默认没有完整环境变量,$PATH 可能不含 /usr/local/bin,导致自定义工具找不到;systemd 虽然启动干净,但默认日志无限增长,几个月后 journald 占满根分区。

性能影响:频繁触发的备份任务若没设 RandomizedDelaySec,所有机器会在整点集中 IO,可能压垮 NAS 或备份服务器。

  • 在 timer unit 里加 RandomizedDelaySec=300,让每台机器在 ±5 分钟内随机触发,错峰 IO
  • service unit 中显式声明环境:Environment=PATH=/usr/local/bin:/usr/bin:/bin
  • 日志不能只靠 journalctl -u backup.service 查,得配 logrotate 管理 /var/log/backup-*.log,否则 journald 日志撑爆磁盘时,连 systemctl status 都可能失败
  • 别信 “systemd 自带依赖管理” 就不写判断——比如恢复脚本仍需检查 /backup/latest 是否存在,systemd 不会替你校验业务逻辑

最易被忽略的点:备份路径里的 latest 是软链,指向某次时间戳命名的目录,但没人定期清理旧快照。一个没设上限的备份策略,半年后磁盘告警,查发现是 87 个 2024010120240630 的目录占满了空间——自动化的前提是明确保留策略,而不是“自动做所有事”。

text=ZqhQzanResources