第五章:维修和翻新

磁盘已满。这就是他们的目的。硬件故障的原因也一样。有时,您必须从一台计算机中取出磁盘并将其放入另一台计算机,或者更换发生故障的硬盘,或者给数据库更多空间。本章讨论如何修改、更新和修复存储池。

在我们开始之前,让我们讨论一下ZFS如何重建损坏的VDEV。

第五章:维修和翻新重新同步扩展池添加VDEV到条带池添加VDEV到镜像池添加VDEV到RAID-Z池硬件状态在线模式(online)降级模式(degraded)故障模式(faulted)不可用模式(unavail)离线模式(offline)已移除(removed)ZFS堆栈错误恢复设备设备缺失更换设备故障的驱动器更换同一插槽更换不可用设备更换镜像提供者重新连接不可用和已删除的驱动器日志和缓存设备维护添加日志或缓存设备移除日志和缓存设备替换失效的日志和缓存设备导出和导入驱动器导出池导入池重命名导入的池不完整的池特殊导入更大的提供者Zpool版本和升级ZFS版本和功能标志Zpool升级和引导加载程序FreeBSD ZFS 池限制

重新同步

镜像和RAID-Z等虚拟设备是专门为重建损坏磁盘上丢失的数据而设计的。如果镜像对中的某个磁盘损坏,则更换该磁盘,ZFS将把幸存的镜像复制到新镜像上。如果RAID-Z VDEV中的磁盘发生故障,您可以更换损坏的驱动器,ZFS将根据奇偶校验数据重建该磁盘。这种数据恢复是每个RAID实施的核心功能。

然而,ZFS了解文件系统和底层存储。这为ZFS提供了传统RAID管理器所缺乏的灵活性和优势。

重建由软件或硬件RAID镜像的磁盘需要将每个扇区从正常磁盘复制到替换磁盘上。RAID单元必须将分区表、文件系统、所有索引节点、所有块(甚至可用空间)以及所有数据从一个复制到另一个。

我们都在 /etc/rc.conf 中输入过一个拼写错误(typo),导致系统无法启动。在用UFS2和 gmerror(8) 镜像的系统上修复该拼写错误需要引导到单用户模式,修复拼写错误,然后重新启动。这使得其中一个磁盘与另一个磁盘不同步。在重新启动时,FreeBSD注意到了这种差异,并通过将当前驱动器的每个扇区复制到备份上来使备份磁盘同步。您可能更改了磁盘上的一两个扇区,但 gmerror(8) 必须复制所有数据。这可能需要几个小时或几天的时间。

ZFS精确地知道每个磁盘的使用量。当ZFS重新组装替换存储提供程序时,它只复制该提供者上实际需要的数据。如果您更换的ZFS磁盘只有三分之一的数据,ZFS只会将磁盘数据的三分之一复制到替换磁盘。

修复ZFS镜像磁盘上的 rc.conf 拼写错误需要系统管理员的干预,这与 gmerror(8) 系统所需的干预非常相似。您将进入单用户模式。你纠正了拼写错误。你重新启动。不同的是,ZFS确切地知道磁盘上哪些块发生了变化。如果在单用户模式下只有一个磁盘通电(不太可能,但有可能发生),这两个磁盘将不同步。ZFS不会尝试复制整个磁盘,而是只更新重新同步磁盘所需的块。系统可能会先修复镜像,然后才能键入命令查看其运行情况。

ZFS重建(reconstruction)称为 resilvering 。与其他ZFS完整性操作一样,resilvering仅在实时文件系统上进行。您可以在单用户模式下调整大小,但这和在单用户方式下安装软件一样有意义。

更换存储提供者时,会自动进行resilvering。当驱动器暂时发生故障并恢复时,也会发生这种情况,例如当控制器重新启动或外部磁盘架重新启动时。虽然更换存储提供者可能需要相当长的时间,但在短暂停机后更换可能只需要几秒钟。

如果在resilvering时正常使用RAID-Z池,resilvering会大大减慢速度。按事务组顺序执行resilvering 和 scrubbing,而正常的读写操作则非常随机。ZFS的重组(resilver)率被调节,这样它就不会影响正常的系统功能。

