Perl 34:rename 成功不代表断电后文件一定还在
上篇的临时文件和 rename 可以将“旧的完整报表”切换成“新的完整报表”。在本机 Linux 同目录写法下,测试中两个协作写进程结束后,目标字节恰好是两个金标中的一个,而不是混合半截。把目标换成目录,rename 失败,旧有效目标仍在。这说明本次测试覆盖了通常运行中的替换边界,不说明断电后的磁盘状态。
close 负责 Perl 层的写出与关闭错误检查;它不等同于对临时文件和所在目录都成功做了 fsync。要论证“断电后仍可恢复”,至少需要文件数据和 rename 所在目录元数据的同步协议,并有支持该协议的文件系统与真实故障注入。这里没有执行系统断电、重启后的校验,也没有实现那套同步协议,断电持久化 NOT_RUN。官方 pod/perlfunc.pod 对 rename 明确说平台行为差异很大,不能把 Linux 上的一次成功推广为通用语义。
图:正常替换与断电恢复的证据边界
1 | |
练习:加一个 sleep(1) 再返回 SAVED,能将程序级替换升级为耐断电保证吗?不能;等待时长不是同步协议。正例、rename 失败反例和真实未测项记录在 examples/perl-language/evidence/32-39.md;参考冻结 Perl 5.38.2 pod/perlfunc.pod 的 rename、pod/perlport.pod。
组合错误路径同样不能用“清理成功”替代“发布成功”。修正后的 Report.pm 先保存主错误,再尝试 unlink 临时文件与关闭锁句柄;只有前面所有发布步骤都成功时,锁关闭失败才成为主错误。这样报告可以同时写出“不能替换报表”和“不能清理临时文件”两类事实,但不会把 cleanup 失败伪装成发布阶段的根因。该边界来自本工程测试与 Perl close/rename 返回值,不涉及断电后目录项持久化。








