Oracle Solaris ZFS 管理指南

第 11 章 Oracle Solaris ZFS 故障排除和池恢复

本章介绍如何确定 ZFS 故障以及如何从相应故障中恢复。还提供了有关预防故障的信息。

本章包含以下各节:

确定 ZFS 故障

作为组合的文件系统和卷管理器,ZFS 可以呈现许多不同的故障。本章首先概述各种故障,然后讨论如何在正运行的系统上确定各种故障。本章最后讨论如何修复问题。ZFS 可能遇到三种基本类型的错误:

请注意,单个池可能会遇到所有这三种错误,因此完整的修复过程依次查找和更正各个错误。

ZFS 存储池中缺少设备

如果某设备已从系统中彻底删除,则 ZFS 会检测到该设备无法打开,并将其置于 REMOVED(已删除)状态。这一删除可能会导致整个池变得不可用,但也可能不会,具体取决于池的数据复制级别。如果镜像设备或 RAID-Z 设备中的一个磁盘被删除,仍可以继续访问池。在下列情况下,池可能会发生故障 (FAULTED),即无法访问数据,除非重新安装设备:

ZFS 存储池中的设备已损坏

“损坏”一词涵盖各种可能出现的错误。以下是错误示例:

在一些情况下,这些错误是瞬态的,如控制器出现问题时的随机 I/O 错误。在另外一些情况下,损坏是永久性的,如磁盘损坏。但是,若损坏是永久性的,则并不一定表明该错误很可能会再次出现。例如,如果管理员意外覆写了磁盘的一部分,且未出现某种硬件故障,则不需要替换该设备。准确确定设备的问题不是一项轻松的任务,在稍后的一节中将对此进行更详细的介绍。

ZFS 数据已损坏

一个或多个设备错误(指示一个或多个设备缺少或已损坏)影响顶层虚拟设备时,将出现数据损坏。例如,镜像的一半可能会遇到数千个绝不会导致数据损坏的设备错误。如果在镜像另一面的完全相同位置中遇到错误,则会导致数据损坏。

数据损坏始终是永久性的,因此在修复期间需要特别注意。即使修复或替换底层设备,也将永远丢失原始数据。这种情况通常要求从备份恢复数据。在遇到数据错误时会记录错误,并可以通过常规池清理对错误进行控制,如下一节所述。删除损坏的块后,下一遍清理会识别出数据损坏已不再存在,并从系统中删除该错误的任何记录。

检查 ZFS 文件系统完整性

对于 ZFS,不存在与 fsck 等效的实用程序。此实用程序传统上有两个作用:文件系统修复和文件系统验证。

文件系统修复

对于传统的文件系统,写入数据的方法本身容易出现导致文件系统不一致的意外故障。由于传统的文件系统不是事务性的,因此可能会出现未引用的块、错误的链接计数或其他不一致的文件系统结构。添加日志记录确实解决了其中的一些问题,但是在无法回滚日志时可能会带来其他问题。ZFS 配置中的磁盘上存在不一致数据的唯一原因是出现硬件故障(在这种情况下,应该已创建冗余池)或 ZFS 软件中存在错误。

fsck 实用程序可以解决 UFS 文件系统特有的已知问题。大多数 ZFS 存储池问题一般都与硬件故障或电源故障有关。使用冗余池可以避免许多问题。如果硬件故障或断电导致池损坏,请参见修复 ZFS 存储池范围内的损坏

如果没有冗余池,则始终存在因文件系统损坏而造成无法访问某些或所有数据的风险。

文件系统验证

除了文件系统修复外,fsck 实用程序还能验证磁盘上的数据是否没有问题。过去,此任务要求取消挂载文件系统并运行 fsck 实用程序,在该过程中可能会使系统进入单用户模式。此情况导致的停机时间的长短与所检查文件系统的大小成比例。ZFS 提供了一种对所有不一致性执行常规检查的机制,而不是要求显式实用程序执行必要的检查。此功能称为清理,在内存和其他系统中经常将它用作一种在错误导致硬件或软件故障之前检测和防止错误的方法。

控制 ZFS 数据清理

每当 ZFS 遇到错误时(不管是在清理中还是按需访问文件时),都会在内部记录该错误,以便您可以快速查看池中所有已知错误的概览信息。

显式 ZFS 数据清理

