把 tar 与 rsync 用准
一句话总结
tar 是保存某个时间点的工具,rsync 是对齐状态的工具。在备份设计中,两者不是竞争关系,而是分工协作。
为什么需要它
“备份该用 tar 还是 rsync?”没有固定答案。需要按代保存归档时用 tar,需要最新状态的副本时用 rsync。多数生产配置会两者都用。
如何运作
tar
tar -czf /backup/etc-$(date +%F).tar.gz --acls --xattrs --selinux --numeric-owner -C / etc
tar -tzf /backup/etc-2026-08-20.tar.gz | head
tar -xzf /backup/etc-2026-08-20.tar.gz -C /restore/
各选项的确切含义如下。
-c(创建)、-x(提取)、-t(列出)、-f(文件)是基本组合。- 压缩方式有
-z(gzip)、-j(bzip2)、-J(xz)、--zstd。 -C会在操作前切换目录。 为避免把绝对路径放进归档,必须使用它。tar -czf x.tgz /etc会把/etc/...放入归档,并在恢复时剥夺路径选择权。-p(保留权限)与--numeric-owner能在恢复时准确还原权限和所有者。--acls、--xattrs、--selinux分别包含 ACL、扩展属性和 SELinux 上下文。在使用 SELinux 的系统中,不带这些选项恢复,服务可能无法启动。--one-file-system不会跨入其他文件系统,可防止意外把挂载的网络存储也一并打包。--listed-incremental=<스냅샷파일>用于管理增量备份。快照文件本身保存状态,因此也必须一起保管。--strip-components=N会在恢复时移除前面的路径组件。
恢复前务必检查路径。 直接用 -C / 解包会覆盖当前系统配置。安全做法是先解压到临时路径,检查内容后只移动需要的文件。
mkdir -p /restore/etc-check
tar -xzf /backup/etc-2026-08-20.tar.gz -C /restore/etc-check
diff -r /restore/etc-check/etc/nginx /etc/nginx | head -40
GNU tar 与 BSD tar(bsdtar) 的选项处理及部分行为不同。典型问题是在 macOS 创建的归档于 Linux 解包时,会出现扩展属性相关文件。备份脚本必须在实际生产发行版上验证。
rsync
rsync -aHAX --numeric-ids --delete --dry-run /srv/data/ backup@10.0.9.2:/backup/prod/data/
-a等同于-rlptgoD,但不包含 ACL(-A)、扩展属性(-X)和硬链接(-H)。--numeric-ids使用数字 UID/GID 而不是名称,可避免恢复到另一系统时所有者被错误映射。-i(itemize)逐行显示将发生的变更。应养成和-n一起使用的习惯。- 使用
--bwlimit和ionice -c 3 nice -n 19可降低生产负载。
利用硬链接可以低成本创建多代备份。
rsync -aHAX --numeric-ids --delete --link-dest=/backup/prod/daily.1 /srv/data/ /backup/prod/daily.0/
每一代看起来都是完整快照,但磁盘只保存变更部分。
两种工具的分工
| 需求 | 工具 |
|---|---|
| 单个特定时间点归档文件 | tar |
| 传往异地的单一对象 | tar(+ 压缩、加密) |
| 维护最新状态副本 | rsync |
| 低成本保存多代快照 | rsync --link-dest |
| 节省带宽进行远程同步 | rsync(增量传输) |
现场常见情况
--delete 事故。 如果源目录为空或挂载已断开,执行后会删除目标端全部数据。这类事故在实践中反复发生,必须设置保护条件。
用不了解硬链接的工具复制多代备份,容量变成三倍。 -H 不包含在 -a 中。
避免传输过程中出现偏差
tar 和 rsync 看似简单,但传输大数据时有一些地方会悄悄出错。
直接归档正在变化的文件会损坏。 如果文件在读取过程中改变,tar 会发出 file changed as we read it 警告,然后带着损坏的该文件继续执行。如果不能停服,就创建快照(LVM、文件系统或云卷)并归档快照。
保留硬链接和稀疏文件。 不带选项传输时,硬链接会变成多个独立副本,容量可能成倍增长;稀疏区域会被零填充,体积暴增。
tar --numeric-owner --acls --xattrs --sparse -cf - /srv | zstd -T0 > srv.tar.zst
rsync -aHAX --sparse --numeric-ids /srv/ backup:/srv/
仅使用 -a 不会保留硬链接(H)、ACL(A)和扩展属性(X)。SELinux 标签包含在 -X 中。
让中断后的传输可以续传。 使用 --partial --append-verify,重启时就不必从头传输。单个大文件需要数天才能搬完时,差异尤其明显。
末尾有无斜杠含义不同。 rsync -a /src/ /dst/ 传输目录内容,而 rsync -a /src /dst/ 会创建 /dst/src。脚本中这一个字符经常导致路径多出一层。
删除前先人工查看。 --delete 会删除仅存在于目标端的内容。源路径写错时,可能清空整个目标端。
rsync -aHAX --delete --dry-run --itemize-changes /src/ /dst/ | head -50
验证必须是独立步骤。 rsync 在传输时使用校验和,但无法告诉你文件后来是否损坏。保存清单和哈希后,几个月后仍可验证。
find /srv -type f -print0 | sort -z | xargs -0 sha256sum > manifest.sha256
sha256sum -c manifest.sha256 --quiet
下一次实验要做什么
使用 tar 处理全量、增量、排除和分卷备份,再用 rsync 实践 dry-run、保护条件、多代备份和负载控制。两个实验最后都会验证结果。