我在#btrfs IRC上问过这个问题,他们说的should be ok if your hw isn't "buggy"
不是-“越野车”的意思your hw has correct flush/barrier semantics
。
TL; DR:这意味着btrfs可以防止由于断电而导致的数据损坏,其保护方式类似于ZFS。
原因如下:ZFS和btrfs背后的总体思路是相似的。两者都使用Merkle树作为数据结构。写操作可能需要更新磁盘上的多个块。文件系统通过将新数据写入空块(即使正在修改现有文件,因此不需要修改反映旧状态的块)并构建新的更新树来处理此问题。完成所有繁重的工作并将数据+更新的树写入磁盘后,头指针将更新到新的树,从而使更改可见。
这是写入文件时应该表现的方式:
- 将数据写入磁盘上的可用块。
- 复制Merkle树*,并根据(1)中的更改对其进行更新。
- 要求硬件将数据刷新到磁盘-硬件写入所有未决数据。
- 将头指针更新为新的Merkle树。
- 免费的旧块不再需要了。
如果在(4)之后断电,则交易完成。如果在步骤(1)到(3)期间断电,文件系统将处于旧状态(丢失在步骤(1)中写入的数据,但文件系统是一致的)。请注意,无需检查文件系统错误,这意味着文件系统可立即使用,这是一个很大的优势(检查大型文件系统可能需要很长时间!)。
这是一个示例,说明“越野车”硬件可能会出错:
- 将数据写入磁盘上的可用块。
- 复制Merkle树*,并根据(1)中的更改对其进行更新。
- 要求硬件将数据刷新到磁盘-硬件确认已完成但未完全刷新(例如,数据可能保留在磁盘的回写缓存中)。
- 将头指针更新为新的Merkle树。该数据先于其他未决数据写入磁盘(例如,因为磁盘头恰好位于正确的位置)。
- 在步骤(1)和(2)中写入的数据被写入磁盘。
- 免费的旧块不再需要了。
如果在(4)和(5)之间或执行步骤(5)时断电,文件系统将变得不一致。结果,Merkle树和/或数据可能仅被部分写入,从而导致文件系统变得不一致。
实际上,使用RAID控制器时必须格外小心。他们通常禁用磁盘上的写回缓存,而使用自己的写回缓存。这里有两种常见的出错方法:
*我在这里简化事情。实际上没有必要复制整个树。只需要添加已更改的部分-其余部分可以在新旧树之间共享。
zpool clear -F
命令恢复池