检查数据完整性的最简单的方法是,对池中所有数据启动显式清理操作。此操作对池中的所有数据遍历一次,并验证是否可以读取所有块。尽管任何 I/O 的优先级一直低于常规操作的优先级,但是清理以设备所允许的最快速度进行。虽然进行清理时池数据应该保持可用而且几乎都做出响应,但是此操作可能会对性能产生负面影响。要启动显式清理,请使用 zpool scrub 命令。例如:


# zpool scrub tank

使用 zpool status 命令可以显示当前清理操作的状态。例如:


# zpool status -v tank
  pool: tank
 state: ONLINE
 scrub: scrub completed after 0h7m with 0 errors on Tue Tue Feb  2 12:54:00 2010
config:
        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            c1t0d0  ONLINE       0     0     0
            c1t1d0  ONLINE       0     0     0

errors: No known data errors

每个池一次只能发生一个活动的清理操作。

可通过使用 -s 选项来停止正在进行的清理操作。例如:


# zpool scrub -s tank

在大多数情况下,旨在确保数据完整性的清理操作应该一直执行到完成。如果清理操作影响了系统性能,您可以自行决定停止清理操作。

执行常规清理可以保证对系统上所有磁盘执行连续的 I/O。常规清理具有副作用,即阻止电源管理将空闲磁盘置于低功耗模式。如果系统通常一直执行 I/O,或功耗不是重要的考虑因素,则可以安全地忽略此问题。

有关解释 zpool status 输出的更多信息,请参见查询 ZFS 存储池的状态

ZFS 数据清理和重新同步

替换设备时,将启动重新同步操作,以便将正确副本中的数据移动到新设备。此操作是一种形式的磁盘清理。因此,在给定的时间,池中只能发生一个这样的操作。如果清理操作正在进行,则重新同步操作会暂停当前清理,并在重新同步完成后重新启动清理操作。

有关重新同步的更多信息,请参见查看重新同步状态

解决 ZFS 问题

以下各节介绍如何确定并解决 ZFS 文件系统或存储池中的问题:

可以使用以下功能来确定 ZFS 配置所存在的问题:

大多数 ZFS 故障排除工作都会涉及到 zpool status 命令。此命令对系统中的各种故障进行分析并确定最严重的问题,同时为您提供建议的操作和指向知识文章(用于获取更多信息)的链接。请注意,虽然池可能存在多个问题,但是此命令仅确定其中的一个问题。例如,数据损坏错误一般意味着一台设备发生故障,但更换故障设备可能无法解决所有数据损坏问题。

此外,ZFS 诊断引擎也会诊断和报告池故障和设备故障。另外还会报告与这些故障关联的校验和、I/O、设备和池错误。fmd 报告的 ZFS 故障在控制台上以及系统消息文件中显示。在大多数情况下,fmd 消息会指示您查看 zpool status 命令的输出,以便获得进一步的恢复说明。

基本的恢复过程如下所示:

本节介绍如何解读 zpool status 输出,以便诊断可能出现的故障类型。尽管大多数工作是由命令自动执行的,但是准确了解所确定的问题以便诊断故障是很重要的。后续部分将介绍如何解决可能遇到的各种问题。

确定 ZFS 存储池中是否存在问题

确定系统上是否存在任何已知问题的最简单的方法是使用 zpool status -x 命令。此命令仅对出现问题的池进行说明。如果系统中不存在运行状态不佳的池,该命令将显示以下信息:


# zpool status -x
all pools are healthy

如果没有 -x 标志,则该命令显示所有池(如果在命令行上指定了池,则为请求的池)的完整状态,即使池的运行状况良好也是如此。

有关 zpool status 命令的命令行选项的更多信息,请参见查询 ZFS 存储池的状态

查看 zpool status 输出

完整的 zpool status 输出与以下内容类似:


# zpool status tank
# zpool status tank
  pool: tank
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
   see: http://www.sun.com/msg/ZFS-8000-2Q
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c1t0d0  ONLINE       0     0     0
            c1t1d0  UNAVAIL      0     0     0  cannot open

errors: No known data errors

以下介绍此输出:

总体池状态信息

zpool status 输出中的这一部分包含以下字段(其中一些字段仅针对出现问题的池显示):

pool

确定池的名称。

state

指示池的当前运行状况。此信息仅指池提供必要复制级别的能力。

status

描述池存在的问题。如果未发现错误,则省略此字段。

action

建议用于修复错误的操作。如果未发现错误,则省略此字段。