扩展池

数据扩展以填充所有可用空间。无论你给一个池多少磁盘空间,最终你都会想要更多。要增加池的大小,请向池中添加VDEV。对于冗余池,您可以用更大的提供者替换存储提供者。

当您扩展池时,ZFS会自动开始将数据写入新空间。随着池的老化,ZFS试图在各种提供者之间均匀地平衡可用空间。ZFS对驱动器的写入进行偏置,使它们同时变满。然而,当一个池有一个空的VDEV和三个几乎满的VDEV的时候,它别无选择,只能将新数据放在空VDEV上。如果你经常创建和删除文件,每个磁盘的负载最终会趋于平稳。

zpool中的每个VDEV都应该相同。如果你的池是由一堆镜像构建的,不要向池中添加RAID-Z3。

使用 zpool attach 命令将提供者添加到VDEV,使用 zpool add 命令将VDEV添加到池。

您无法从非镜像VDEV或池中的任何VDEV中删除设备。 zpool add-n 标志执行“模拟运行”,显示在不实际更改池的情况下运行命令的结果。运行带有 -n 标志的 zpool add 命令并仔细研究由此产生的池配置,可以警告你即将自食其果。

添加VDEV到条带池

条带池没有冗余,可以扩展到硬件的极限。然而,您添加到池中的每个非冗余VDEV都会增加灾难性故障的可能性,就像它所类似的RAID-0设备一样。记住,池中单个VDEV的故障会破坏整个池。在条带化池中,每个磁盘都是一个独立的VDEV。

这是一个有三个提供者的条纹池。

使用 zpool add 命令将存储提供程序添加到 scratch 池中。

池状态现在显示四个存储提供者,您还有额外的磁盘空间。

添加VDEV到镜像池

您可以向镜像VDEV添加提供程序,但额外的磁盘不会增加可用空间。它们成为彼此的额外镜子。要向使用镜像VDEV的池中添加空间,请向池中添加一个新的镜像VDEV。

zpool db 当前有两个镜像VDEVs。

我们需要更多的空间,所以我们想添加第三个镜像VDEV。使用 zpool add 命令创建新的镜像设备并将其添加到池中。在这里,我们使用提供程序 gpt/zfs4gpt/zfs5 创建一个新镜像并将其添加到池中。

池的状态现在显示了一个新的镜像VDEV mirror-2,其中包含两个存储提供者。当您写入和删除数据时,池会在所有三个VDEV之间逐渐转移负载。要查看池当前如何在VDEV之间分配数据,请使用 zpool list -v

添加VDEV到RAID-Z池

您无法向任何RAID-Z VDEV添加提供者。要扩展基于RAID-Z的池,您必须向池中添加额外的VDEV,或者用更大的成员磁盘替换每个成员磁盘。最佳做法是让所有RAID-Z VDEV使用相同数量的驱动器。

这是一个RAID-Z池,我们想用另一个VDEV扩展它。

使用 zpool add 命令创建一个新的VDEV并加入到池中:

检查池状态会显示一个新的VDEV raidz1-1 ,其中包含三个提供程序。ZFS立即开始在新提供程序中对数据进行条带化。

如果要将新的VDEV添加到基于RAID-Z2或RAID-Z3的池中,请使用具有所需RAID-Z类型和适当数量的提供程序的相同命令。

请记住,您不能向RAID-Z VDEV添加提供程序——RAID-Z VDEV的配置是固定的。许多人试图使用 zpool add 向RAID-Z VDEV添加磁盘。zpool add 命令将新的VDEV添加到池中。如果使用 -f 命令 zpool添加一个新磁盘到基于RAID-Z的池中,则会得到一个格式错误的池,其中有一个RAID-Z成员和一个条带成员。由此产生的池是不可维护的,也是不可修复的。修复它需要备份数据,然后销毁并重新创建池。

您可以使用 zpool attach 来扩展镜像和条带VDEV,但它不适用于RAID-Z池。您无法向RAID-Z VDEV添加提供程序。

