主要观点:作者多年研究fsync()
并带来 OpenZFS 相关成果,近日看到 CouchDB 关于fsync()
防止数据损坏的文章,其中在打开数据库时进行额外fsync()
的做法引发疑问,作者深入探讨fsync()
的耐久性和顺序性保证,认为fsync(fd)
成功时保证该文件描述符之前的写操作已持久化,失败时之后的写操作状态未知,还分析了open()
后fsync()
可能奏效的原因及潜在问题,最后总结对于可移植程序fsync()
仅能保证同一文件描述符的写操作,且不涉及系统其他地方的 I/O。
关键信息:
- 不同文件描述符的
fsync()
互不影响,仅保证对应文件描述符的写操作持久化。 fsync()
的描述在 POSIX 中很模糊,对数据状态和错误处理未明确规定。- CouchDB 打开数据库时的额外
fsync()
引发对fsync()
行为的思考。 - 程序崩溃后
open()
再fsync()
可能因页面缓存等原因看似成功但实际数据状态未知。
重要细节: - POSIX 对
fsync()
的定义仅两段,第一段关于耐久性,第二段关于顺序性,且都很模糊。 - 不同操作系统对
fsync()
错误处理方式不同。 - 以 OpenZFS 为例说明
fsync()
可能会刷新底层对象的未完成写操作。 - Linux 和 ext4 对页面写失败的处理方式特殊。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。