BTRFS 是否保证停电时的数据一致性?

cer*_*cem 12 btrfs failure-resistance

正如ZFS 专门声明的那样ZFS 声称是无懈可击的 ZFS 承认它可能容易受到电源故障的影响。

我找不到 BTRFS 这样的声明。它(或设计/计划)在停电期间耐用吗?

Mar*_*rad 6

我在#btrfs IRC 上问过这个问题,他们说 not- should be ok if your hw isn't "buggy"“buggy” 的意思是your hw has correct flush/barrier semantics.

TL;DR:这意味着 btrfs 以与 ZFS 类似的方式受到保护,防止因断电而导致数据损坏。

原因如下: ZFS 和 btrfs 背后的总体思路是相似的。两者都使用 Merkle 树作为数据结构。写入可能需要更新磁盘上的多个块。文件系统通过将新数据写入空块(即使正在修改现有文件,因此它不需要修改反映旧状态的块)并构建新的更新树来处理此问题。一旦完成所有繁重的工作并且数据 + 更新的树已写入磁盘,头指针将更新到新树,从而使更改可见。

以下是写入文件时的行为方式:

  1. 将数据写入磁盘上的空闲块。
  2. 复制 Merkle 树*,根据 (1) 中写入的更改对其进行更新。
  3. 要求硬件将数据刷新到磁盘 - 硬件写入所有挂起的数据。
  4. 更新指向新 Merkle 树的头指针。
  5. 释放不再需要的旧块。

如果在 (4) 之后断电,则交易完成。如果在步骤 (1) 到 (3) 期间断电,文件系统将回到旧状态(在步骤 (1) 中写入的数据丢失,但文件系统是一致的)。请注意,无需检查文件系统错误,这意味着文件系统立即可用,这是一个很大的优势(检查大型文件系统可能需要很长时间!)。

以下是“有缺陷”的硬件如何出错的示例:

  1. 将数据写入磁盘上的空闲块。
  2. 复制 Merkle 树*,根据 (1) 中写入的更改对其进行更新。
  3. 要求硬件将数据刷新到磁盘 - 硬件确认完成但不会完全刷新(例如,数据可能保留在磁盘的回写缓存中)。
  4. 更新指向新 Merkle 树的头指针。该数据在其他未决数据之前写入磁盘(例如,因为磁盘的磁头恰好位于正确的位置)。
  5. 在步骤 (1) 和 (2) 中写入的数据将写入磁盘。
  6. 释放不再需要的旧块。

如果在 (4) 和 (5) 之间或在执行步骤 (5) 时断电,文件系统将变得不一致。因此,默克尔树和/或数据可能只被部分写入,导致文件系统变得不一致。

实际上,在使用 RAID 控制器时必须特别小心。他们通常禁用磁盘上的回写缓存,而使用自己的回写缓存。这里有两种常见的出错方式:

*我在这里简化了事情。实际上没有必要复制整棵树。只需要添加更改的部分 - 其余部分可以在旧树和新树之间共享