当使用close()
或fclose()
(例如)关闭文件时,Linux是否保证将文件写回(持久)光盘?
我的意思是,如果close()
返回0然后立即断电,以前写的数据是否保证会持续存在,即是否持久?
该fsync()
系统调用确实提供了这种保证.关闭文件也足够了吗?
我找不到任何可能以某种方式提出任何要求的东西.
问题2:
如果close()
隐含地做了fsync()
,有没有办法告诉它不要?
来自" man 2 close
":
成功关闭并不能保证数据已成功保存到磁盘,因为内核会延迟写入.
手册页说如果你想确保你的数据在磁盘上,你必须自己使用fsync().
不,接近并没有执行的fsync(2) ,如果它这样做会连击许多机器死亡.许多中间文件由其创建者打开和关闭,然后由其消费者打开和关闭,然后删除,如果close(2)执行自动fsync(2),这个非常常见的序列将需要触摸磁盘.相反,通常不会触摸磁盘,磁盘永远不会知道文件存在.
同样重要的是要注意fsync不保证文件在磁盘上; 它只是保证操作系统已经要求文件系统刷新磁盘更改.文件系统不必向磁盘写入任何内容
来自man 3 fsync
如果
_POSIX_SYNCHRONIZED_IO
未定义,则措辞在很大程度上依赖于一致性文档来告诉用户系统可以期望什么.明确意图允许null实现.
幸运的是,Linux的所有常见文件系统实际上都会将更改写入磁盘; 不幸的是,仍然不能保证文件在磁盘上.许多硬盘驱动器都打开了写入缓冲(因此有自己的缓冲区,fsync不会刷新).有些驱动器/ raid控制器甚至会骗你冲洗他们的缓冲区.
不,fclose()并不意味着fsync().许多Linux文件系统会延迟写入并批量处理,从而提高整体性能,可能会减少磁盘驱动器的磨损,并缩短笔记本电脑的电池寿命.如果操作系统必须在文件关闭时写入磁盘,那么许多这些好处都将丢失.
保罗·汤姆林(Paul Tomblin)在他的回答中提到了一个争议,解释我所看到的那个不适合评论.这是我听到的:
最近的争议是关于ext4的排序(ext4是流行的ext3 Linux文件系统的拟议继承者).在Linux和Unix系统中,通常通过读取旧文件,使用不同的名称写出新文件并将新文件重命名为旧文件来更改重要文件.这个想法是确保新的或旧的,即使系统在某些时候失败.不幸的是,ext4似乎很乐意阅读旧版本,将新版本重命名为旧版本,并编写新版本,如果系统在步骤2和3之间出现故障,这可能是一个真正的问题.
解决这个问题的标准方法当然是fsync(),但这会破坏性能.真正的解决方案是修改ext4以保持ext3顺序,在完成写入文件之前,它不会重命名文件.显然这不是标准所涵盖的,所以它是一个实现质量的问题,而ext4的QoI在这里真的很糟糕,没有办法在不经常调用fsync()的情况下可靠地编写新版本的配置文件,并且存在所有问题导致或冒失去两个版本的风险.