当前位置:首页 > 文章列表 > 文章 > linux > Linux rsync --delete-after 的删除时机与回滚风险

Linux rsync --delete-after 的删除时机与回滚风险

来源:17golang原创 2026-11-01 10:20:41 0浏览 收藏

如果你把部署目录从源端同步到目标端,同时又希望目标端多出来的旧文件在本次传输结束后再清理,rsync --delete-after 就是针对这个时机的选项。它会隐含启用删除逻辑,把删除多余文件安排到传输完成之后;但它不是事务,也没有“失败后自动回滚”能力。源端清单、过滤规则或路径写错时,目标端仍可能在收尾阶段删除不该删除的文件。

官方地址:https://rsync.samba.org/

把 --delete-after 当成“延后执行删除”,不要当成“安全删除”。上线前先用同样的源端、目标端和过滤规则做预演;需要恢复能力时,额外准备 --backup-dir 或文件系统快照。

先看清 --delete-after 的删除时机

rsync 先根据源端构建文件清单,再传输新增或变化的对象。使用 --delete-after 时,目标端不在每个目录开始处理时立即清理,而是在传输完成后做一次删除阶段。这个安排适合“本次传输带来了新的目录级过滤文件,删除阶段需要使用它们”的场景。

它还有一个容易被忽略的代价:官方手册说明,--delete-after 会强制使用旧的非增量递归算法,需要一次性扫描传输涉及的文件。文件数量很大时,内存压力和文件清单构建时间可能明显高于默认的增量删除方式。

rsync delete-after 从源端文件清单到接收端删除阶段的静态结构说明图
图1:传输完成后才进入删除阶段的关系说明图,不是终端截图或运行证据。

从旧命令迁移到可预演命令

假设源端是发布目录,目标端是待切换目录。先用完全相同的参数做 dry-run,重点观察 *deleting 行以及源端路径是否符合预期:

# 中文说明:只预演删除清单,不改动目标端;正式命令需复用同一组参数。
rsync -a --delete-after --dry-run --itemize-changes \
  --backup --backup-dir=/srv/backup/release-2026-11-01 \
  /srv/release/ deploy@example:/srv/app/

上面的命令只预演,不改动目标端。代码块中的反斜杠用于续行;--itemize-changes 让变更类型更容易被日志捕获;--backup-dir 指定一个目标端备份目录,便于把被覆盖或删除的文件移出主目录。正式执行前,至少检查下面三件事:

  • 源端末尾的斜杠是否正确:/srv/release/ 表示同步目录内容,而不是再套一层 release 目录。
  • 目标端是否确实是接收端:命令方向写反时,删除风险会落到另一台机器。
  • 过滤文件、环境文件和备份目录是否被保护:不要把刚生成的备份目录再次纳入删除范围。

预演输出不等于回滚点。它只是按当前时刻计算出来的候选变化;如果源端在正式执行前变化,或者过滤规则来自动态的合并文件,最终删除列表也可能变化。

什么时候改用 --delete-delay

--delete-delay 也会尽量把删除动作放到传输后,但它在传输过程中记录待删除对象,随后统一执行删除。与 --delete-after 相比,它通常更适合保持增量递归的效率;代价是删除名单需要暂存,并且在特定文件数量或临时空间条件下可能回退到其他处理方式。

可以按下面的迁移表判断:

选择删除位置主要取舍适合的判断
--delete-before传输前先释放空间,但会拖延传输开始目标磁盘紧张且能接受先清理
--delete-during按目录增量处理通常更高效,但删除和更新交错目录规模大、无需等到最后清理
--delete-delay传输后集中处理兼顾延后删除和增量递归,需暂存删除名单希望减少误删窗口又不想强制旧递归
--delete-after传输完成后单独处理过滤文件对本次删除生效,但文件清单占用可能更高确实需要“新过滤文件先传过去,再决定删什么”
rsync 三种删除时机与备份和删除上限的静态对比说明图
图2:三种删除时机与安全护栏的概念对比图,属于原创结构图。

