侧边栏壁纸
博主头像
一笑痕

人生若只如初见,
是可喜亦或者是可悲?

  • 累计撰写 270 篇文章
  • 累计收到 7 条评论

进程退出后能读到文件,不等于数据已持久化

2026-11-14 / 0 评论 / 14 阅读

进程退出后能读到文件,不等于数据已持久化

子进程用 os.write 写了 4096 字节,随后直接调用 os._exit(9)。父进程等它退出,再打开文件查询长度,结果仍是 4096。这个结果看起来像是「没调 fsync 也写稳了」,实际只能说明这次进程结束后,同一台机器上的父进程仍查到文件长度为 4096。

记录来自 tools/verify-fsync.py 和 tools/verify-fsync.log。脚本在 macOS 26.2、APFS 上创建临时目录,分三种收尾方式写同样的内容,再由父进程用新文件描述符查询文件长度。三种模式的日志都是 4096 字节。它没有模拟掉电,也没有验证存储设备断电后的状态。读回函数使用 os.fstat 查询大小,没有把文件正文读出后逐字节比较,因此这里的 4096 指长度,不代表内容校验通过。

为什么被杀后还能读到?

os._exit(9) 让子进程立即退出,不执行 Python 的清理流程。实验里,写入走的是 os.write,不是 Python 文件对象的缓冲写入;内核已经接收这次写入。进程消失后,内核和文件系统仍在运行,父进程也能继续访问同一文件系统。进程被杀不等于机器掉电,更不等于存储设备突然停止工作。

日志原样记录了三种结果:

close        -> 读回 4096 字节
fsync+close  -> 读回 4096 字节
kill         -> 读回 4096 字节

这里观察的是文件长度。父进程新开文件描述符后用 fstat 查到 4096 字节,说明这次实验结束后文件仍呈现该长度;它没有在重启或断电后重新检查内容,也没有校验设备缓存和文件系统的恢复行为。读回成功不是持久性的同义词。

close 和 fsync 分别怎么参与?

脚本里这两个操作的位置是明确的。close 模式调用 os.close(fd);fsync+close 模式先调用 os.fsync(fd),再关闭描述符;kill 模式调用 os._exit(9),脚本注释说明它不再经过后续的 close 和 fsync。日志只记录父进程读到的长度,没有记录 fsync 的返回结果,也没有检查 waitpid 返回的子进程状态。

这个细节限制了能下的判断。看到三种模式都读回 4096 字节,可以报告读回长度相同;不能据此断言三种收尾等价。脚本也没有比较文件的 4096 个字节是否逐字相同,虽然三种模式都由同一段代码写入 x,日志仍然只证明了长度。若要把字节内容也纳入结论,读取端应实际取出内容并比较,而不是只看 fstat().st_size。

脚本直接调用 os.write,没有覆盖 Python 文件对象的缓冲路径,也没有测 flush。因此从这份结果不能推出「调用 flush 就足够」或「fsync 一定覆盖了尚未提交给操作系统的缓冲内容」。这两种路径不在现有实验范围内。读脚本时看到一个 API 名,不等于验证过它所有关联行为。

读回验证能回答什么?

它适合确认一条较窄的问题:进程按某种路径退出后,另一个进程用新描述符查询文件,能否观察到预期长度。若任务关心「写入进程非正常退出后,文件长度是否仍可查询」,在隔离目录里复现这条路径,比只检查进程退出码更直接。真正的业务文件不适合拿来做强制退出试验,脚本的临时目录让验证范围保持在临时文件内。

它回答不了掉电或内核崩溃时的数据状态。脚本没有让机器重启,也没有模拟存储设备失去供电;所以 fsync 相关结果只限于这次进程运行期间的读回。若文章要讨论更强的故障保证,需要另一组针对目标平台的测试,不能从这三行长度输出外推。只观察进程退出后的读回,容易把「当前可见」误写成「故障后仍持久」。

脚本还没有在重启后重读文件,也没有比较文件内容或检查子进程状态。它用 fstat 取长度,把三种路径都归纳成 4096 字节。若要研究内容一致性,应让父进程读取完整字节并比较;若要研究进程退出状态,则需检查 waitpid 返回值。两者都不是现有日志给出的结论。

记录里最适合保留的是测试条件与结果:三种收尾方式,每个分支写入的 4096 字节,以及父进程读回的文件长度。它们足以复核「子进程退出后还能读取到预期长度」这件事。若目标改为核对文件内容是否一致,脚本需新增相应断言。断电后的结果更要另行测试,不能让同一份日志代替。

我会把这份脚本当作进程退出后的可见性测试,不当作掉电持久性测试。它得到的结论很窄,却有用:本机这三种收尾方式都能让父进程读回 4096 字节。想证明更强的保证,测试也必须覆盖更强的故障条件。

配图:Jacek Halicki,《2019 Rozebrane dyski twarde》,CC BY-SA 4.0,裁切调整。

    🤞 分享