登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

rsync partial-dir 怎么保留中断的大文件传输

来源:17golang原创

时间:2026-10-06 19:39:49 294浏览 收藏

用 --partial-dir=.rsync-partial 就能把中断的大文件保留在接收端的独立目录里。传输恢复时,重跑相同的 rsync 命令;rsync 会把该目录中的部分文件作为 delta 计算基础,完成后再删除对应的 partial 文件。

--partial-dir 会自动启用 --partial。相对路径最省心:它跟随各目标目录创建,不会把半成品直接暴露成最终文件名。

官方手册:https://download.samba.org/pub/rsync/rsync.1

问题:默认中断后为什么找不到半成品

rsync 默认会在传输中断时删除未完成文件。对于几十 GB 的镜像、备份包或归档文件,这意味着下次执行可能重新发送大量数据。--partial 会保留部分文件,而 --partial-dir=DIR 在此基础上把半成品放进指定目录,不让它占用最终文件路径。

这个方案解决的是“保留并复用已接收数据”,不是像 HTTP Range 那样简单从某个字节继续。再次运行时,rsync 仍会检查源和目标,并利用 delta-transfer 算法判断哪些块可以从 partial 文件复用。

最小配方:使用目标目录内的相对缓存

# 推送目录内容,并在接收端每个目标目录中保留中断数据
rsync -a --info=progress2 --partial-dir=.rsync-partial \
  /data/archive/ backup@example:/srv/archive/

# 网络恢复后重跑同一条命令,rsync 会复用可用的 partial 数据
rsync -a --info=progress2 --partial-dir=.rsync-partial \
  /data/archive/ backup@example:/srv/archive/

命令中的源路径以斜杠结尾,表示复制 /data/archive/ 里面的内容,而不是再创建一层 archive 目录。相对的 .rsync-partial 会按需出现在接收端目标文件所在目录下;rsync 能创建最后一级目录,但不会替你创建更深路径的所有父目录。

rsync 发送端、远程传输、接收端目标树、partial 目录和最终文件的静态关系图
图1:partial 文件位于接收端目标树中的独立目录,并与最终文件保持分离;这是静态结构图,不是终端截图。

如果传输再次中断,partial 文件仍留在目录中。成功传完后,rsync 将最终内容放到目标文件位置,并删除已经完成使命的 partial 文件;使用相对路径时,空的 partial 目录也会被清理。

关键选项怎么配

写法作用适合情况
--partial保留未完成文件只关心续传,不介意半成品所在位置
--partial-dir=.rsync-partial保留到独立目录,并隐含启用 partial大文件同步的推荐起点
-P等价于 --partial --progress交互式长传输,需要单文件进度
--info=progress2显示整个传输的整体进度文件多,希望少滚屏

-P 本身不会指定独立 partial 目录。如果希望短命令同时使用独立目录,可以设置环境变量,但要记住 RSYNC_PARTIAL_DIR 只决定 partial 的位置,不会单独启用保留行为。

# 环境变量只指定目录,-P 负责启用 --partial 并显示进度
export RSYNC_PARTIAL_DIR='.rsync-partial'
rsync -aP /data/archive/ backup@example:/srv/archive/

# 脚本结束后清理变量,避免影响同一 shell 中的其他 rsync 任务
unset RSYNC_PARTIAL_DIR

变体:什么时候用绝对 partial 目录

绝对路径适合管理员专门划出的工作区,例如接收端有独立高速盘,希望 partial 数据集中存放。此时目录不会像相对路径那样随空目录自动删除,需要自行管理容量、权限和过期文件。

# 接收端预先创建专用目录,并限制为当前同步用户可读写
ssh backup@example 'install -d -m 700 /srv/rsync-partials/job-a'

# 使用本次任务独享的绝对 partial 目录,避免多个任务混用
rsync -a --info=progress2 \
  --partial-dir=/srv/rsync-partials/job-a \
  /data/archive/ backup@example:/srv/archive/

不要把 /tmp 当作共享 partial 目录。官方手册明确提醒,该目录不能由其他用户写入,否则存在安全风险。多条同步任务也应使用不同目录,避免同名文件和清理策略互相影响。

兼容坑:这些选项会让续传失效或变味

rsync partial-dir、partial、P、whole-file、inplace 与删除规则的静态兼容关系图
图2:partial-dir 与相关选项的静态兼容关系;重点看冲突区和清理区,这不是命令执行流程。
  • --whole-file:禁用 delta-transfer。发现 partial-dir 文件时会将其移除,无法用它加速本次更新。两个本地路径之间复制时该模式通常默认启用。
  • --inplace:直接改写最终目标文件,与 --partial-dir 冲突。它还会让中断时的最终文件处于半更新状态,不适合作为本文配方的替代品。
  • 删除顺序:相对 partial-dir 会自动加入可消失的排除规则,但自定义 filter 可能改变效果。需要清理残留时优先研究 --delete-after;过早使用 --delete-before 或 --delete-during 可能删掉本次本可复用的 partial 数据。
  • 磁盘空间:目标旧文件与 partial 文件可能同时存在。大文件更新前要给接收端预留足够空间,不能只看待传输文件的最终大小。
  • 版本差异:双方 rsync 至少为 3.2.0 时,恢复 partial-dir 文件可直接原地更新,减少额外临时副本;旧版本仍能使用该选项,但空间行为可能不同。

完整片段:适合脚本和定时任务

#!/usr/bin/env bash
set -euo pipefail  # 任一命令失败就退出,避免脚本误报成功

SOURCE='/data/archive/'
DESTINATION='backup@example:/srv/archive/'
PARTIAL_DIR='.rsync-partial'

# 相对 partial 目录跟随目标树,整体进度适合日志收集
rsync \
  --archive \
  --human-readable \
  --info=progress2 \
  --partial-dir="${PARTIAL_DIR}" \
  --timeout=300 \
  "${SOURCE}" \
  "${DESTINATION}"

# rsync 返回 0 才说明本轮传输已正常完成
printf '%s\n' 'rsync transfer completed'

脚本被网络中断、超时或人工停止后,不要改源路径层级、目标目录或 partial-dir 名称,直接重新执行。若源文件已经改变,rsync 会重新评估差异,不能把旧 partial 文件当成绝对可靠的字节断点。

结果检查清单

  • 中断后,接收端是否出现了 .rsync-partial 和对应半成品?
  • 重跑命令时,源、目标和 --partial-dir 是否保持一致?
  • 命令里是否意外带了 --whole-file 或 --inplace?
  • partial 目录是否只有同步账号和管理员可写?
  • 接收端是否有同时容纳旧目标与 partial 数据的空间?

相关问题

--partial-dir 还需要再写 --partial 吗?不需要,前者会隐含启用后者。

-P 能替代 --partial-dir 吗?不能完全替代。-P 保留 partial 并显示进度,但不指定独立目录。

本地复制为什么没有利用 partial 文件?两个本地路径之间通常启用 whole-file,它会绕过 delta-transfer;先确认该模式是否符合你的场景。

可以把多个同步任务都指向同一个绝对 partial 目录吗?不建议。按任务分目录更容易避免同名冲突、权限混乱和误清理。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>