给不可逆删除加上回滚边界

rsync 的删除不是数据库事务。即使传输阶段看起来正常,收尾阶段仍可能受到源端目录被误清空、include/exclude 规则过宽、挂载点未就绪或参数方向错误的影响。实际发布可以组合以下护栏:

  1. 备份被覆盖和删除的对象。使用 --backup --backup-dir=/srv/backup/release-2026-11-01,并让备份目录位于同步目标之外或明确加入保护规则。
  2. 限制一次删除的数量。使用 --max-delete=50 作为异常保护;超过上限时,rsync 会跳过后续删除并以错误码结束,不能把它当成成功部署。
  3. 把删除日志单独留存。将 dry-run 和正式运行的 --itemize-changes 输出写入带批次号的日志,方便把删除对象与发布清单对应起来。
  4. 避免用 --ignore-errors 掩盖故障。官方文档默认在发送端检测到 I/O 错误时关闭目标端删除,这是保护机制;只有已经理解风险并有额外恢复手段时才考虑覆盖这个行为。

一个偏保守的正式命令可以这样写:

rsync -a --delete-after --itemize-changes \
  --backup --backup-dir=/srv/backup/release-2026-11-01 \
  --max-delete=50 \
  /srv/release/ deploy@example:/srv/app/ \
  | tee /var/log/rsync-release-2026-11-01.log

# 中文说明:先保留被覆盖或删除的目标文件,再把删除数量限制在 50 个以内。
# 中文说明:命令失败或触发上限时,应停止切换并检查日志,不要直接重跑同一条命令。

这里的备份目录只是文件级恢复手段,不等于整个系统快照。需要保证权限、磁盘空间和保留周期;如果发布目录还涉及数据库、软链接或挂载点,仍应使用与应用架构匹配的快照和回滚方案。

上线前的版本迁移清单

从不带删除、带默认增量删除或旧脚本中的 --delete-before 迁移到 --delete-after,建议按这个顺序收口:

  1. 记录 rsync 两端版本和目标目录的文件数量,确认是否能接受非增量递归的内存开销。
  2. 固定源端、目标端、末尾斜杠和过滤规则,先执行一次 --dry-run。
  3. 对比预演输出,确认待删除文件都在本次发布的淘汰清单内。
  4. 启用 --backup-dir 或文件系统快照,并验证恢复目录有足够空间。
  5. 设置 --max-delete,把异常退出、错误码和日志纳入发布平台的失败条件。
  6. 明确传输完成后的删除阶段由谁观察,避免脚本在删除时被超时或会话断开而无人处理。

最重要的变化不是把删除延后几秒,而是把“源端清单是否完整”和“目标端多余文件是否应该删除”拆成两个需要分别确认的决策。

常见问题

--delete-after 会不会自动回滚?

不会。它只改变删除时机;回滚要靠 --backup-dir、快照、版本化发布目录或其他外部恢复方案。

文件很多时一定要用 --delete-after 吗?

不一定。官方文档说明它会强制旧的非增量递归;如果只是希望最后再删除,可以优先评估 --delete-delay 的内存和临时空间特征。

为什么发送端有 I/O 错误却没有删除目标端文件?

这是 rsync 的默认保护行为,用来避免源端暂时的文件系统故障引发大范围删除。不要为了让脚本“继续完成”就直接加 --ignore-errors。

--max-delete=0 能不能当作正式发布?

它更适合用于只观察目标端多余对象的预演;如果要正式同步,应使用一个符合变更窗口的正数上限,并把触发上限视为失败信号。

参考:https://rsync.samba.org/ftp/rsync/rsync.html

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Linux dmesg --level 怎样筛选内核日志级别Linux dmesg --level 怎样筛选内核日志级别
上一篇
Linux dmesg --level 怎样筛选内核日志级别
Linux mount --bind 与 --rbind 的子挂载差异
下一篇
Linux mount --bind 与 --rbind 的子挂载差异
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    821次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    816次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    905次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    876次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    698次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码