硬件状态

大多数ZFS配置都容忍一定数量的硬件故障。当底层存储提供程序发生故障时,ZFS会尽力警告您。听听它的警告。

zpool status 命令在 STATE 字段中显示存储硬件的状态。您将在顶部附近获得整个池的一个 STATE 字段。往下看,zpool状态列出了每个VDEV和存储提供程序,STATE 列允许您缩小故障所在的范围。

错误向上渗透。如果单个存储提供者发生故障,则池会发生相关故障。zpool status 顶部的大提示失败消息是您查看各个提供者以查看潜在错误的线索。

池和VDEV可以有六种状态。基础提供者可能至少有三个这样的状态(states)。

在线模式(online)

池的状态为 online 时,表示池、VDEV、提供者都在正常工作。

降级模式(degraded)

一个 degraded (降级)的池丢失了至少一个存储提供者。该提供者要么完全脱机,要么丢失,要么比ZFS允许的更快地生成错误。降级的池保留了足够的恢复能力以继续工作,但再发生一次故障可能会将其关闭。

如果存储提供者有太多I/O错误,ZFS更愿意完全关闭(故障)设备。然而,ZFS确实试图避免为池提供必要弹性的设备发生故障。如果镜像中最后一个工作的提供者开始显示许多错误,或者某个提供者在已经有死存储提供者的RAID-Z1 VDEV中发生故障,则ZFS会将该提供者置于降级模式,而它通常会将其置于故障(faulted)模式。

故障模式(faulted)

faulted 模式表示存储提供者要么已经损坏,要么产生的错误超出ZFS的容忍范围。出现故障的存储提供者会带走数据的最后一个已知的良好数据副本。如果一个双磁盘镜像丢失了两个磁盘,或者RAID-Z1丢失了两块磁盘,则VDEV发生故障。出现故障的VDEV会带走其整个池。

不可用模式(unavail)

unavail 表示ZFS无法打开存储提供者。可能设备不再连接到系统,或者可能它导入得不好(请参阅本章后面的“移动池”)。在任何情况下,它都不存在,因此ZFS无法使用它。不可用的设备可能会占用整个VDEV,从而占用整个池。

不可用设备会根据VDEV中的弹性影响VDEV的状态。如果池仍然具有足够的恢复能力来运行,则池将进入降级状态。如果VDEV不能再工作,则会处于故障模式。

不可用设备按分配给它们的GUID而不是提供者的设备节点显示在池的状态中。

离线模式(offline)

offline 设备是系统管理员故意关闭的设备。在大型阵列中关闭驱动器的原因不胜枚举。

已移除(removed)

当系统运行时,某些硬件可以检测驱动器何时从系统中物理删除。这样的硬件允许ZFS在拉动驱动器时设置 Removed 状态。重新连接驱动器时,ZFS会尝试使提供者重新联机。

ZFS堆栈错误

以下示例是一台服务器,其中有两个断开连接的存储提供者。这不属于Lucas或Jude的系统;它属于Lucas朋友的系统。请注意提供者上的错误、VDEV的类型和池作为一个整体的状态。

此RAID-Z2池处于降级(degraded)状态。它缺少两个提供者, /dev/gpt/zfs0/dev/gppt/zfs10 。RAID-Z2 VDEV最多可以处理两个磁盘故障,并将继续工作,尽管缺少驱动器。

然而,降级池的自愈能力有限。没有冗余的池没有ZFS修复文件所需的信息。上面的示例池在其RAID-Z2 VDEV中丢失了两个磁盘。它具有零冗余。如果文件发生位腐烂(bit rot),ZFS无法修复它。当您尝试访问该文件时,ZFS返回错误。数据集层的冗余(具有 copies 属性)可能会让ZFS修复文件。

如果此池再次发生驱动器故障,则池将不再具有其数据的完整副本,并将发生故障。

恢复设备

如果ZFS善意地宣布了它的问题,意味着至少可以尝试修复它们。修复过程取决于驱动器是否丢失(missing)或发生故障(failed)。

设备缺失

在操作期间断开连接的驱动器显示为已卸下(removed)或出现故障(faulted)。也许您删除了驱动器以检查其序列号。也许是电缆松了。可能是小鬼捣蛋(have been gremlins)。在任何情况下,您可能希望将其重新插入。

如果硬件注意到驱动器被删除,而不仅仅是说它丢失了,那么硬件也会注意到驱动器何时返回。ZFS尝试重新激活已恢复的驱动器。

在添加或删除驱动器时不通知操作系统的硬件需要sysadmin干预来恢复服务。使用 zfs online 命令将重新连接的驱动器恢复使用。

但是,如果驱动器因故障而脱机,则必须更换它,而不是重新打开它。

更换设备

驱动器更换最困难的部分通常与ZFS无关:您必须找到损坏的驱动器。我们建议在首次安装驱动器时使用磁盘的GPT标签中磁盘的物理位置,以便于以后的更换。如果必须在没有此信息的情况下识别故障驱动器,请使用 gpart listsmartctl 获取磁盘的序列号和制造商,然后在机箱中搜索该驱动器。这是第0章中讨论的相同过程,相反,增加了计划外停机的压力。最糟糕的情况是,可能无法读取到坏硬盘的序列号等信息,就只能找到所有好的磁盘的序列号,再用排除法找到损坏的磁盘。

现在你不希望你事先做好这项工作吗?

一旦找到故障驱动器并安排更换,我们就可以开始使用ZFS。

故障的驱动器

使用 zpool replace 命令从弹性VDEV中删除驱动器并更换新驱动器。旧驱动器不必出现故障,也可能是想要更换的健康驱动器。

以下示例是一个驱动器损坏的RAID-Z1池:

/var/log/messages 日志包含了大量关于 gpt/zfs3 物理磁盘错误的警告。这个磁盘需要从机器中取出。使用 zpool replace 命令从VDEV中删除出现故障的提供者,并用新的设备替换它:

这个命令可能会耗费较长时间,取决于磁盘的容量和速度以及磁盘上的数据量。可以使用 zpool status db 查看替换状态:

给出的重建(resilver)时间估计假设磁盘活动恒定,在重建过程中启动大型数据库转储会延迟同步时间。

更换同一插槽

如果磁盘阵列已满,并且没有多余的插槽供新硬盘插入。必须物理移除失效的硬盘,将新硬盘插入到空出的位置,对新硬盘进行分区并标记它,然后替换提供者。这只是稍微复杂一些。

然而,这样做有更多风险。使用 zpool replace 命令,出现故障的提供者将尽可能保持在线,直到重建完成。如果在重建过程中RAID-Z1丢失了第二块提供者,则池有可能具有足够的数据完整性而生存下来。如果在开始重建之前就更换掉有故障的提供者,则完全失去该安全性。不过,如果硬件不能提供更安全的更换所需的灵活性,则可能需要从备份中恢复数据。

首先让失效的提供者脱机,此操作会通知ZFS停止尝试对设备进行读写操作:

现在,可以从阵列中取出故障驱动器,并安装替换驱动器。根据需要对新提供者进行分区,如果不确定分区,可以使用 gpart backup da0|gprat restore da9 命令将现有磁盘的分区表复制到新磁盘上。在 zpool replace 中使用新的提供者标签。如果新的提供者上的标签与删除的驱动器上的标签相同,则不必重复提供者名称。以下示例中,我们将 gpt/zfs3 替换为一个新的磁盘,也标记为 gpt/zfs3

如果按照第0章中的建议,按序列号标记磁盘,则不会出现此问题。

更换不可用设备

如果设备状态为 UNAVAIL ,ZFS使用GUID标记丢失的设备,并在旁边给出提供者设备的名称。zpool还能继续工作,但确实需要更换设备了。

安装一个新的驱动器,它在 /var/run/dmesg.boot 中显示为 da5 ,并在上面创建了一个 freebsd-zfs 分区。这个新的提供者获得了GPT标签zfs3。池不会自动将此提供者标识为替代品,它知道以前的提供者是 /dev/gpt/zfs3 ,但新的 /dev/gpt/zfs3 缺少将其标识为ZFS卷的磁盘元数据。

