首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有fsync()的rename()安全吗?

没有fsync()的rename()安全吗?
EN

Stack Overflow用户
提问于 2011-09-15 15:03:29
回答 3查看 11.5K关注 0票数 35

在不首先调用rename(tmppath, path)的情况下调用fsync(tmppath_fd)安全吗?

我希望路径始终指向完整的文件。我主要关心的是Ext4。在所有未来的Linux内核版本中,rename()是否都是安全的?

Python中的一个用法示例:

代码语言:javascript
复制
def store_atomically(path, data):
    tmppath = path + ".tmp"
    output = open(tmppath, "wb")
    output.write(data)

    output.flush()
    os.fsync(output.fileno())  # The needed fsync().
    output.close()
    os.rename(tmppath, path)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-15 15:09:14

不是的。

看看libeatmydata,这个演示文稿:

吃我的数据:每个人都是如何搞错文件IO的

http://www.oscon.com/oscon2008/public/schedule/detail/3172

来自MySql的斯图尔特·史密斯著。

如果它离线/不可用,我会保存它的副本:

  • 视频这里
  • 演示文稿 (幻灯片的在线版本)
票数 34
EN

Stack Overflow用户

发布于 2016-12-28 13:06:46

来自ext4文档

代码语言:javascript
复制
When mounting an ext4 filesystem, the following option are accepted:
(*) == default

auto_da_alloc(*)    Many broken applications don't use fsync() when 
noauto_da_alloc     replacing existing files via patterns such as
                    fd = open("foo.new")/write(fd,..)/close(fd)/
                    rename("foo.new", "foo"), or worse yet,
                    fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
                    If auto_da_alloc is enabled, ext4 will detect
                    the replace-via-rename and replace-via-truncate
                    patterns and force that any delayed allocation
                    blocks are allocated such that at the next
                    journal commit, in the default data=ordered
                    mode, the data blocks of the new file are forced
                    to disk before the rename() operation is
                    committed.  This provides roughly the same level
                    of guarantees as ext3, and avoids the
                    "zero-length" problem that can happen when a
                    system crashes before the delayed allocation
                    blocks are forced to disk.

从“损坏的应用程序”的用词判断,ext4开发人员肯定认为它是不好的做法,但在实践中,它被广泛使用,以至于在ext4本身中得到了修补。

因此,如果您的使用符合模式,您应该是安全的。

如果不是,我建议您进一步调查,而不是为了安全起见到处插入fsync。这可能不是一个好主意,因为fsync可能是ext3 (朗读)的主要性能打击。

另一方面,在非日志文件系统上,在重命名之前进行刷新是进行替换的正确方法。也许这就是为什么ext4最初预期程序中会出现这种行为,auto_da_alloc选项后来被添加为一个修复程序。此外,用于写回(非日记)模式的 ext3修补程序试图通过在重命名上异步刷新以减少数据丢失的可能性来帮助那些粗心的程序。

您可以阅读更多关于ext4 problem 这里的内容。

票数 3
EN

Stack Overflow用户

发布于 2011-09-15 16:02:37

如果您只关心ext4而不关心ext3,那么在重命名之前,我建议在新文件上使用fsync。ext4上的fsync性能似乎比在ext3上要好得多,而且没有很长的延迟。或者可能是因为写回是默认模式(至少在我的Linux系统上)。

如果您只关心文件是完整的,而不是目录中命名的文件,那么您只需要对新文件进行fsync。也不需要对目录进行同步,因为它将指向具有完整数据的新文件或旧文件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7433057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档