如果在移动文件时被中断,文件系统会变得不一致吗?


13

我在同一分区(EXT2)上有两个文件夹如果我mv folder1/file folder2发生某些中断(例如电源故障),文件系统是否可能会最终变得不一致?

mv操作不是原子的吗?

更新: 到目前为止,在IRC上,我有以下观点:

  1. 它是原子的,因此不会发生不一致
  2. 首先,您将目录条目复制到新目录中,然后擦除上一个目录中的条目,因此可能会有两次引用文件的不一致,但是引用计数为1
  3. 它首先擦除指针,然后再复制指针,因此不一致之处在于该文件的引用为0

有人可以澄清吗?

Answers:


11

首先,让我们消除一些神话。

它是原子的,因此不会发生不一致

rename就软件环境而言,在同一文件系统(即)系统调用中移动文件是原子的。原子性意味着寻找该文件的任何进程将在其旧位置或新位置看到该文件;没有进程能够观察到该文件具有不同的链接计数,或者该文件在目标目录中存在之后在源目录中存在,或者在源文件中不存在之后目标目录中没有该文件目录。

但是,如果系统由于错误,磁盘错误或断电而崩溃,则不能保证文件系统保持一致状态,更不用说移动未完成一半了。Linux通常不会就硬件事件提供原子性保证。

首先,您将目录条目复制到新目录中,然后擦除上一个目录中的条目,因此可能会有两次引用文件的不一致,但是引用计数为1

这是指一种特定的实现技术。还有其他

碰巧Linux上的ext2(从内核3.16开始)使用了这种特殊技术。但是,这并不意味着磁盘内容按顺序[旧位置]→[两个位置]→[新位置]进行,因为这两个操作(添加新条目,删除旧条目)在硬件级别上都不是原子的:其中之一可能会被中断,从而使文件系统处于不一致状态。(希望fsck可以修复它。)此外,块层可以对写入进行重新排序,因此前一半可以在崩溃之前提交到磁盘,而后一半将不执行。

只要系统不崩溃,就不会观察到参考计数与1有所不同(请参见上文),但是该保证不会扩展到系统崩溃。

它首先擦除指针,然后再复制指针,因此不一致之处在于该文件的引用为0

再一次,这是指一种特定的实现技术。如果系统没有崩溃,则无法观察到悬挂文件,但是至少在某些配置中,这是系统崩溃的可能结果。


根据Alexander Larsson的博客文章,ext2无法保证系统崩溃时的一致性,但是ext3可以在这种data=ordered模式下实现。(请注意,此博客文章不是关于rename自己的,而是关于写文件和调用rename该文件的组合。)

ext2,ext3和ext4文件系统的主要作者Theodore Ts'o 就同​​一问题撰写了一篇博客文章。这篇博客文章讨论了原子性(仅关于软件环境)和持久性(关于崩溃的原子性以及承诺保证,即知道已执行操作)。不幸的是,我无法单独找到关于崩溃的原子性信息。但是,ext4的耐用性保证要求rename是原子性的。对ext4的内核文件指出,EXT4与auto_da_alloc选项(这是在现代内核默认设置),以及为ext4,提供了耐用性担保write后跟一个rename,这rename对于硬件崩溃而言是原子的。

为增加了Btrfs,一个rename覆写现有文件被保证是原子相对于崩溃,但一个rename不覆盖文件可导致既不文件或现有这两个文件。


总而言之,对于您的问题的答案是,不仅因为ext2崩溃而移动的文件不是原子的,而且甚至不能保证使文件保持一致的状态(尽管fsck无法修复的故障很少见)—几乎什么都没有,这就是为什么发明了更好的文件系统的原因。Ext3,ext4和btrfs确实提供了有限的保证。


13

重命名操作在任何文件系统上都非常快,因此不太可能被中断,但是在经典文件系统上,它肯定可以被中断-如果它先创建目标链接,则可以在文件上留下两个链接-这是合法的,但该文件认为它只有一个,如果以后删除一个,可能会导致问题。另一方面,如果先删除源链接,则文件可能会丢失。运行fsck通常会检测并更正这两种情况,但是如果文件丢失,它将以任意名称而不是所需的位置放置在“丢失+找到”目录中-如果它具有两个链接,则链接计数将很简单进行更新,因此如果文件系统支持,文件将存在于两个位置。

如果您需要一个文件系统来应对电源故障,那么应该使用日记文件系统,例如NTFS,EXT3或XFS。默认情况下,大多数现代系统将默认使用日记文件系统,但是您应该知道,如果将FAT用于外部驱动器,则它不是日记文件系统。

日记文件系统使用“重复输入”系统-将要移动的事实写入日记文件,然后执行移动。在启动时检查文件系统时,如果文件系统被中断,它将注意到该移动尚未完成,然后重做。

日记文件系统有两种类型-元数据日记和完整日记。元数据日记功能意味着它不会跟踪日记系统中文件内容的更改(因此,如果您正在写入文件,最终可能会丢失内容),但仍会跟踪重要的文件系统信息,例如目录内容,文件属性等。


当人们谈论重命名操作是原子的时,他们意味着不能在过渡过程中通过系统上的另一个进程观察到它,也不能通过例如用中断mv命令本身来使它完成一半^C。写入每个目录的物理过程(其存储空间可能位于磁盘上的不同位置)在硬件级别可能不是真正的原子操作。


为了完整起见,我会注意到,除了在目标目录中创建新链接并在旧目录中删除它之外,还有一些与重命名相关的偶然I / O操作-更新两个目录的mtime,可能会扩展目标目录的分配大小,..如果文件是目录,则更改链接和父目录的链接计数。另外,我不确定文件本身的时间是否受到影响。


日记不保证电源故障的原子性。我认为ext3和ext4确实可以保证rename是原子的,但是btrfs却不符合Wiki(请参阅我的回答)。也可以在没有日志的情况下保证原子性(我不知道Linux上的示例,但可能会有一些)。您是否有关于ext2的可靠信息?
吉尔斯(Gilles)'所以

@Gilles您是否有任何信息,从理论上讲,即使没有期刊,也可以保证该信息?我的意思是,从根本上讲,我们正在谈论将写入同步到两个不同的文件,以确保您永远不会得到只执行其中一个的结果。
Random832

日志结构的文件系统通过不覆盖正在使用的块来保持一致性。这非常适合覆盖现有数据的闪存介质。日志实际上并不像日志,因为挂载时不会重播任何内容-尽管您可以说整个文件系统都是日志(除非挂载永远不会涉及重播整个内存,因为这样做太慢了)。Wikipedia中对LogFS的描述是一个很好的概述。
吉尔斯(Gilles)'所以

1

在超级用户上,该问题的询问方式略有不同。该mv命令的Wikipedia页面也对此进行了很好的解释

通常,在同一文件系统内移动文件的方式与复制文件然后删除原始文件的方式不同。在不支持重命名syscall的平台上,新链接将添加到新目录,原始链接将被删除。无法访问文件数据。

Linux具有重命名的syscall,因此会将文件重命名为原子操作,即不可互操作。因此,在您描述的情况下文件系统不会变得不一致。


2
重命名系统调用是os抽象吗?从硬件角度来看,我始终可以中断一系列操作,因为重命名必须是一系列操作
graphtheory92

不,这不是操作系统的抽象,但我认为指出“因此文件系统不太可能会变得不一致...”会使事情变得过于复杂。我同意你的看法。
本杰明·B。

2
这个答案让我想知道为什么rename即使发生电源故障,系统调用也不能导致文件系统处于不一致状态。我觉得这是@ graphtheory92问题的核心。
Tanner Swett,2015年

1
@ graphtheory92:如果系统调用是原子的,则并不意味着最终的磁盘操作(或一系列磁盘操作!)也将是原子的。------我可以想象通过移动文件(硬链接数为1)并切断电源,硬盘连接或在合适的时间使内核崩溃,您最终可以得到两个硬链接(原始链接和新链接) )到硬链接数仍为1的文件。------我认为该问题有两种基本解决方案:a)软件-日记FS,可以自动从不一致状态中恢复。b)硬件支持的交易。
pabouk

2
您引用的原子性保证是关于其他过程的观察。如果系统崩溃,它将不保留。
吉尔斯(Gilles)'所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.