资讯详情

硬盘写到一半时断电,文件系统里会发生什么?

原标题:硬盘写到一半时断电,文件系统会发生什么?

转载自 Linux爱好者

来源:知乎

https://www.zhihu.com/question/55711728

【伯乐在线转注:】本文来源于知乎问答帖:文件系统在硬盘件系统发生了什么?。补充原题主的问题:

断电时文件系统发生了什么?硬盘发生了什么?下次启动时,系统层面是否仍有一半的文件?它还在底层吗?

进一步, 如何保证文件系统的事务性, 会不会有一些极端的情况,比如最后几个bit还没写完, 文件系统认为它成功了

答案不限于任何文件系统,谢谢!

下面是「北极」伯乐在线授权回复分享:

断电的那一刻,很多事情都无法确定:

1.您无法确定您试图向设备驱动发送的写作指令是否成功。驱动程序本身通常有缓存;

2. 即使指令正常返回,您也无法确定设备是否实际成功,因为设备本身也可能有缓存。目前,当没有设备可以保证指令返回时,所有数据必须成功地存储在介质上(但一些制造商可以确保少量数据可以成功地写入),并存储设备flush操作不绝对可靠;

3. 哪些成功和失败可能是混乱的,换句话说,如果你先发送请求A,再发送写请求B,并且都成功返回,掉电时请求A可能丢失,但B成功(NCQ功能);

4. 机械磁盘可能会丢失半数据(例如,512字节风扇区域只写入100字节,即主题所说的bit等级错误),但通常通过校准位检测到。

由于上述限制如此之多,事实上,文件系统无法保证数据不会丢失,甚至不确定哪些丢失可以恢复。

一般来说,文件系统有以下策略:

1. 完全不管错事,错了就错了;

2. 通过磁盘检测功能恢复标记位置的方式;

3. 文件系统结构可以在设计上恢复,但用户数据不能恢复;

4. 确保数据在用户数据层面的绝对正确性。

现在第一和第二种策略比较少见,FAT文件系统属于这一类;主流文件系统基本上可以保证第三种,例如NTFS等等;第四种比较难,一般配合存储驱动,多见于Flash介质专属文件系统。

具体方案一般包括:

方案1:Copy-On-Write,写数据时,不要在原来的位置写,而是先读一个,然后写到另一个位置。当确认写作成功时,将文件系统的指针指向新的位置。如下图所示:

75f9a5274f1b6a9f9ad56415647b7611.png

在实际应用中,情况更复杂,因为Data在写入过程中,File1本身的一些信息(修改时间等)也发生了变化,所以CopyOnWrite影响不止这一块,而是很多。

方案2:日志(Journal)技术。使用日志记录meta-data甚至数据块的变化(NTFS就是这个策略),一旦掉电,就可以在日志中反推到正确的状态,保证meta-data不损坏。

这两种常见的方案,当然还有其他更复杂的技术,可以参考这个链接(Comparison of file systems),但无论采用何种方案,本质上都是以牺牲性能为代价换取结构稳定。

最后,回到受试者的问题,文件系统如何确保数据的正确性?如果是指文件的数据部分,则无法保证,因为文件系统无法确定数据是否写入。绝大多数文件系统只能确保其结构正确,但这种正确性可能是回滚后的状态。文件系统无法保证具体的回滚内容。

说起来很复杂,不同的文件系统,不同的设备,不同的介质,效果都不一样。

下面是「马涛」伯乐在线授权分享答案

文件系统的设计一般是性能和数据完整性的妥协。如果你想要最高完整性,性能会更差。如果你想要最高性能,数据完整性会更差,仅此而已。当然,这些都是针对数据的。对于文件系统本身的元数据,一般设计师会有日志系统来考虑自己的数据完整性(例如ext4使用jbd2)尽量保证文件系统断电时没有问题或问题很少(需要使用)fsck解决方案),但用户选择和配置用户数据是否完整,文件系统会根据不同的配置选择不同的策略。

我们以Linux最通用的ext例如,他有三种模式供用户选择data=writeback/ordered/journal,对应的是数据落盘的三种方式,writeback指元数据更新时数据不考虑是否落盘,所以掉电后可能会看到一些乱七八糟的数据,ordered意思是元数据更新后(如果不更改元数据,就无法保证数据),另一种是journal意思是先写数据journal再写文件(double write),数据安全性最高,性能最差。可参加详细介绍mount(8)。

在文件系统之后,我们将讨论文件系统下的硬盘,因此文件系统严重依赖硬盘来实现数据完整性,硬盘还提供了一些确保文件系统数据完整性的命令。例如,硬盘提供flush命令保证,只要上层文件系统调用此命令,文件系统之前写的硬盘内容就必须落盘(一般硬盘有内存)cache,部分数据将被缓存,以提高写入性能,flush会命令硬盘将cache内容落盘。当然,如果硬盘有电容,可以保证cache即使掉电也会掉下来,所以他也可以欺骗上层文件系统 :) ),这样,文件系统在写入一些关键数据后必须调用flush,得到硬盘的flush以后再做反馈。当然,还有一些现代硬盘FUA(Force Unit Access)这些操作是为了加速某种磁盘下降的操作质上,即使硬盘不提供文件系统,也可以改为write flush为了实现(只是性能差),如果你感兴趣,你可以自己做google之。

说完底层,还有一层要说,就是你的应用是怎么写文件和硬盘的,如果是的话buffer write(应用程序只写操作系统的内存,从操作系统延迟到硬盘),如果应用程序是direct IO(应用程序绕过操作系统内存,直接写硬盘),那么可能只有掉电时刻正在写入的数据不见了,当然这里可能还涉及到direct IO不同文件系统的语义和具体实现与文件系统有关,需要具体分析。回搜狐多看看

责任编辑:

标签: 如何用电容延迟断电

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台