see

对包含详细修复信息的知识文章的引用。在线文章的更新频率高于本指南的更新频率。因此,务必参考这些文章以了解最新的修复程序。如果未发现错误,则省略此字段。

scrub

确定清理操作的当前状态,它可能包括完成上一清理的日期和时间、正在进行的清理或者是否未请求清理。

errors

确定是否存在已知的数据错误。

池配置信息

zpool status 输出中的 config 字段说明池中的设备的配置,以及设备的状态和设备产成的任何错误。其状态可以是以下状态之一: ONLINEFAULTEDDEGRADEDUNAVAILOFFLINE。如果状态是除 ONLINE 之外的任何状态,则说明池的容错能力已受到损害。

配置输出的第二部分显示错误统计信息。这些错误分为以下三类:

这些错误可用于确定损坏是否是永久性的。小量 I/O 错误数可能指示临时故障,而大量 I/O 错误则可能指示设备出现了永久性问题。这些错误不一定对应于应用程序所解释的数据损坏。如果设备处于冗余配置中,则设备可能显示无法更正的错误,而镜像或 RAID-Z 设备级别上不显示错误。这种情况下,ZFS 成功检索到良好的数据并试图利用现有副本修复受损数据。

有关解释这些错误的更多信息,请参见确定设备故障的类型

最后,在 zpool status 输出的最后一列中显示其他辅助信息。此信息是对 state 字段的详述,以帮助诊断故障。如果设备处于 FAULTED 状态,则此字段指示是否无法访问设备或者设备上的数据是否已损坏。如果设备正在进行重新同步,则此字段显示当前的进度。

有关监视重新同步进度的信息,请参见查看重新同步状态

清理状态

zpool status 输出的清理部分说明任何显式清理操作的当前状态。此信息不是用于指示系统上是否检测到任何错误,但是可以利用此信息来判定数据损坏错误报告的准确性。如果上一清理是最近结束的,则很可能已发现任何已知的数据损坏。

清理完成消息可在系统重新引导后存留下来。

有关数据清理以及如何解释此信息的更多信息,请参见检查 ZFS 文件系统完整性

数据损坏错误

zpool status 命令还显示是否有已知错误与池关联。在数据清理或常规操作期间,可能已发现这些错误。ZFS 将与池关联的所有数据错误记录在持久性日志中。每当系统的完整清理完成时,都会轮转此日志。

数据损坏错误始终是致命的。出现这种错误表明至少一个应用程序因池中的数据损坏而遇到 I/O 错误。冗余池中的设备错误不会导致数据损坏,而且不会被记录在此日志中。缺省情况下,仅显示发现的错误数。使用 zpool status -v 选项可以列出带有详细说明的完整错误列表。例如:


# zpool status -v
  pool: tank
 state: UNAVAIL
status: One or more devices are faulted in response to IO failures.
action: Make sure the affected devices are connected, then run 'zpool clear'.
   see: http://www.sun.com/msg/ZFS-8000-HC
 scrub: scrub completed after 0h0m with 0 errors on Tue Feb  2 13:08:42 2010
config:

        NAME        STATE     READ WRITE CKSUM
        tank        UNAVAIL      0     0     0  insufficient replicas
          c1t0d0    ONLINE       0     0     0
          c1t1d0    UNAVAIL      4     1     0  cannot open

errors: Permanent errors have been detected in the following files: 

/tank/data/aaa
/tank/data/bbb
/tank/data/ccc

也可使用 fmd 在系统控制台上和 /var/adm/messages 文件中显示类似的消息。还可以使用 fmdump 命令跟踪这些消息。

有关解释数据损坏错误的更多信息,请参见确定数据损坏的类型

ZFS 错误消息的系统报告

除了持久跟踪池中的错误外,ZFS 还在发生相关事件时显示系统日志消息。以下情况将生成事件以通知管理员:

如果 ZFS 检测到设备错误并自动从其恢复,则不进行通知。这样的错误不会造成池冗余或数据完整性方面的故障。并且,这样的错误通常是由伴随有自己的一组错误消息的驱动程序问题导致的。

修复损坏的 ZFS 配置

