打开()之后的 fsync()是一个精心设计的无操作

主要观点:作者多年研究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 对页面写失败的处理方式特殊。
阅读 8
0 条评论