Linux是否保证文件内容在关闭()后刷新到光盘?

Linux是否保证文件内容在关闭()后刷新到光盘?,linux,file-io,filesystems,Linux,File Io,Filesystems,当使用close()或fclose()关闭文件时(例如),Linux是否保证将文件写回(持久)光盘 我的意思是,如果close() fsync()系统调用确实提供了这种保证。关闭一个文件也足够了吗 目前我找不到任何东西能以这样或那样的方式提出任何要求 问题2: 如果close()确实隐式执行了fsync(),有没有办法告诉它不要这样做?没有,不保证。操作系统有自己的缓存。close真正能保证的是程序缓冲区被刷新到操作系统中,但操作系统可能仍然未写入缓冲区。我相信Linux内核世界中存在一些争议

当使用
close()
fclose()
关闭文件时(例如),Linux是否保证将文件写回(持久)光盘

我的意思是,如果
close()

fsync()
系统调用确实提供了这种保证。关闭一个文件也足够了吗

目前我找不到任何东西能以这样或那样的方式提出任何要求


问题2:


如果
close()
确实隐式执行了
fsync()
,有没有办法告诉它不要这样做?

没有,不保证。操作系统有自己的缓存。close真正能保证的是程序缓冲区被刷新到操作系统中,但操作系统可能仍然未写入缓冲区。我相信Linux内核世界中存在一些争议,因为即使是fsync也不能保证它被刷新到磁盘上,至少在ext3中是这样。

不,close不执行fsync(2),如果它这样做的话,会把许多机器打死。许多中间文件由其创建者打开和关闭,然后由使用者打开和关闭,然后删除,如果close(2)执行自动fsync(2),则这一非常常见的顺序需要触摸磁盘。相反,磁盘通常不会被触摸,而且磁盘永远不会知道文件在那里。

我认为Linux不能保证这一点,因为驱动器本身也可以缓存数据

从“
man 2关闭”
”:

成功关闭并不保证数据已被删除 已成功保存到磁盘,如 内核延迟写入

手册页上说,如果要确保数据在磁盘上,必须自己使用fsync()。

否。fclose()并不意味着fsync()。许多Linux文件系统都会延迟写入并将其批处理,从而提高总体性能,可能会减少磁盘驱动器的磨损,并延长笔记本电脑的电池寿命。如果操作系统必须在文件关闭时写入磁盘,那么许多好处都将失去

保罗·汤姆布林在他的回答中提到了一个争议,我所看到的解释不适合作为评论。以下是我听到的:

最近的争议是关于ext4的排序(ext4是流行的ext3linux文件系统的后续版本)。在Linux和Unix系统中,通常通过读取旧文件、用不同的名称写出新文件并将新文件重命名为旧文件来更改重要文件。这样做的目的是确保无论是新的还是旧的系统都会在那里,即使系统在某个时刻出现故障。不幸的是,ext4似乎乐于阅读旧版本,将新版本重命名为旧版本,然后编写新版本,如果系统在第2步和第3步之间崩溃,这可能是一个真正的问题


处理这个问题的标准方法当然是fsync(),但这会降低性能。真正的解决方案是修改ext4以保持ext3的顺序,在完成文件的编写之前不会重命名文件。显然,标准没有涵盖这一点,因此这是一个实现质量问题,而ext4的QoI在这里非常糟糕,如果不不断调用fsync(),就无法可靠地编写新版本的配置文件,以及由此产生的所有问题,或者有丢失两个版本的风险。

同样重要的是,fsync不能保证文件在磁盘上;它只是保证操作系统已请求文件系统刷新磁盘的更改。文件系统不必向磁盘写入任何内容

如果未定义
\u POSIX\u SYNCHRONIZED\u IO
,则措辞严重依赖 在一致性文档上,告诉用户可以预期的内容 从系统中删除。明确地说,一个空的实现 是允许的


幸运的是,Linux的所有通用文件系统实际上都将更改写入磁盘;不幸的是,这仍然不能保证文件在磁盘上。许多硬盘驱动器都开启了写缓冲(因此它们有自己的缓冲区,fsync不会刷新)。您可能还对firebird sql数据库中有关fcntl(O_SYNC)不在linux上工作的内容感兴趣

此外,你所问的问题暗示了一个潜在的问题。写入磁盘是什么意思?为什么这很重要?您是否担心电源中断,驱动器中的文件丢失?为什么不在系统或SAN上使用UPS

在这种情况下,您需要一个日志文件系统,不仅需要一个元数据日志文件系统,还需要一个完整的日志,即使是所有数据

即使在这种情况下,您也必须了解,除了O/S的参与外,-fsync只是将数据发送到驱动器,而如何等待驱动器刷新自己的缓存则取决于各个操作系统


--jeffk++

打开的手册页上写着:

为了保证同步I/O,除了使用O\U DIRECT外,还必须使用O\U SYNC

通常,这(O_DIRECT)会降低性能


您可以使用fcntlF_SETFL切换此标志,以便在每次读写之后将I/O的缓存影响降至最低。

如果计算机/操作系统有一个容错文件系统,可以保证至少在一次电源循环后写入一个文件,我们就不必关心这个问题我们把这一限制强加给了他们。如果有一些非易失性RAM或等效物,则不必是磁盘。我模模糊糊地记得,过去某个时代的一些大型机确实有这样的机制,而且据说确实做出了这样的保证

但是,如果驱动器被告知不要使用,或者(更常见的情况)是电池备份的RAID控制器