ZFS 在根文件系统中维护活动池及其配置的高速缓存。如果此高速缓存文件损坏或者不知何故变得与磁盘上所存储的配置信息不同步,则无法再打开池。虽然底层存储设备的质量始终可能会带来任意的损坏,但是 ZFS 会尽量避免出现此情况。此情况通常会导致池从系统中消失(它原本应该是可用的)。此情况还可能表现为不是一个完整的配置,缺少数量不明的顶层虚拟设备。在这两种情况下,都可以通过先导出池(如果它确实是可见的)再重新导入它来恢复配置。

有关导入和导出池的信息,请参见迁移 ZFS 存储池

解决缺少设备的问题

如果设备无法打开,则它在 zpool status 输出中显示为 UNAVAIL状态。此状态表示在首次访问池时 ZFS 无法打开设备,或者设备自那时以来已变得不可用。如果设备导致顶层虚拟设备不可用,则无法访问池中的任何内容。此外,池的容错能力可能已受到损害。无论哪种情况,只需要将设备重新附加到系统即可恢复正常操作。

例如,设备出现故障后,可能会在 fmd 的输出中看到与以下内容类似的消息:


SUNW-MSG-ID: ZFS-8000-FD, TYPE: Fault, VER: 1, SEVERITY: Major
EVENT-TIME: Thu Jun 24 10:42:36 PDT 2010
PLATFORM: SUNW,Sun-Fire-T200, CSN: -, HOSTNAME: neo2
SOURCE: zfs-diagnosis, REV: 1.0
EVENT-ID: a1fb66d0-cc51-cd14-a835-961c15696fcb
DESC: The number of I/O errors associated with a ZFS device exceeded
acceptable levels.  Refer to http://sun.com/msg/ZFS-8000-FD for more information.
AUTO-RESPONSE: The device has been offlined and marked as faulted.  An attempt
will be made to activate a hot spare if available. 
IMPACT: Fault tolerance of the pool may be compromised.
REC-ACTION: Run 'zpool status -x' and replace the bad device.

要查看有关设备问题和解决办法的更详细信息,请使用 zpool status -x 命令。例如:


# zpool status -x
  pool: tank
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
   see: http://www.sun.com/msg/ZFS-8000-2Q
 scrub: scrub completed after 0h0m with 0 errors on Tue Feb  2 13:15:20 2010
config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c1t0d0  ONLINE       0     0     0
            c1t1d0  UNAVAIL      0     0     0  cannot open

errors: No known data errors

从此输出中可以看到,缺少的设备 c1t1d0 不起作用。如果您确定该设备有问题,请予以替换。

然后,使用 zpool online 命令将替换的设备联机。例如:


# zpool online tank c1t1d0

最后一步是确认设备更换后的池正常运行。例如:


# zpool status -x tank
pool 'tank' is healthy

以物理方式重新附加设备

重新附加缺少的设备的具体方式取决于相关设备。如果设备是网络连接驱动器,则应该恢复与网络的连接。如果设备是 USB 设备或其他可移除介质,则应该将它重新附加到系统。如果设备是本地磁盘,则控制器可能已出现故障,以致设备对于系统不再可见。在这种情况下,应该替换控制器,以使磁盘重新可用。可能存在其他问题,具体取决于硬件的类型及其配置。如果驱动器出现故障,且对系统不再可见,则应该将该设备视为损坏的设备。按照更换或修复损坏的设备中概述的过程进行操作。

将设备可用性通知 ZFS

将设备重新附加到系统后,ZFS 可能会也可能不会自动检测其可用性。如果池以前是有故障的,或者在附加过程中重新引导了系统,则 ZFS 在尝试打开池时会自动地重新扫描所有驱动器。如果在系统运行时池的性能降低且设备已替换,则必须通知 ZFS 设备现在是可用的并可以使用 zpool online 命令重新打开。例如:


# zpool online tank c0t1d0

有关使设备联机的更多信息,请参见使设备联机

更换或修复损坏的设备

本节介绍如何确定设备故障类型、清除瞬态错误和替换设备。

确定设备故障的类型

术语损坏的设备相当含糊,它可以用来描述许多可能的情况:

准确确定设备的问题可能是一个很困难的过程。第一步是检查 zpool status 输出中的错误计数。例如:


# zpool status -v tpool
  pool: tpool
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
 scrub: scrub completed after 0h0m with 2 errors on Tue Jul 13 11:08:37 2010
config:

        NAME        STATE     READ WRITE CKSUM
        tpool       ONLINE       2     0     0
          c1t1d0    ONLINE       2     0     0
          c1t3d0    ONLINE       0     0     0
