zpool 清除后丢失的写入会发生什么情况?

Kev*_*vin 6 zfs software-raid

我试图了解 ZFS 在特定条件下的行为,但文档对此不是很明确,所以我只能猜测。

假设我们有一个具有冗余的 zpool。采取以下事件顺序:

  1. 设备 D 与服务器之间的连接出现问题。这会导致大量故障,并且 ZFS 会导致设备出现故障,从而使池处于降级状态。

  2. 当池处于降级状态时,池会发生突变(数据被写入和/或更改。)

  3. 连接问题已得到物理修复,设备 D再次可靠

  4. 知道 D 上的大多数数据都是有效的,并且不想通过重新同步给池带来不必要的压力,管理员改为运行zpool clear pool D。Oracle 文档指出,当故障是由于暂时性问题引起且已得到纠正时,这是适当的操作。

我读过,这只zpool clear清除错误计数器,并将设备恢复到在线状态。然而,这有点麻烦,因为如果这就是它所做的一切,它将使池处于不一致的状态!

这是因为步骤 2 中的突变不会成功写入 D。相反,D 将反映连接失败之前池的状态。这当然不是 zpool 的规范状态,并且可能会在另一个设备发生故障时导致硬数据丢失 - 但是,池状态不会反映此问题!

我至少会假设基于 ZFS 强大的完整性机制,尝试从 D 读取变异数据会捕获错误并修复它们。然而,这会带来两个问题:

  1. 除非完成清理,否则不能保证读取命中所有突变;和

  2. 一旦 ZFS确实命中了变异数据,它(我猜测)可能会再次使驱动器出现故障,因为 ZFS 会认为它正在损坏数据,因为它不记得以前的写入失败。

理论上,ZFS 可以通过跟踪降级状态期间发生的突变并在清除时将它们写回 D 来规避此问题。但出于某种原因,我怀疑事实并非如此。

我希望对 ZFS 有深入了解的人可以在这方面提供一些启发。

小智 1

注意:

  1. 每个数据块在 ZFS 上都有公平的校验和。因此,当发生故障时,ZFS 知道哪个驱动器在冗余设置中保存正确的数据。运行zpool scrub ZFSPOOL将修复数据或将数据传播到 RADZ 的所有正在运行的驱动器。
  2. ZFS 采用Reed-Solomon 纠错,最适合突发错误。缺少驱动器是这样的突发错误,RS 可以纠正这些错误。

当数据中心的空调问题和 ZFS 能够解决这个问题时,我在驱动器上遇到了许多 DMA 错误。这只是简单的镜子。

我确实记得 SUN 在推出 ZFS 时发布的宣传视频...他们在部署到 8 端口 USB 集线器的 USB 闪存驱动器上进行了 RAIDZ,然后随机更改其中少数几个集线器的位置,同时在该池上进行 IO 操作,观察到没有中断。