write / fwrite是否保证是顺序的?

时间:2015-04-25 05:33:28

标签: c posix libc

通过write(或fwrite)写入的数据是否保证以序列方式保留在磁盘上?特别是在容错方面。如果系统在写入期间失败,它的行为就好像先写入第一个字节并在中间停止写入(而不是写入随机块)。

此外,对write / fwrite的顺序调用是否保证是连续的?根据POSIX,我发现只有read的来电可以保证考虑之前的write

我问我正在创建一个持久存储到磁盘的容错数据存储。我的逻辑写入顺序是错误不会破坏数据,但如果不遵守逻辑顺序,我就会遇到问题。

注意:我不是在问是否保证持久性。只有当我的写作调用最终持续存在时,他们才会遵守我实际编写的顺序。

4 个答案:

答案 0 :(得分:2)

The POSIX docs for write()表示“如果已设置O_DSYNC位,则对文件描述符的写入I / O操作应按照同步I / O数据完整性完成的定义完成”。据推测,如果未设置O_DSYNC位,则未指定I / O数据完整性完成的同步。 POSIX还说“POSIX.1-2008的这个卷也没有提及应用程序级缓存的任何影响(比如stdio所做的那样)”,所以我认为不能保证fwrite()

答案 1 :(得分:2)

我不是专家,但我可能知道足以指出正确的方向:

最灾难性的情况是,如果你失去了权力,那么这是唯一值得考虑的事情。

  • 从包含X字节有意义内容的文件开始,以及指示它的标题。
  • 在不会使X无效的地方写下Y字节的有意义内容。
  • 致电fsync(慢!)。
  • 更新标题(可能必须小于磁盘的块大小)。

我不知道更改文件的长度是否安全。我不知道多少取决于文件系统挂载模式,除了任何" safe"对于需要具有轻微性能水平的系统,模式可能完全无法使用。

请记住,在某些系统上,fsync调用只是在没有安全做任何事情的情况下返回。你可以说,因为它快速返回。因此,您需要进行相当大的事务(即比应用程序级事务大得多)。

请记住,在现实世界中解决这个问题的人至少要获得高6位数的报酬。对于我们其他人来说,最好的答案是"只需将数据发送到postgres并让它处理它。"或者"接受我们可能不得不丢失数据并恢复为每小时备份。"

答案 2 :(得分:0)

不,一般而言,就POSIX和现实而言,文件系统不提供这样的保证。持久性顺序(其中磁盘使它们在盘片上永久存在)不是由制作系统调用的顺序,或文件中的位置,或磁盘上扇区的顺序决定的。文件系统将要写入内存的数据保留几秒钟,尽可能地囤积,然后以适合的顺序将它们分批发送到磁盘。无论内核如何将其发送到磁盘,由于NCQ,磁盘本身可以自行重新排序写入。

文件系统可以确保某些订购安全。过去使用了障碍,现在有明确的冲洗和FUA请求。关于这一点,有一个很好的article on LWN。但那些是由文件系统使用的,而不是应用程序。

我强烈建议您阅读有关Application Level Consistency的文章。不确定与您有多相关,但它显示了开发人员过去错误地假设的许多行为。

来自o11c的回答是一个很好的方法。

答案 3 :(得分:-1)

是的,只要我们不谈论增加多线程的复杂性。它将在磁盘上以相同的顺序,因为它使磁盘成为可能。它会缓冲到内存并在内存填满时将内存转储到磁盘,或者关闭文件。