errors: Permanent errors have been detected in the following files:

        /tpool/words

错误分为 I/O 错误与校验和错误,这两种错误都指示可能的故障类型。典型操作可预知的错误数非常少(在很长一段时间内只能预知几个错误)。如果看到大量的错误,则此情况可能指示即将出现或已出现设备故障。然而,管理员错误也可能导致错误计数较大。另一信息源是 syslog 系统日志。如果日志显示大量的 SCSI 或光纤通道驱动程序消息,则此情况可能指示出现了严重的硬件问题。如果未生成 syslog 消息,则损坏很可能是瞬态的。

目的是回答以下问题:

此设备上是否可能出现另一错误?

仅出现一次的错误被认为是瞬态的,不指示存在潜在的故障。其持久性或严重性足以指明潜在硬件故障的错误被认为是致命的。由于确定错误类型的行为已超出当前可用于 ZFS 的任何自动化软件的功能范围,因此如此多的操作必须由您(即管理员)手动执行。在确定后,可以执行相应的操作。清除瞬态错误,或者替换出现致命错误的设备。以下几节将介绍这些修复过程。

即使设备错误被认为是瞬态的,仍然可能导致池中出现了无法更正的数据错误。这些错误需要特殊的修复过程,即使认为底层设备运行状况良好或已进行修复也是如此。有关修复数据错误的更多信息,请参见修复损坏的数据

清除瞬态错误

如果认为设备错误是瞬态的(因为它们不大可能影响设备将来的运行状况),则可以安全地清除设备错误,以指示未出现致命错误。要将 RAID-Z 或镜像设备的错误计数器清零,请使用 zpool clear 命令。例如:


# zpool clear tank c1t1d0

此语法清除所有设备错误,并清除与设备关联的任何数据错误计数。

要清除与池中虚拟设备关联的所有错误,并清除与池关联的任何数据错误计数,请使用以下语法:


# zpool clear tank

有关清除池错误的更多信息,请参见清除存储池设备错误

替换 ZFS 存储池中的设备

如果设备损坏是永久性的,或者将来很可能出现永久性损坏,则必须替换该设备。是否可以替换设备取决于配置。

确定是否可以替换设备

对于要替换的设备,池必须处于 ONLINE 状态。设备必须是冗余配置的一部分,或者其运行状况必须良好(处于 ONLINE 状态)。如果设备是冗余配置的一部分,则必须存在可以从其中检索正确数据的足够副本。如果四向镜像中有两个磁盘是有故障的,则可以替换其中任一磁盘(因为运行状况良好的副本是可用的)。但是,如果四向 RAID-Z (raidz1) 虚拟设备中有两个磁盘是有故障的,则两个磁盘都不能替换,因为不存在从其中检索数据的足够副本。如果设备已损坏但处于联机状态,则只要池不处于 FAULTED 状态就可以替换它。但是,除非存在包含正确数据的足够副本,否则会将设备上的任何损坏数据复制到新设备。

在以下配置中,可以替换磁盘 c1t1d0,而且将从完好的副本 c1t0d0 复制池中的任何数据:


    mirror            DEGRADED
    c1t0d0             ONLINE
    c1t1d0             FAULTED

虽然因没有可用的正确副本而无法对数据进行自我修复,但还是可以替换磁盘 c1t0d0

在以下配置中,无法替换任一有故障磁盘。也无法替换 ONLINE 磁盘,因为池本身是有故障的。


    raidz              FAULTED
    c1t0d0             ONLINE
    c2t0d0             FAULTED
    c3t0d0             FAULTED
    c4t0d0             ONLINE

在以下配置中,尽管已将磁盘上存在的错误数据复制到新磁盘,但是任一顶层磁盘都可替换。


c1t0d0         ONLINE
c1t1d0         ONLINE

如果其中一个磁盘是有故障的,则无法执行替换操作,因为池本身是有故障的。

无法替换的设备

如果设备缺失导致池出现故障,或者设备在非冗余配置中包含太多的数据错误,则无法安全地替换设备。如果没有足够的冗余,则不存在可用来恢复损坏设备的正确数据。这种情况下,唯一的选择是销毁池并重新创建配置,然后从备份副本恢复数据。

有关恢复整个池的更多信息,请参见修复 ZFS 存储池范围内的损坏

替换 ZFS 存储池中的设备