要将此新提供者插入zpool,应再次使用 zpool replace 命令,使用GUID而不是之前的设备名称:

检查池状态,会显示重建开始了。如果重建完成,池就完全恢复了。

更换镜像提供者

有时,一个磁盘并没有完全失败,但会产生大量错误,很明显它快坏了。当此磁盘位于镜像虚拟设备中时,在添加替换磁盘时,最好将发生故障的提供者保留在原位,这可以最大限度地提高整个更换过程中的冗余度。它确实要求您的硬件能够使用三个磁盘,而不是通常的两个磁盘。如果系统只能使用两块硬盘,则最好使用在 zpool replace 命令来完成。

本示例中我们有一个单镜像VDEV,它由两个硬盘组成,gpt/zfs0gpt/zfs1 。我们必须替换掉 gpt/zfs0 ,新硬盘是 gpt/zfs2 。与其直接使用 zpool replace 命令,不如先将替换磁盘附加到池。zpool attach 命令告诉池添加一个镜像到池:

这里我们附加了一个提供者到池 db 。已经存在的一个提供者是 gpt/zfs1 ,我们附加了 gpt/zfs2 。关注 zpool status db ,可以看到池在重建。当新的提供者同步完数据后,从虚拟设备移除失效的提供者。

失效的磁盘 gpt/zfs0 就不再被使用了。

也可以使用zpool attach命令将单磁盘池转换称镜像虚拟设备。

重新连接不可用和已删除的驱动器

UNAVAIL 驱动器可能没有发生灾难性故障,可能只是没有插电。尝试晃动驱动器托盘,如果驱动器重新亮起,就可以告诉zpool重新激活磁盘。也可以重新激活状态为 REMOVED 的驱动器。在任何情况下,都可以使用 zpool online 命令、池名称和缺少的提供者的GUID。

ZFS将恢复重新激活的驱动器并恢复正常功能。

日志和缓存设备维护

建议使用高耐久性(high-endurance)SSD驱动器组成ZFS Intent Log(写缓存)和L2ARC(读缓存)。high endurance(高耐久性)和high enough endurance(足够高的耐久性)是不同的,你可能需要更换设备。日志设备使用与常规存储提供者相同的状态关键字,比如faultedoffline 等。你可能还需要插入日志设备,或者删除日志设备(不太常见)。

虽然下面示例中只显示了日志设备,但缓存设备的工作方式完全相同。

添加日志或缓存设备

使用 zpool add 命令可以添加日志或缓存设备。例如:

以上示例向 db 池添加日志设备 gpt/zlog0 。池会立即使用新的日志或缓存。

可以使用 mirror 关键字添加镜像的log设备。镜像的ZIL提供冗余的写入,有助于保证写入磁盘的数据在硬件故障中幸存下来。下面示例,我们镜像设备 gpt/zlog0gpt/zlog1 ,并告诉池数据库将镜像用作日志设备。

通常,镜像cache并不能很好的利用快速磁盘。条带缓存跨多个设备可以减少单个设备的负载,从而降低故障的可能性。

移除日志和缓存设备

从ZFS池中移除日志或缓存时,ZFS会停止向日志写入新数据,清除日志中的数据缓冲区,并释放设备。

使用 zpool remove 命令可移除独立的日志或缓存设备。

删除镜像日志设备稍微复杂一些。必须知道镜像名称,然后才能删除它。请查看池状态。

日志设备称为mirror-2。像删除独立设备一样删除它。

池清理日志并将设备从池中移除。

替换失效的日志和缓存设备

与更换任何其他故障设备一样,更换故障日志或缓存设备,甚至镜像成员。在这里,我们将设备 gpt/zlog0 替换为 gpt/zlog2

日志设备将重建并启用。

导出和导入驱动器

