在不首先调用rename(tmppath, path)的情况下调用fsync(tmppath_fd)安全吗?
我希望路径始终指向完整的文件。我主要关心的是Ext4。在所有未来的Linux内核版本中,rename()是否都是安全的?
Python中的一个用法示例:
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)发布于 2011-09-15 15:09:14
不是的。
看看libeatmydata,这个演示文稿:
吃我的数据:每个人都是如何搞错文件IO的
http://www.oscon.com/oscon2008/public/schedule/detail/3172
来自MySql的斯图尔特·史密斯著。
如果它离线/不可用,我会保存它的副本:
发布于 2016-12-28 13:06:46
来自ext4文档
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 这里的内容。
发布于 2011-09-15 16:02:37
如果您只关心ext4而不关心ext3,那么在重命名之前,我建议在新文件上使用fsync。ext4上的fsync性能似乎比在ext3上要好得多,而且没有很长的延迟。或者可能是因为写回是默认模式(至少在我的Linux系统上)。
如果您只关心文件是完整的,而不是目录中命名的文件,那么您只需要对新文件进行fsync。也不需要对目录进行同步,因为它将指向具有完整数据的新文件或旧文件。
https://stackoverflow.com/questions/7433057
复制相似问题