代码之家  ›  专栏  ›  技术社区  ›  MarkR

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

  •  22
  • MarkR  · 技术社区  · 17 年前

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

    我的意思是,如果 关闭() 返回0,然后在电源故障后立即返回,以前写入的数据是否保证持久性,即持久性?

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

    我现在找不到任何东西能以这种或那种方式提出任何要求。


    问题2:

    如果 关闭() 是否隐式执行 fSyc() 有没有办法告诉它不要这样做?

    9 回复  |  直到 12 年前
        1
  •  33
  •   unbeknown    17 年前

    从“ man 2 close “:

    成功关闭不能保证数据 已成功保存到磁盘,作为 内核推迟写入。

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

        2
  •  11
  •   Brandon Rhodes    17 年前

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

        3
  •  9
  •   Chas. Owens    17 年前

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

    从 man 3 fsync

    如果 _POSIX_SYNCHRONIZED_IO 没有定义,措辞严重依赖 在一致性文档上告诉用户可以期望什么 来自系统。它的明确意图是一个空的实现 是允许的。

    幸运的是,所有用于Linux的通用文件系统实际上都会将更改写入磁盘;不幸的是,这仍然不能保证文件在磁盘上。许多硬盘都打开了写缓冲(因此有自己的缓冲区,fsync不会刷新)。还有一些 drives/raid controllers even lie to you 关于冲洗缓冲器。

        4
  •  6
  •   David Thornley    17 年前

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

    保罗·汤布林在他的回答中提到了一个争议,并且解释了我所看到的一个争议不适合发表评论。我听到的是:

    最近的争论是关于ext4的排序(ext4是流行的ext3 Linux文件系统的继承者)。在Linux和Unix系统中,通常通过读取旧文件、用不同名称写出新文件以及将新文件重命名为旧文件来更改重要文件。这样做的目的是确保新的或旧的系统都在那里,即使系统在某个点上发生故障。不幸的是,ext4似乎乐于阅读旧的,将新的重命名为旧的,并编写新的,如果系统在步骤2和3之间崩溃,这可能是一个真正的问题。

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

        5
  •  3
  •   Paul Tomblin    17 年前

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

        6
  •  2
  •   user1055604    14 年前

    主页 打开 说:

    确保同步I/O o-同步 除此之外,还必须使用 奥伊德 .

    那

    一般来说,这(o_direct)会降低性能。

    可以使用 文件锁 具有 FSETFL 因此 最小化I/O的缓存效果 每次读写之后。

        7
  •  1
  •   jdkoftinoff    17 年前

    你也可能对这个感兴趣 bug report 来自Firebird SQL数据库,关于fcntl(o_sync)不在Linux上工作。

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

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

    即使在这种情况下,你也必须明白,除了O/S的介入, most hard disks lie to you about doing an fsync. -fsync只是将数据发送到驱动器,而如何等待驱动器刷新自己的缓存则取决于各个操作系统。

    ——杰弗克+

        8
  •  0
  •   Adrian Grigore    17 年前

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

        9
  •  -3
  •   Seren Seraph    13 年前

    如果计算机/操作系统有一个容错的文件系统,可以保证至少对我们设置了这个限制的文件进行一次电源循环后的写入,我们就不必担心这个问题了。如果有一些非易失性RAM或等效内存,那么它不必是磁盘。我模糊地记得,过去时代的一些大型机确实有这样的机制,而且据说确实做出了这样的保证。