确定可以替换设备后,可以使用 zpool replace 命令替换设备。如果要用不同的设备替换损坏的设备,请使用类似以下的语法:


# zpool replace tank c1t1d0 c2t0d0

此命令将数据从损坏的设备或从池中的其他设备(如果处于冗余配置中)迁移到新设备。此命令完成后,将从配置中拆离损坏的设备,此时可以将该设备从系统中移除。如果已移除设备并在同一位置中将它替换为新设备,请使用命令的单设备形式。例如:


# zpool replace tank c1t1d0

此命令接受未格式化的磁盘,适当地将它格式化,然后重新同步其余配置中的数据。

有关 zpool replace 命令的更多信息,请参见替换存储池中的设备


示例 11–1 替换 ZFS 存储池中的设备

以下示例说明如何替换 Oracle Sun Fire x4500 系统上的镜像存储池 tank 中的设备 (c1t3d0)。要在同一位置将磁盘 c1t3d0 替换为新磁盘 (c1t3d0),尝试替换磁盘之前必须取消磁盘配置。基本步骤如下:

以下示例分步显示了替换 ZFS 存储池中的磁盘的过程。


# zpool offline tank c1t3d0
# cfgadm | grep c1t3d0
sata1/3::dsk/c1t3d0            disk         connected    configured   ok
# cfgadm -c unconfigure sata1/3
Unconfigure the device at: /devices/pci@0,0/pci1022,7458@2/pci11ab,11ab@1:3
This operation will suspend activity on the SATA device
Continue (yes/no)? yes
# cfgadm | grep sata1/3
sata1/3                        disk         connected    unconfigured ok
<Physically replace the failed disk c1t3d0>
# cfgadm -c configure sata1/3
# cfgadm | grep sata1/3
sata1/3::dsk/c1t3d0            disk         connected    configured   ok
# zpool online tank c1t3d0
# zpool replace tank c1t3d0
# zpool status tank
  pool: tank
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Tue Feb  2 13:17:32 2010
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            c0t1d0  ONLINE       0     0     0
            c1t1d0  ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            c0t2d0  ONLINE       0     0     0
            c1t2d0  ONLINE       0     0     0
          mirror-2  ONLINE       0     0     0
            c0t3d0  ONLINE       0     0     0
            c1t3d0  ONLINE       0     0     0

errors: No known data errors

请注意,上述 zpool output 可能会在 replacing 标题下显示新磁盘和旧磁盘。例如:


replacing     DEGRADED     0     0    0
  c1t3d0s0/o  FAULTED      0     0    0
  c1t3d0      ONLINE       0     0    0

此文本表示替换过程正在进行,且新磁盘正在重新同步。

如果您打算将一个磁盘 (c1t3d0) 替换为另一个磁盘 (c4t3d0),则只需运行 zpool replace 命令。例如:


# zpool replace tank c1t3d0 c4t3d0
# zpool status
  pool: tank
 state: DEGRADED
 scrub: resilver completed after 0h0m with 0 errors on Tue Feb  2 13:35:41 2010
config:

        NAME             STATE     READ WRITE CKSUM
        tank             DEGRADED     0     0     0
          mirror-0       ONLINE       0     0     0
            c0t1d0       ONLINE       0     0     0
            c1t1d0       ONLINE       0     0     0
          mirror-1       ONLINE       0     0     0
            c0t2d0       ONLINE       0     0     0
            c1t2d0       ONLINE       0     0     0
          mirror-2       DEGRADED     0     0     0
            c0t3d0       ONLINE       0     0     0
            replacing    DEGRADED     0     0     0
              c1t3d0     OFFLINE      0     0     0
              c4t3d0     ONLINE       0     0     0

errors: No known data errors

磁盘替换完成之前,您可能需要多次运行 zpool status 命令。


# zpool status tank
  pool: tank
 state: ONLINE
 scrub: resilver completed after 0h0m with 0 errors on Tue Feb  2 13:35:41 2010
config:

        NAME          STATE     READ WRITE CKSUM
        tank          ONLINE       0     0     0
          mirror-0    ONLINE       0     0     0
            c0t1d0    ONLINE       0     0     0
            c1t1d0    ONLINE       0     0     0
          mirror-1    ONLINE       0     0     0
            c0t2d0    ONLINE       0     0     0
            c1t2d0    ONLINE       0     0     0
          mirror-2    ONLINE       0     0     0
            c0t3d0    ONLINE       0     0     0
            c4t3d0    ONLINE       0     0     0


