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

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

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

操作不是mv原子的吗?

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

  1. 它是原子的,因此不会发生不一致
  2. 首先,将目录条目复制到新目录中,然后删除先前目录中的条目,因此可能会出现文件被引用两次的不一致情况,但引用计数为 1
  3. 它首先擦除指针,然后复制指针,因此不一致的是文件的引用为0

有人可以澄清一下吗?

答案1

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

如果您需要一个在电源故障时保持稳健的文件系统,你应该使用日志文件系统,例如 NTFS、EXT3 或 XFS。大多数现代系统默认使用日志文件系统,但您应该知道,如果您将 FAT 用于外部驱动器,则它不是日志文件系统。

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

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


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


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

答案2

首先,让我们消除一些误解。

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

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

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

首先,将目录条目复制到新目录中,然后删除先前目录中的条目,因此可能会出现文件被引用两次的不一致情况,但引用计数为 1

这是指具体的实现技术。还有其他的。

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

只要系统不崩溃(见上文),引用计数就永远不会被观察到与 1 不同,但这种保证不会扩展到系统崩溃。

它首先擦除指针,然后复制指针,因此不一致的是文件的引用为0

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


根据亚历山大·拉尔森 (Alexander Larsson) 的博客文章,ext2 不保证系统崩溃时的一致性,但 ext3 在该data=ordered模式下提供一致性。 (请注意,这篇博文不是关于rename其本身,而是关于写入文件和调用该文件的组合rename。)

Theodore Ts'o,ext2、ext3 和 ext4 文件系统的主要作者,写了一篇关于同一问题的博客文章。这篇博文讨论了原子性(仅针对软件环境)和耐用性(这是关于崩溃的原子性加上承诺保证,即知道操作已经执行)。不幸的是,我无法找到有关仅与崩溃有关的原子性的信息。然而,为 ext4 提供的持久性保证要求它rename是原子的。ext4 的内核文档声明带有auto_da_alloc选项的 ext4(这是现代内核中的默认选项)以及 ext4 为 awrite后跟的 a提供了持久性保证rename,这意味着rename相对于硬件崩溃而言,它是原子的。

对于 Btrfs,arename覆盖现有文件就崩溃而言保证是原子的,但是arename不覆盖文件可能会导致两个文件都不存在或两个文件都不存在。


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

答案3

这个问题已被询问在超级用户上的方式略有不同。该命令的维基百科页面mv解释一下很好:

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

Linux 有重命名系统调用因此会将文件重命名为原子操作,即不可中断的操作。所以不,文件系统在您描述的情况下不会变得不一致。

相关内容