Is file append atomic in UNIX?

2019-06-17 11:25发布

在一般情况下,我们能理所当然的,当我们从多个进程附加到文件在UNIX? 是否有可能丢失数据(一个过程覆盖对方的变化)? 是否有可能得到错位的数据? (例如,每道工序都追加每追加一行到一个日志文件,是有可能,两行得到错位?)如果追加不在上述意义上的原子,那么什么是确保相互排斥的最佳方式?

Answer 1:

那是PIPE_BUF'的大小下的写入被认为是原子的。 这应该是至少512个字节,但它很容易被较大的(linux下似乎有其设置为4096)。

这假设你在说所有完全POSIX兼容的组件。 举例来说,这是不是在NFS如此。

但是,假设你写信给你“O_APPEND”模式打开,并保持在“PIPE_BUF”字节的行(包括换行符)长的日志文件,你应该能够有多个作家到日志文件中没有任何损坏问题。 所有的中断会前或写入之后到达,而不是在中间。 如果你希望文件以诚信求生存重新启动,你还需要调用fsync(2)每次写入之后,但是这是可怕的性能。

澄清 :阅读意见和奥兹所罗门的回答 。 我不知道该O_APPEND应该有PIPE_BUF大小的原子。 这是完全可能的,这是由于Linux是如何实现write()也可能是由于底层文件系统的块大小。



Answer 2:

编辑:更新August 2017最新的Windows结果。

我想给你的链接的答案,测试代码和结果提出了笔者Boost.AFIO它实现异步文件系统和文件I / O C ++库。

首先,O_APPEND或Windows上的等效FILE_APPEND_DATA意味着最大程度文件(文件“长度”)的增量是并发作家下原子 。 这是通过POSIX,和Linux,FreeBSD的,OS X和Windows保证所有正确实现它。 桑巴也正确地实现它,V5并没有因为它缺少的线制式能力以原子追加NFS之前。 所以,如果你打开你的文件只追加-, 并发写入不再与 NFS,除非涉及撕裂彼此在任何主要的操作系统

然而并发读取到原子追加可能会看到这取决于OS撕裂写入,文件系统,并且你开什么旗的文件-文件的最大程度上是原子的增加,但写入相对于知名度,可以读取或可能不会是原子的。 下面是旗帜,操作系统和文件系统的快速摘要:


没有O_DIRECT / FILE_FLAG_NO_BUFFERING:

微软的Windows 10,NTFS:更新原子= 1个字节,直到并包括10.0.10240,从10.0.14393至少1MB,可能无限(*)。

更新原子= 1个字节:Linux的ext4的4.2.6

FreeBSD的10.2 ZFS:更新原子=至少为1MB,可能无限(*)

O_DIRECT / FILE_FLAG_NO_BUFFERING:

微软的Windows 10,NTFS:更新原子=直到并包括10.0.10240最多只有页对齐的4096个字节,否则512字节,如果FILE_FLAG_WRITE_THROUGH关闭,其他64个字节。 请注意,这个原子可能的PCIe DMA的功能,而不是设计。由于10.0.14393,至少1MB,可能无限(*)。

更新原子=至少为1MB,可能无限(*):Linux的ext4的4.2.6。 需要注意的是ext4的早期Linux版本绝对没有超过4096个字节,XFS肯定曾经有过自定义锁,但它看起来像最近的Linux终于解决了这个问题。

FreeBSD的10.2 ZFS:更新原子=至少为1MB,可能无限(*)


你可以看到在原始实证检验结果https://github.com/ned14/afio/tree/master/programs/fs-probe 。 请注意我们的测试只在512倍字节的倍数撕裂的偏移,所以我不能说,如果一个512字节扇区的部分更新会读 - 修改 - 写周期中撕裂。

因此,要回答的任择议定书的问题,O_APPEND写不会互相干扰,但读取并发往O_APPEND写入可能会看到撕裂写的Linux上的ext4,除非O_DIRECT上,于是你的O_APPEND写入将需要一个扇区大小的倍数。


(*)“无限可能”从POSIX规范这些条款梗:

下面所有的职能应是原子在当他们常规文件或符号链接运行在POSIX.1-2008指定的效果相互... [许多功能] ...阅读()...写( )...如果每个两个线程调用这些函数之一,每个呼叫应由看到所有的其他呼叫,或没有人的规定影响。 [资源]

写操作可以相对于被序列化到其他的读取和写入。 如果文件数据的读取()可以证明(通过任何方式),以数据的写入()后发生的,它必须反映write()方法,即使调用是由不同的工艺制造。 [资源]

但反过来:

POSIX.1-2008的这卷不指定从多个进程文件并发写入的行为。 应用程序应该使用某种形式的并发控制。 [资源]

您可以在此答案阅读更多关于这些的意思



Answer 3:

我写了一个脚本来实证检验的最大原子追加尺寸。 该脚本,写在bash,生成多个工作进程,所有编写特定工人的签名相同的文件。 然后读取该文件,寻找重叠或损坏的签名。 您可以在此看到脚本源的博客文章 。

实际最大原子追加尺寸不仅OS,而是由文件系统的变化。

在Linux + EXT3的大小是4096,和Windows + NTFS的尺寸为1024,请参阅下面的评论更多的大小。



Answer 4:

下面是标准说什么: http://www.opengroup.org/onlinepubs/009695399/functions/pwrite.html 。

如果O_APPEND文件状态标志的标志被设置,该文件偏移量应被设定为之前每个写入文件的端部和没有中间文件修改操作应改变文件偏移量和写入操作之间发生。



文章来源: Is file append atomic in UNIX?