用 rsync 做增量备份:比全量拷贝省 90% 时间

举报
yd_292915714 发表于 2026/11/05 18:50:24 2026/11/05
【摘要】 rsync 增量备份实战:--link-dest 硬链接快照、参数逐个解释、四个常见坑,以及什么时候不该用 rsync。

用 rsync 做增量备份:比全量拷贝省 90% 时间

备份这件事,很多人第一版实现都是 cp -r 或者 tar 打包整个目录。数据量小的时候没问题,一旦目录到了几十 GB、几百万个小文件,每次全量拷贝既慢又占空间,磁盘 I/O 还会把线上服务拖慢。

rsync 解决的就是这个问题:它只传输变化的部分。这篇文章记录一套可以直接用的增量备份方案。

rsync 为什么快

rsync 的默认算法是「快速检查」:先比较文件大小和修改时间(mtime),两者都一致就跳过,不再读文件内容。这意味着对绝大多数场景,它根本不会去传输没变的文件。

如果需要更严格的校验,可以加 -c 参数让它计算校验和。代价是要把两边文件都读一遍,速度会慢很多,适合对数据完整性要求极高的场景。

另一个关键点是 rsync 的传输协议:即使文件变了,它也只传差异块,而不是整个文件。对大文件(数据库文件、日志归档)效果非常明显。

一条能用的命令

rsync -aHAX --delete --numeric-ids \
      --exclude='*.tmp' --exclude='cache/' \
      /data/ backup@192.0.2.10:/backup/data/

参数逐个说明:

  • -a 归档模式,等价于 -rlptgoD,保留权限、时间、软硬链接、属主属组
  • -H 保留硬链接。备份大量重复文件(比如 Docker 镜像层)时必须加,否则硬链接会被展开成独立文件,体积暴涨
  • -A 保留 ACL,-X 保留扩展属性。SELinux 环境或者用了 setfacl 的目录必须加
  • --delete 让目标端删除源端已删除的文件,保持严格镜像
  • --numeric-ids 按数字 UID/GID 同步,不查用户名。跨机器、容器环境里用户名对不上时,不加会把属主改错

--delete 是有风险的参数:如果源目录挂载失败变成空目录,rsync 会把备份也清空。稳妥做法是加 --delete-after(先传完再删)配合 --dry-run 先跑一遍看清单。

增量备份到不同日期目录

严格镜像只能保留最新一份,误删文件会被同步过去。要保留历史版本,可以用硬链接快照:

#!/bin/bash
set -euo pipefail
SRC=/data/
DEST=/backup/snapshots
TODAY=$(date +%Y-%m-%d)
LATEST=$(ls -1d "$DEST"/2* 2>/dev/null | tail -1)

mkdir -p "$DEST/$TODAY"
if [ -n "$LATEST" ]; then
    rsync -aHAX --numeric-ids --delete \
          --link-dest="$LATEST" "$SRC" "$DEST/$TODAY/"
else
    rsync -aHAX --numeric-ids "$SRC" "$DEST/$TODAY/"
fi

--link-dest 是关键:rsync 会把没变的文件硬链接到上一份快照,只有变化的文件才占新空间。这样每天的「全量快照」实际只多出增量部分的磁盘占用,但恢复时每个目录都是完整的、可直接拷回去的树。

实测一个 40 GB 的目录,首次备份 12 分钟,之后每天增量约 1 分钟,单日新增占用 200 MB 到 1 GB 不等。

常见坑

mtime 不可信会导致漏备份。 有些程序写完文件不改 mtime(或者被 touch 重置),rsync 会误判为未变化。这类目录要么加 -c,要么在备份前 touch 一下。

跨文件系统同步丢硬链接。 硬链接不能跨文件系统,如果目标盘和源盘不在同一个 fs 上,-H 会退化成复制。硬链接快照方案要求 $DEST 内部是同一个文件系统。

排除规则写错会漏文件。 --exclude='cache' 匹配任意层级的 cache,而 --exclude='/cache' 只匹配根目录下的。排除规则多的时候建议写成文件,用 --exclude-from=rules.txt 管理。

中断后重跑不需要特殊处理。 rsync 支持断点续传,--partial 会保留未完成的临时文件,重跑时接着传。不加这个参数的话,中断的大文件下次会从头开始。

什么时候不该用 rsync

rsync 适合「文件级」备份。数据库这类有自己事务日志的服务,直接同步数据文件可能拿到不一致的状态,正确做法是先做逻辑导出(mysqldump、pg_dump)或者用文件系统快照(LVM、ZFS、btrfs snapshot)再同步快照。

另外 rsync 是单线程的,超大目录(千万级 inode)扫描阶段会成为瓶颈。这种规模可以考虑 btrfs send/receive 或者分布式方案。

小结

rsync 的价值不在「能拷文件」,而在「只拷变化的、能保留元数据、能构造硬链接快照」。一套 --link-dest 的每日快照脚本大约 20 行,就能覆盖大部分中小规模备份需求,恢复时也不需要任何特殊工具,直接把目录拷回去即可。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。