您可以在机器之间移动ZFS文件系统驱动器,甚至可以在运行不同操作系统的机器之间移动。您不局限于类似的架构,ZFS甚至允许您在不同的端接硬件之间移动磁盘!这为Sparc OpenSolaris和FreeBSD之间的迁移提供了一条简单的路径。ZFS使用自己的磁盘元数据来跟踪池中每个提供程序的角色,因此您不需要跟踪驱动器顺序、设备节点或任何常见的磁盘问题。拔下驱动器的插头,将其放入包中,驾车穿过城镇,然后重新插入电源。将池恢复在线称为导入(importing)。

然而,ZFS可以在磁盘以外的存储提供者上运行。假设您在ZFS磁盘上使用GPT磁盘分区,正如我们建议的那样。然后,您可以决定将这些磁盘从FreeBSD主机移动到另一个操作系统或另一个硬件体系结构。如果新的操作系统或硬件不能识别GPT分区,新主机将无法找到池来导入它们!

然而,在导入池之前,必须将其导出。

导出池

导出,大致类似于干净地卸载传统文件系统。ZFS将提供者标记为非活动状态,并完成所有待处理的交易。如果有ZIL,则该日志将被清除。所有内容都写入提供者,文件系统被卸载,系统会收到通知,这些提供者可以自由重用。

使用 zpool export 导出池:

此命令静默(silently)运行,没有任何提示就表示正常导出。可以使用 zpool list 命令检查池是否还存在。

系统会拒绝导出活动的文件系统。关闭所有写入数据集的守护进程,并将shell的工作目录更改为远离数据集。停止跟踪(tailing)文件。可以使用 fstat(1)isof(8) 命令来识别使用该数据集上的文件系统进程。

导入池

使用 zpool import 可以查看连接到系统的非活动池。这实际上并不会导入任何池,而只是显示可用于导入的内容。

以上显示池 db 可以被导入。id 后面的长数字是标识符。您在底部看到的池配置与活动池的配置完全相同。

状态 ONLINE 并不意味着池是活动的,而是说明提供者处于备用状态。据ZFS所知,该池已准备就绪。

使用 zpool import 命令指定池名称或数字ID导入池:

如果有多个同名的非活动池,可以按数字ID导入:

如果具有该名称的池已存在,则不能导入该池,除非重命名该池。

重命名导入的池

我们中的一些人在机器之间重用池名称。当Lucas需要数据库的专用池时,他总是将其称为 db ,因为它很短,而且他很懒。这对于标准化非常有用,每个人都知道数据库文件的确切位置。然而,当将磁盘移动到另一台机器上时,这是一种烦恼。每台计算机只能具有每个名称的一个池。

ZFS允许通过在现有名称后提供新名称来永久重命名池。在这里,我们以 olddb 的名称导入名为 db 的池。

可以在 /olddb 中找到导入池中的数据集。这些重命名是永久的。可以永远使用池的新名称导出和重新导入池。

要在池的通常挂载点以外的位置临时挂载池,请使用 –R 标志和备用根路径。

这会将路径 /dunno 临时添加到导入池中的所有数据集。导出池将删除额外的路径并取消设置 altroot 属性。

当您不知道池中有什么,并且不想偶然将其覆盖在现有数据集或文件系统上时,请使用 altroot 属性。

记住,BSD文件系统是可以堆叠的。可以在另一种引导环境中使用它,在这种环境中,导入的池可能会覆盖正在运行的根文件系统,并隐藏管理池所需要的工具

不完整的池

如果池没有足够的成员来提供所有所需的数据,则无法导入池。就像在缺少两个磁盘的情况下不能使用RAID-Z1一样,也不能导入缺少多个磁盘的RAID-Z1。

以上是一个四提供者组成的RAID-Z1,但是两个提供者丢失了。检查重新安装的磁盘是否已正确连接,然后重试。

特殊导入

池导入在从损坏的系统中恢复时非常有用。ZFS允许您在导入池时解决许多错误和问题。本节将介绍导入的一些特殊情况。

销毁池并不会销毁数据。仅仅是将池标记为消除,但是池和其中的数据还保存在硬盘上,直到被覆写。使用 -D 选项告诉ZFS查找已销毁但可以导入的池。

