通过write
(或fwrite
)写入的数据是否保证以序列方式保留在磁盘上?特别是在容错方面。如果系统在写入期间失败,它的行为就好像先写入第一个字节并在中间停止写入(而不是写入随机块)。
此外,对write
/ fwrite
的顺序调用是否保证是连续的?根据POSIX,我发现只有read
的来电可以保证考虑之前的write
。
我问我正在创建一个持久存储到磁盘的容错数据存储。我的逻辑写入顺序是错误不会破坏数据,但如果不遵守逻辑顺序,我就会遇到问题。
注意:我不是在问是否保证持久性。只有当我的写作调用最终持续存在时,他们才会遵守我实际编写的顺序。
答案 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)
我不是专家,但我可能知道足以指出正确的方向:
最灾难性的情况是,如果你失去了权力,那么这是唯一值得考虑的事情。
fsync
(慢!)。我不知道更改文件的长度是否安全。我不知道多少取决于文件系统挂载模式,除了任何" safe"对于需要具有轻微性能水平的系统,模式可能完全无法使用。
请记住,在某些系统上,fsync
调用只是在没有安全做任何事情的情况下返回。你可以说,因为它快速返回。因此,您需要进行相当大的事务(即比应用程序级事务大得多)。
请记住,在现实世界中解决这个问题的人至少要获得高6位数的报酬。对于我们其他人来说,最好的答案是"只需将数据发送到postgres并让它处理它。"或者"接受我们可能不得不丢失数据并恢复为每小时备份。"
答案 2 :(得分:0)
不,一般而言,就POSIX和现实而言,文件系统不提供这样的保证。持久性顺序(其中磁盘使它们在盘片上永久存在)不是由制作系统调用的顺序,或文件中的位置,或磁盘上扇区的顺序决定的。文件系统将要写入内存的数据保留几秒钟,尽可能地囤积,然后以适合的顺序将它们分批发送到磁盘。无论内核如何将其发送到磁盘,由于NCQ,磁盘本身可以自行重新排序写入。
文件系统可以确保某些订购安全。过去使用了障碍,现在有明确的冲洗和FUA请求。关于这一点,有一个很好的article on LWN。但那些是由文件系统使用的,而不是应用程序。
我强烈建议您阅读有关Application Level Consistency的文章。不确定与您有多相关,但它显示了开发人员过去错误地假设的许多行为。
来自o11c的回答是一个很好的方法。
答案 3 :(得分:-1)
是的,只要我们不谈论增加多线程的复杂性。它将在磁盘上以相同的顺序,因为它使磁盘成为可能。它会缓冲到内存并在内存填满时将内存转储到磁盘,或者关闭文件。