Linux是否保证在close()之后将文件内容刷新到磁盘上? 您所在的位置:网站首页 saved么读 Linux是否保证在close()之后将文件内容刷新到磁盘上?

Linux是否保证在close()之后将文件内容刷新到磁盘上?

2024-07-08 10:49| 来源: 网络整理| 查看: 265

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

我的意思是,如果close()返回0,然后立即断电,是否可以保证先前写入的数据持久存在,即持久性?

fsync()系统调用确实提供了此保证。 关闭文件是否也足够?

我目前找不到任何能以某种方式要求任何权利的东西。

问题2:

如果close()确实隐式地执行了fsync(),是否有办法告诉它不要?

相关讨论 一个相关的问题是在close()之后是否可以将文件重新打开到fsync()。 我找不到任何权威的答案。 这是一个悬而未决的问题。

从" man 2 close"开始:

A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes.

手册页指出,如果要确保数据位于磁盘上,则必须自己使用fsync()。

不,close不会执行fsync(2),如果这样做会导致许多机器瘫痪。许多中间文件由其创建者打开和关闭,然后由其使用者打开和关闭,然后删除,如果close(2)执行自动fsync(2),此非常常见的顺序将需要接触磁盘。取而代之的是,通常不会触摸磁盘,并且磁盘永远不会知道文件在那里。

相关讨论 你确定吗?您对此有参考吗? 是;在close(2)的手册页中,提到没有执行同步。对于更大的文件系统缓存问题,请参见涵盖操作系统中现代磁盘缓存的任何不错的文章,例如Hennessy和Pattersons的" Quantitative"操作系统教科书。 甚至fsync()都不是确定的..磁盘控制可能至少一小部分时间在缓存数据...

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

来自man 3 fsync

If _POSIX_SYNCHRONIZED_IO is not defined, the wording relies heavily on the conformance document to tell the user what can be expected from the system. It is explicitly intended that a null implementation is permitted.

幸运的是,事实上,所有用于Linux的通用文件系统都将更改写入磁盘。不幸的是,仍然不能保证文件在磁盘上。许多硬盘驱动器都打开了写缓冲功能(因此有自己的fsync不刷新的缓冲区)。某些驱动器/突袭控制器甚至对您撒谎冲洗缓冲区。

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

保罗·汤布林(Pau??l Tomblin)在回答中提到了一个争议,并解释了我所看到的一个内容,不予置评。这是我所听到的:

最近的争议是关于ext4的排序(ext4是流行的ext3 Linux文件系统的拟议继任者)。在Linux和Unix系统中,习惯上是通过读取旧文件,用不同的名称写出新文件并将新文件重命名为旧文件来更改重要文件。这样做的想法是即使系统在某个时候出现故障,也要确保新的或旧的都在那里。不幸的是,ext4似乎很乐于阅读旧版本,将新版本重命名为旧版本,然后编写新版本,如果系统在步骤2和3之间中断,这可能是一个真正的问题。

处理此问题的标准方法当然是fsync(),但这会浪费性能。真正的解决方案是修改ext4以保持ext3的顺序,在这种情况下,直到文件写完,它才重命名文件。显然,这不是标准所涵盖的,因此这是实现质量的问题,而ext4的QoI确实很糟糕,没有办法可靠地编写新版本的配置文件,而无需不断调用fsync(),就遇到了所有问题导致或冒着丢失两个版本的风险。

相关讨论 也许那就是我想的。我应该问一下我听到过咆哮的人们到底在抱怨什么。 无论如何,这就是最近在Slashdot上出现的大文件系统问题。我在那里建议,对于C ++系统来说,通过空指针取消引用向您的老板发送一封令人讨厌的辞职信,并将您的色情收藏集(/。meme)发送给您的妈妈也是符合标准的。 对于较新版本的Ext4,有一个选项可以打开类似Ext3s data = ordered的选项:thread.gmane.org/gmane.comp.file-systems.ext4/12179

不,不能保证。操作系统具有自己的缓存。完全可以保证,程序缓冲区已刷新到OS,但是OS可能仍未写入而保留它。我相信Linux内核世界存在一些争议,因为即使fsync也不能保证至少在ext3中将其刷新到磁盘。

相关讨论 请提供引用,如果fsync()没有执行其应做的工作,那将是一个可怕的错误。 即它将完全破坏数据库的持久性。 我见过的争议是另外一回事,不适合发表评论。我正在为此写答案。

open的联机帮助页显示:

To guarantee synchronous I/O the O_SYNC must be used in addition to O_DIRECT.

然后

In general this (O_DIRECT) will degrade performance.

可以使用带有F_SETFL的fcntl来切换该标志,以便最大程度地减少此后每次读取和写入时I / O的缓存影响。

您可能还对firebird sql数据库中的此bug报告感兴趣,因为它涉及fcntl(O_SYNC)在Linux上不起作用。

此外,您提出的问题暗示潜在的问题。写入磁盘是什么意思?为什么这有关系?您是否担心电源中断并且驱动器中缺少文件?为什么不在系统或SAN上使用UPS?

在那种情况下,您需要一个日记文件系统-不仅是元数据日记文件系统,而且甚至是所有数据的完整日记。

即使在这种情况下,您也必须了解,除了操作系统的问题外,大多数硬盘对您进行fsync都是骗人的。 -fsync只是将数据发送到驱动器,这取决于各个操作系统来知道如何等待驱动器刷新其自己的缓存。

--jeffk ++

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

相关讨论 但是,如果已告知该驱动器不做驱动器,或者(通常)是该驱动器是电池供电的RAID控制器,则原则上应该能够提供此保证。 从原则上讲,这可能是正确的,但实际上,这不是规范。 那就是驱动器的问题,那么,如果它可以向其报告已成功写入某些内容并撒了谎。一旦确信设备驱动程序已将其写入磁盘,Linux便会做所有可以做的事情。 在写操作完成之前,拥有硬件写缓存的全部要点不会阻塞操作系统。该驱动器别无选择,只能"撒谎"。请不要误会我的意思,我不是要怪Linux,我只是说Linux不能保证这一点,即使付出了很大的努力。 驱动程序实际上是对操作系统说谎吗?我对此领域一无所知,但我一直以为它回答"我明白了",然后在实际上确实回答时说"我写了"……我还认为操作系统有一种方法可以要求它立即写出。这些假设不正确吗? 据我了解,它不是操作系统的驱动程序,而是硬盘驱动器本身。看看jasonbrome.com/blog/archives/2004/04/03/writecache_enabled.h tml 磁盘唯一的谎言就是说它没有写数据时就是拥有电池后备的高速缓存,因此无论如何都不会丢失数据。否则,您确实应该获得更好的磁盘。

如果计算机/操作系统具有容错文件系统,并且至少在我们施加了此约束的文件中关闭了电源循环,则可以保证对这些文件进行写操作,那么我们就不必在乎这一点。如果有一些非易失性RAM或等效的RAM,则不必是磁盘。我隐约记得一些过去时代的大型机确实具有这样的机制,并且据说确实提供了这样的保证。

相关讨论 大多数现代服务器级RAID控制器都具有此功能(电池后备缓存)。但是,到控制器的总线速度是有限的,因此,如果应用程序明确要求,操作系统通常只会等待数据被"写入"。如对这个问题的回答所示。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有