如果已销毁的池状态显示ONLINE(DESTROYED),则表示该池拥有运行所需的一切。使用 -D 选项可以将其复活。

如果池缺少太多的存储提供程序,则无法导入它。您不能使用 zpool online 分离驱动器。检查驱动器托盘,并确保要导入的驱动器已连接并通电。下次运行 zpool import 时,重新连接的驱动器将显示。

如果池缺少其日志设备,请添加 -m 标志以在没有该设备的情况下导入它。导出池应具有存储提供程序上的所有内容。

可以在导入时使用 -o 标志设置池属性。在这里,我们导入和重命名数据库池,并将其设置为只读。

现在,可以从旧池中复制文件,而不会损坏数据的原始副本。

您可能希望导入损坏的池,以尝试恢复其中的部分数据。–F 标志告诉 zpool import 回滚最后几个事务。这可能会将池返回到可导入状态。您将丢失回滚事务的内容,但如果这样做有效,这些事务很可能会导致您的问题。

更大的提供者

关于ZFS的一个有趣的事实是,它允许用较大的提供者替换提供者。如果冗余存储池使用4 TB磁盘,则可以将其替换为10 TB型号,并增加池的大小。这需要用较大的提供者替换连续的提供者。

池通过每个VDEV中的最小磁盘来计算其大小。如果您的镜像在单个VDEV中具有4 TB磁盘和10 TB磁盘,则镜像VDEV将只有4 TB空间。没有明智的方法在4 TB磁盘上镜像10 TB的数据!然而,如果更换4 TB磁盘,您将能够将镜像扩展到最小磁盘的大小。

要问的一个问题是:您希望池在可以时自动扩展,还是希望手动激活扩展?ZFS可以自动使扩展工作,但您需要在启动之前为每个池设置 autoexpand 属性。ZFS默认情况下不使用该选项,因为您永远不能收缩池。(必须启用 autoexpand 不会对您造成伤害,但默认情况下启用它可能会使池对于任何其他磁盘来说太大。)

如果没有此属性集,则必须在替换提供者后运行命令来扩展池。

替换池中的所有提供者并不复杂,但它确实涉及一定程度的乏味。使用具有三个提供程序的RAID-Z1池。

每个提供者都是单独的小磁盘。

如果硬件有足够的物理空间,可添加新的驱动器并创建替换提供者。如果物理空间不足,可关闭提供者并更换磁盘。本例中脱机并更换驱动器。

此池有三个提供者:gpt/zfs1gpt/zfs2gpt/zfs3。先替换 gpt/zfs1,使用 gpart show -l 显示提供者是设备da1。

如果需要离线设备并添加替换设备,首先要确定驱动器da1的物理位置。根据硬件要求准备替换驱动器,然后将提供者脱离池。

此命令应该是静默执行的。使用 zpool status 检查提供者是否离线。然后将硬盘移出系统。

将替换驱动器插入到卸下旧驱动器的空间或新插槽中。新设备将出现在 /var/run/dmesg.boot 中。本例中,新设备显示为 /dev/da4 。在该驱动器上创建所需的分区并为其添加标签。如果标签中没有使用序列号,而是仅按物理位置进行标签,则可以使用相同的标签。(同样的,我们在这里使用这些短标签,因为它们在学习时更容易阅读。)

现在告诉池更换故障设备。

在替换任何其他提供程序之前,让池完成重建。在重建过程中更换非冗余单元只会导致疼痛。如果您正在使用RAID-Z2或RAID-Z3,则可以同时更换多个磁盘,但这是有风险的。额外的磁盘故障可能会使VDEV失败。没有额外提供者提供的冗余,ZFS无法自行修复。每个磁盘的I/O限制可能会限制重建速度。

在您的第一个提供者重建完成后,更换下一个较小的提供者。在更换VDEV中的每个提供者之前,您将不会看到磁盘空间的变化。要确保已将每个提供者都替换为较大的提供者,请检查 zpool list

EXPANDSZ 表示池可以扩展到的最大尺寸。这个池可以扩展。

如果在开始之前将设置为自动扩展,它应该会自动增长。如果没有,可使用 zpool online -e 手动扩展池中的每个设备:

这个池现在有更多的空间。

Zpool版本和升级

FreeBSD和OpenZFS团队不断改进他们的软件,为ZFS和FreeBSD的ZFS支持添加新功能。其中一些改进需要对zpools进行更改或添加。当您升级主机的操作系统时,主机可能会获得现有池不支持的ZFS功能。在使用这些新功能之前,必须升级存储池。如果您不升级池,池将继续运行,但它们将无法利用需要更改磁盘格式的新功能。

但是,在升级操作系统时,您可能会选择不升级池。如果您要将系统从FreeBSD 11升级到FreeBSD 12,您可能会将磁盘保留为FreeBSD 11的池格式。如果需要回滚升级,操作系统仍将能够读取池。操作系统升级是可逆的。但池升级是不可逆的

ZFS版本和功能标志

最初,ZFS使用版本号来指示支持的池或操作系统版本的功能。版本号从1开始,每改进一次ZFS(涉及磁盘格式),就会增加一个版本号。当Sun Microsystems担任所有ZFS开发的中央协调人时,一个递增的版本号是有意义的。OpenZFS中的版本号设置为5000,池使用功能标志。我们在第3章中详细讨论了特征标志。

功能标志的两个问题是:“您的池目前支持哪些功能?”和“您的操作系统支持哪些功能?”检查池属性以查看磁盘上的内容,如第3章所述。要查看FreeBSD版本支持的所有功能标志,请运行 zpool upgrade -v

标记为“read-only compatible”的功能意味着不支持这些功能标志的主机可以导入这些池,但只能作为只读。有关在主机之间移动池的讨论,请参阅本章前面的“池导入和导出”。

每个版本的FreeBSD发行说明都指出了ZFS的新功能。在升级之前,你确实仔细阅读了发行说明,是吗?如果您以某种方式错过了文档的这一部分, zpool status 告诉您哪些池可以使用升级。(记住,仅仅因为池可以进行升级并不意味着你应该进行升级。如果你可能需要还原操作系统升级,请保留池原有功能!)

您还将获得升级支持的新功能列表。通过在池上运行 zpool upgrade 来升级您的池。

池升级将不可逆地向现有池布局添加新字段。然而,升级不会重写现有数据。虽然新功能可能存在问题,但磁盘上仅提供该功能标志的风险非常低。

如果您计划将磁盘移动到运行旧操作系统的系统,或移动到运行OpenZFS旧版本的操作系统,则可以更有选择地启用池功能。将磁盘从FreeBSD 11系统移动到FreeBSD 10系统需要仔细检查池功能。通过将单个功能的属性设置为 enabled 来启用该功能。

此池现在支持 large_blocks 功能。

Zpool升级和引导加载程序

FreeBSD的引导加载程序必须了解您从中引导的ZFS池。这意味着它必须识别池的特征。每当更新包含 /boot 文件系统的池时,都必须更新磁盘上的引导加载程序。使用 gpart(8) 更新引导加载程序。如果从磁盘da0和da1上的ZFS镜像启动,您将按如下方式更新这两个磁盘上的加载器:

没有此更新,系统可能无法启动。 zpool upgrade 命令会打印一个提醒以执行更新,但如果你愿意,可以忽略它。如果您使系统无法启动,您可能会尝试从最新的FreeBSD-current ISO或 live CD启动,并将其引导加载程序复制到您的系统。

FreeBSD ZFS 池限制

FreeBSD还不支持ZFS的所有功能。由于FreeBSD和Solaris架构之间的根本差异,大多数不受支持的功能都无法工作。人们正在积极开发解决方案,让FreeBSD支持ZFS的所有功能。我们预计其中一些将在本书出版后得到支持。

此时,热备盘不起作用。热备盘使ZFS能够自动将故障驱动器与系统上分配的备用驱动器进行交换。这取决于即将到来的 zfsd(8) 实现,该实现仍在进行中。

现在,您可以用数据填充池并修复硬件,让我们使用ZFS的几个更有用的功能,克隆和快照。