示例 11–2 更换出现故障的日志设备

以下示例说明如何从存储池 (pool) 中出现故障的日志设备 (c0t5d0) 进行恢复。基本步骤如下:


# zpool status -x
  pool: pool
 state: FAULTED
status: One or more of the intent logs could not be read.
        Waiting for adminstrator intervention to fix the faulted pool.
action: Either restore the affected device(s) and run 'zpool online',
        or ignore the intent log records by running 'zpool clear'.
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        pool        FAULTED      0     0     0 bad intent log
          mirror    ONLINE       0     0     0
            c0t1d0  ONLINE       0     0     0
            c0t4d0  ONLINE       0     0     0
        logs        FAULTED      0     0     0 bad intent log
          c0t5d0    UNAVAIL      0     0     0 cannot open
<Physically replace the failed log device>
# zpool online pool c0t5d0
# zpool clear pool

# zpool status -x
  pool: pool
 state: FAULTED
status: One or more of the intent logs could not be read.
        Waiting for adminstrator intervention to fix the faulted pool.
action: Either restore the affected device(s) and run 'zpool online',
        or ignore the intent log records by running 'zpool clear'.
 scrub: none requested
config:

        NAME          STATE     READ WRITE CKSUM
        pool          FAULTED      0     0     0 bad intent log
          mirror-0    ONLINE       0     0     0
            c0t1d0    ONLINE       0     0     0
            c0t4d0    ONLINE       0     0     0
        logs          FAULTED      0     0     0 bad intent log
          c0t5d0      UNAVAIL      0     0     0 cannot open
<Physically replace the failed log device>
# zpool online pool c0t5d0
# zpool clear pool

查看重新同步状态

替换设备这一过程可能需要很长一段时间,具体取决于设备的大小和池中的数据量。将数据从一个设备移动到另一个设备的过程称为重新同步,可以使用 zpool status 命令监视此过程。

传统的文件系统在块级别上重新同步数据。由于 ZFS 消除了卷管理器的人为分层,因此它能够以更强大的受控方式执行重新同步。此功能的两个主要优点如下:

要查看重新同步过程,请使用 zpool status 命令。例如:


# zpool status tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
 scrub: resilver in progress for 0h0m, 22.60% done, 0h1m to go
config:
        NAME                  STATE     READ WRITE CKSUM 
        tank             DEGRADED     0     0     0
          mirror-0       DEGRADED     0     0     0
            replacing-0  DEGRADED     0     0     0
              c1t0d0     UNAVAIL      0     0     0  cannot open
              c2t0d0     ONLINE       0     0     0  85.0M resilvered
            c1t1d0       ONLINE       0     0     0

errors: No known data errors

在本示例中,磁盘 c1t0d0 被替换为 c2t0d0。通过查看状态输出的配置部分中是否显示有 replacing ,可观察到此替换虚拟设备的事件。此设备不是真正的设备,不可能使用它创建池。此设备的用途仅仅是显示重新同步进度,以及确定被替换的设备。

请注意,当前正进行重新同步的任何池都处于 ONLINEDEGRADED 状态,这是因为在重新同步过程完成之前,池无法提供所需的冗余级别。虽然 I/O 始终是按照比用户请求的 I/O 更低的优先级调度的(以最大限度地减少对系统的影响),但是重新同步会尽可能快地进行。重新同步完成后,该配置将恢复为新的完整配置。例如:


# zpool status tank
  pool: tank
 state: ONLINE
 scrub: resilver completed after 0h1m with 0 errors on Tue Feb  2 13:54:30 2010
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            c2t0d0  ONLINE       0     0     0  377M resilvered
            c1t1d0  ONLINE       0     0     0

errors: No known data errors

池再次处于 ONLINE 状态,而且原故障磁盘 (c1t0d0) 已从配置中删除。

修复损坏的数据

以下各节介绍如何确定数据损坏的类型以及如何修复数据(如有可能)。

ZFS 使用校验和、冗余和自我修复数据来最大限度地减少出现数据损坏的风险。但是,如果没有冗余池,如果将池降级时出现损坏,或者不大可能发生的一系列事件协同损坏数据段的多个副本,则可能会出现数据损坏。不管是什么原因,结果都是相同的: 数据被损坏,因此无法再进行访问。所执行的操作取决于被损坏数据的类型及其相对值。可能损坏以下两种基本类型的数据:

数据是在常规操作期间和清理过程中验证的。有关如何验证池数据完整性的信息,请参见检查 ZFS 文件系统完整性

确定数据损坏的类型

缺省情况下,zpool status 命令仅说明已出现损坏,而不说明出现此损坏的位置。例如:


# zpool status monkey
  pool: monkey
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
 scrub: scrub completed after 0h0m with 8 errors on Tue Jul 13 13:17:32 2010
config:

        NAME        STATE     READ WRITE CKSUM
        monkey      ONLINE       8     0     0
          c1t1d0    ONLINE       2     0     0
          c2t5d0    ONLINE       6     0     0

errors: 8 data errors, use '-v' for a list

每个错误仅指示在给定时间点出现了错误。每个错误不一定仍存在于系统上。一般情况下是如此。某些临时故障可能会导致数据损坏,故障结束后会自动修复。完整的池清理可保证检查池中的每个活动块,因此每当清理完成后都会重置错误日志。如果确定错误不再存在,并且不希望等待清理完成,则使用 zpool online 命令重置池中的所有错误。

如果数据损坏位于池范围内的元数据中,则输出稍有不同。例如:


# zpool status -v morpheus
  pool: morpheus
    id: 1422736890544688191
 state: FAULTED
status: The pool metadata is corrupted.
action: The pool cannot be imported due to damaged devices or data.
   see: http://www.sun.com/msg/ZFS-8000-72
config:

        morpheus    FAULTED   corrupted data
          c1t10d0   ONLINE

如果出现池范围的损坏,池将被置于 FAULTED 状态,这是因为池无法提供所需的冗余级别。

修复损坏的文件或目录

如果文件或目录被损坏,则系统可能仍然正常工作,具体取决于损坏的类型。如果系统中存在完好的数据副本,则任何损坏实际上都是不可恢复的。如果数据具有价值,必须从备份中恢复受影响的数据。即便如此,您也许能够从此损坏中恢复,而不必恢复整个池。

如果损坏出现在文件数据块中,则可以安全地删除该文件,从而清除系统中的错误。使用 zpool status -v 命令可以显示包含持久性错误的文件名列表。例如:


# zpool status -v
  pool: monkey
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
 scrub: scrub completed after 0h0m with 8 errors on Tue Jul 13 13:17:32 2010
config:

        NAME        STATE     READ WRITE CKSUM
        monkey      ONLINE       8     0     0
          c1t1d0    ONLINE       2     0     0
          c2t5d0    ONLINE       6     0     0

errors: Permanent errors have been detected in the following files: 

/monkey/a.txt
/monkey/bananas/b.txt
/monkey/sub/dir/d.txt
monkey/ghost/e.txt
/monkey/ghost/boo/f.txt

包含持久性错误的文件名列表可能描述如下:

如果损坏发生在目录或文件的元数据中,则唯一的选择是将文件移动到别处。可以安全地将任何文件或目录移动到不太方便的位置,以允许恢复原始对象。

修复 ZFS 存储池范围内的损坏

如果损坏位于池元数据,并且该损坏阻止池被打开或导入,则可以使用下列选项:

修复无法引导的系统

根据设计,即使在出错时 ZFS 也是强健而稳定的。尽管这样,在访问池时,软件错误或某些意外问题可能导致系统发出警告音。在引导过程中,必须打开每个池,这意味着这样的故障将导致系统进入应急重新引导循环。为了从此情况恢复,必须通知 ZFS 不要在启动时查找任何池。

ZFS 在 /etc/zfs/zpool.cache 中维护可用池及其配置的内部高速缓存。此文件的位置和内容是专用的,有可能更改。如果系统变得无法引导,则使用 m =none 引导选项引导到 -none 里程碑。系统启动后,将根文件系统重新挂载为可写入,然后重命名 /etc/zfs/zpool.cache 文件或将其移动到其他位置。这些操作使 ZFS 忘记系统上存在池,从而阻止它尝试访问导致问题的有问题池。然后可以通过发出 svcadm milestone all 命令进入正常系统状态。从备用根引导时,可以使用类似的过程执行修复。

系统启动后,可以尝试使用 zpool import 命令导入池。但是,这样做很可能会导致在引导期间出现的相同错误,因为该命令使用相同机制访问池。如果系统中存在多个池,请执行以下操作: