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


12

使用zfs,如果您copies=2丢失了包含其中一些副本的驱动器,那么如何告诉系统应为受影响的文件制作数据块的新副本?还是zfs一发现坏数据块就立即开始为额外副本添加数据块?

会擦洗吗?

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

Answers:


10

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

如果您有冗余(mirroring / raidz / raidz2 / raidz3),则同上区块与其他区块没有什么不同,因此清理/重新同步将重新创建它们。


这与@Redmumba所说的直接冲突-Redmumba提供了代码链接。您能否引用您的言论来源?特别是,我很想看到为什么您认为copys = N不能解决整个设备故障的原因-这与我所读的内容不符。
詹姆斯·摩尔

1
@James Moore整个设备出现故障后,该磁盘上将不会写入任何同上块。池级别没有冗余,因此无法用新磁盘替换故障磁盘。正确恢复这种情况的唯一方法是对池进行完全备份,使用运行状况良好的设备重新创建该池,然后从备份还原,同时确保在完成第一次备份之前不会意外重启。否则,该池可能不可导入,并且其数据将丢失。与冗余池相比,这是一个沉重的负担,在冗余池中,联机完成损坏磁盘的操作并可以在重新启动后幸免。
jlliagre 2012年

1
这里是参考:docs.oracle.com/cd/E19082-01/817-2271/gbbvf / ... For a device to be replaced, the pool must be in the ONLINE state. The device must be part of a redundant configuration, or it must be healthy (in the ONLINE state).我假定copys = 2或3不被视为冗余配置。
jlliagre 2012年

1
不过,要记住的一件事是,如果您最初拥有copies=1并将其升级到copies=2,那么您之后可能会希望重新进行银/刷新操作,这将创建这些实例。但是@jilliagre是正确的:ditto块不构成冗余配置。即使池中有多个设备,也无法保证将块设置在另一台设备上。
Andrew M.

1
“副本数= N,其中N> 1”功能不是为了增加冗余。它旨在解决数据损坏。写入zfs的所有内容都经过校验和或哈希处理。读回时,校验和/哈希被验证。如果N = 1,则校验和/哈希验证失败将导致错误返回给应用程序。如果N> 1,则可以查阅其他副本之一并用于修复所有其他副本。
longneck 2012年

9

我发现这个问题确实很有趣,花了一个小时浏览文档之后,我才开始研究代码。这是我发现的。

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

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

考虑到这一点,当到达读取部分时,如果所有子项(不包含镜像或同上块)不包含期望值good_copies,则将其视为不安全,然后根据需要重写它们。因此,听起来您的问题的答案是-是的,当您至少有一个良好的副本并且满足以下任一条件时,它将重写它们:

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

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


1
问题出在@jlliagre的答案中-如果丢失任何设备,则该池已死。池中仍然有足够的同上块的事实似乎无关紧要。可以解决吗?
James Moore

4
@JamesMoore如果设备的前1MB出现故障,则可以强制阵列以降级状态联机。大概您只需要故障设备中的元数据。我已经用jbod风格的zpool测试了它,它的工作原理是:恢复raidz损坏的标签。在破坏zpool之前和之后,我都执行了md5sum,并且在导入之后只有copys = 1文件系统被破坏了。副本= 2和副本= 3文件系统完美匹配。
朱迪C

2

@jlliagre和其他人似乎认为,如果zpool中的一个磁盘(vdevs)死了,但整个zpool却死了,但是该池不是多余的(镜像/ raidz)。这不是真的; 一个多磁盘池将永远生存下去,即使它不是一个镜面或RAIDZ一个完整的磁盘故障。

ZFS元数据始终至少被复制2次,因此完整磁盘(或其任何部分)的完全故障将不会破坏文件系统。此外,许多文件(尤其是较小的文件)不会分散在所有磁盘上,因此不一定会因磁盘故障而出现故障。OP正在询问使用同上块(用户数据副本> 1)的多磁盘池的情况。在这里,一个完整的磁盘故障应该永远不会导致任何数据丢失。ZFS将始终尝试将ditto块置于远离原始块的位置,对于具有多个vdev的池,这始终意味着在另一个vdev上(一个vdev占池的50%以上可能是一个例外,这是非常不寻常的) 。文件系统元数据也总是比同上级别多复制+1或+2倍,因此它将始终在磁盘故障中幸免。此外,如果一个池中的磁盘多于三个,则应该可以丢失多达一半的磁盘而不会丢失任何数据;ZFS将ditto块存储在下一个磁盘上,只要您不会丢失两个相邻的磁盘,就不会丢失数据。(ditto = 2的三个相邻磁盘故障)。

当有足够的数据副本可访问文件时(无论这些副本来自ditto块,镜像还是raidz),则在访问文件时将修复所有丢失的数据副本。这就是擦洗的目的;读取所有数据,并通过使用冗余副本来修复所有不良数据。因此,要直接回答OP问题,您只需在更换故障驱动器后进行擦洗,即可恢复所有副本。

与往常一样,您可以通过创建池来进行试验,这些池的后备存储vdev只是普通的稀疏文件。通过删除或破坏vdev文件,您可以模拟任何类型的故障,并可以一路验证池,文件系统和数据的完整性。

编辑:经过实验后,如果磁盘在拷贝数大于等于2的多磁盘非冗余池中发生故障,则zfs似乎会使池失败。一个或多个磁盘上的局部数据损坏应保持生存状态,并应通过清理来修复。


这些实验的可怕之处在于,它们非常适合告诉我设置将立即或至少很快失败。他们不是很乐意告诉我设置有时会失败。无论如何,都不清楚如何带回有故障的池。我试图用三个稀疏文件来设置一个这样的池,然后删除其中一个稀疏文件似乎对整个池来说都是致命的。zpool replace不会替换失败的文件,zpool scrub停滞在5%(这是非常小的池),并且illumos.org/msg/ZFS-8000-5E上的错误页面并不乐观。
詹姆斯·摩尔

我的实验结果与我类似,只有在回答后才完成。我通常只使用raidz,并且根据我认为是可靠来源的信息(Oracle博客)进行回答。我不再相信副本数大于1的多磁盘JBOD类型池可以在磁盘故障中幸免。
亚伦B
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.