DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

rsync 报 file has vanished:退出码 24 与动态源文件

rsync 返回 24 并提示 file has vanished 时,确认动态源文件是否属于必须保留的数据;分开保存退出状态与日志,避免过滤管道掩盖其他错误。

cron 里运行 rsync 同步网站目录,参数已经用了 -q,仍收到 file has vanished 的提示。包装脚本把退出码 24 改成 0 后,提示邮件也未必消失:退出状态和写到终端的诊断信息是两个通道,改变前者不会撤回已经输出的文本。

先确认消失的是哪类源文件。rsync 将退出码 24 定义为源文件消失造成的部分传输;缓存生成后又被应用清理,可能符合这条路径。它不代表所有业务数据都已完整复制,更不代表数据库或正在更新的目录取得了某一时刻的一致副本。

记录实际状态,确认是源文件在传输期间消失

示例诊断可能类似:

file has vanished: "/srv/example-site/cache/page-fragment.tmp"
rsync warning: some files vanished before they could be transferred (code 24)

路径和输出格式会随环境不同而变化。检查 rsync 建立文件列表之后,该路径是否被应用删除、重命名或替换;同时查看当时的缓存清理、部署和轮换时间。如今文件不存在,只能说明当前状态,不能单凭这一点还原它消失的时刻。

保留本次同步的源、目标、选项、完整日志和实际退出码。若是权限错误、读取错误或网络问题,应按对应信息继续检查,不能都归入“缓存刚好消失”。退出码 23 表示因错误造成的部分传输,与 24 不同。

-q 抑制的是普通进度和非错误信息,不能用多写几个 q 保证诊断不再输出。cron 是否发邮件取决于运行环境;在会把任务输出作为通知内容的配置中,返回 0 仍可能产生通知。

业务需要完整副本时,稳定源再复制

如果丢失的是应当保留的上传文件、发布产物或其他业务内容,不能把 24 统一降为成功。需要找出哪个写入或清理流程与复制重叠,并选择适合数据的处理方式:安排一致性快照,按应用要求短暂停写,或从已经完成且不会继续变化的导出目录复制。

数据库文件尤其不能仅靠对活跃目录反复 rsync 就承诺可恢复,应使用数据库支持的备份或一致性处理。快照也要考虑应用事务是否已处于可恢复状态;文件系统时间点一致不自动等于业务一致。

如果确定是可重新生成、业务无需备份的临时缓存,可以审核排除规则。但要先确认缓存与必须保留的数据是否混在同一路径,避免把整个目录排除后连业务文件一起遗漏。排除属于改变备份范围,应记录这一决定,不能只为了让错误消息消失而添加。

即使第二轮退出码变成 0,也不能证明第一轮与第二轮的文件组合是一个完整时间点。成功标准应与备份要求对应,例如稳定的导出清单及内容完整,而不是重试次数足够多。

将日志与退出码分开保留

包装脚本可以把完整输出保存到日志,再交给告警流程按状态和已审核的文件类型决定通知。下面是 Bash 局部示例:src、dst 和 run_log 均已设置为审核过的目录及本次独立日志文件,日志父目录已存在、可写,且日志路径不在同步树中。

if rsync -a -- "$src/" "$dst/" > "$run_log" 2>&1; then
    status=0
else
    status=$?
fi

printf 'rsync exit status: %s; log: %s\n' "$status" "$run_log" >&2
exit "$status"

这段同步会写入目标并可能覆盖同名文件,正式使用前应有目标恢复方案,先带 -n 审核范围。示例没有加入删除选项,也没有把 24 自动当成成功。日志应限制读取权限并有保留、轮换规则,其中可能包含文件名和业务路径。

退出状态在 else 中立即保存,不要在执行 echo、grep 或其他命令后才取 $?。也不要将 rsync 直接接到 grep -v vanished 后,用默认管道的最后一段状态判断同步成功:此时看到的可能只是 grep 的结果,其他 rsync 错误反而被掩盖。

如果业务明确允许特定临时文件消失,可以让告警层将这类运行记为已知警告,保留原始状态和全量日志,再减少重复通知。仅凭状态 24 无法说明消失的都是已批准的缓存,仍需审核本次涉及的路径。把全部标准错误丢到 /dev/null,会同时失去权限、连接和读取错误的证据。

几个名字相似的选项不能解决这条竞争

--ignore-missing-args 处理的是显式源参数或 --files-from 条目在最初处理时就不存在的情况,不会屏蔽已经找到、后来消失的文件。

--ignore-errors 主要影响发生 I/O 错误时是否继续目标端删除,不是“忽略所有错误”的开关。把它加到带删除的备份任务中可能扩大数据损失,不能拿它处理 vanished 提示。

调整日志或排除规则前保存原脚本、参数和备份范围。修复后确认完整日志仍在、非预期错误仍能进入告警,且需要保留的文件确实可恢复。回退脚本不会还原目标端已经覆盖的内容,数据恢复仍需依赖同步前的备份或其他保留副本。