ZFS:丢失驱动器后如何恢复正确数量的副本?

Jam*_*ore 12 zfs

使用 zfs,如果您拥有copies=2然后丢失了一个包含其中一些副本的驱动器,您如何告诉系统它应该为受影响的文件制作数据块的新副本?或者 zfs 是否在发现坏数据块后立即开始为额外副本添加数据块?

擦洗会这样做吗?

(v0.6.0.56-rc8,ZFS 池版本 28,ZFS 文件系统版本 5,Ubuntu 11.10)

jll*_*gre 10

“copies=2”(或 3)更适合与没有冗余的池(单个磁盘或条带)一起使用。目标是能够恢复轻微的磁盘损坏,而不是整个设备故障。在后一种情况下,池是不可挂载的,因此不会发生同样的块恢复。

如果您有冗余(镜像/raidz/raidz2/raidz3),同上块与其他块没有什么不同,擦洗/重新同步将重新创建它们。

  • @James Moore 在整个设备发生故障后,该磁盘上不会写入任何同上块。池级别没有冗余,因此无法用新磁盘替换有故障的磁盘。正确恢复这种情况的唯一方法是对池进行完整备份,使用健康的设备重新创建它,然后从备份中恢复,同时确保在完成第一次备份之前不会发生意外重新启动。否则,池可能无法导入并且其数据会丢失。与冗余池相比,这是一个相当大的负担,在冗余池中,损坏磁盘的恢复是在线完成的,并且在重新启动后仍然存在。 (3认同)
  • 这是一个参考:http://docs.oracle.com/cd/E19082-01/817-2271/gbbvf/index.html#6mhupg6rl `对于要更换的设备,池必须处于 ONLINE 状态。该设备必须是冗余配置的一部分,或者它必须是健康的(处于在线状态)。`我假设副本= 2或3不被认为是冗余配置。 (3认同)
  • “copies=N where N>1”特性并不是为了增加冗余。它旨在解决数据损坏问题。写入 zfs 的所有内容都经过校验和或散列。当它被读回时,校验和/哈希被验证。如果 N=1,则校验和/哈希验证失败会导致错误返回给应用程序。如果 N>1,则可以查询其他副本之一并用于修复所有其他副本。 (2认同)

And*_* M. 9

我发现这个问题真的很有趣,在花了一个小时翻阅文档后,我深入研究了代码。这是我发现的。

首先,一些术语。Ditto 块(这些副本是什么,而不是镜像)在写入时自动创建,但可能与原始副本位于相同的虚拟设备 (vdev) 中,也可能不同。另一方面,镜像块总是被反射到另一个虚拟设备上。

但是,代码将这两种类型的块都称为子块。您将在此处看到同上块只是其子项io_vd == NULL(这是在 write 函数中)。对于镜像块,io_vd将设置为相应的虚拟设备(例如,您的第二个磁盘)。

考虑到这一点,当它到达读取部分时,如果它不包含预期good_copies,它会将所有子项(无论是镜像还是同上块)视为潜在不安全,并根据需要重写它们。所以听起来你的问题的答案是 - 是的,当你至少有一个好的副本时,它会重写它们,并且具有以下任一条件:

  • 尝试读取数据时出现意外错误,
  • 您正在重新同步,或
  • 你在擦。

呼!也许有人可以指出缺陷,但我很喜欢通过这个小练习学习 ZFS,我希望这会有所帮助!

  • @JamesMoore 如果您的设备的前 1MB 出现故障,您可以强制阵列以降级状态联机。大概您只需要来自故障设备的元数据。我已经用 jbod 风格的 zpool 测试了这个,它的工作原理:[恢复 raidz 损坏的标签](http://mail.opensolaris.org/pipermail/zfs-discuss/2012-June/051731.html)。我在破坏 zpool 之前和之后做了一个 md5sum,导入后只有副本=1 文件系统被破坏。副本=2 和副本=3 文件系统完美匹配。 (4认同)