本章介绍如何确定 ZFS 故障以及如何从相应故障中恢复。还提供了有关预防故障的信息。
本章包含以下各节:
作为组合的文件系统和卷管理器,ZFS 可以呈现许多不同的故障。本章首先概述各种故障,然后讨论如何在正运行的系统上确定各种故障。本章最后讨论如何修复问题。ZFS 可能遇到三种基本类型的错误:
请注意,单个池可能会遇到所有这三种错误,因此完整的修复过程依次查找和更正各个错误。
如果某设备已从系统中彻底删除,则 ZFS 会检测到该设备无法打开,并将其置于 REMOVED(已删除)状态。这一删除可能会导致整个池变得不可用,但也可能不会,具体取决于池的数据复制级别。如果镜像设备或 RAID-Z 设备中的一个磁盘被删除,仍可以继续访问池。在下列情况下,池可能会发生故障 (FAULTED),即无法访问数据,除非重新安装设备:
镜像的所有组件都被删除
RAID-Z (raidz1) 设备中有一个以上设备被删除
单磁盘配置中移除了顶层设备
由于损坏的磁盘或控制器而导致的瞬态 I/O 错误
磁盘上的数据因宇宙射线而损坏
导致数据传输至错误目标或从错误源位置传输的驱动程序错误
用户意外地覆写了物理设备的某些部分
在一些情况下,这些错误是瞬态的,如控制器出现问题时的随机 I/O 错误。在另外一些情况下,损坏是永久性的,如磁盘损坏。但是,若损坏是永久性的,则并不一定表明该错误很可能会再次出现。例如,如果管理员意外覆写了磁盘的一部分,且未出现某种硬件故障,则不需要替换该设备。准确确定设备的问题不是一项轻松的任务,在稍后的一节中将对此进行更详细的介绍。
一个或多个设备错误(指示一个或多个设备缺少或已损坏)影响顶层虚拟设备时,将出现数据损坏。例如,镜像的一半可能会遇到数千个绝不会导致数据损坏的设备错误。如果在镜像另一面的完全相同位置中遇到错误,则会导致数据损坏。
数据损坏始终是永久性的,因此在修复期间需要特别注意。即使修复或替换底层设备,也将永远丢失原始数据。这种情况通常要求从备份恢复数据。在遇到数据错误时会记录错误,并可以通过常规池清理对错误进行控制,如下一节所述。删除损坏的块后,下一遍清理会识别出数据损坏已不再存在,并从系统中删除该错误的任何记录。
对于 ZFS,不存在与 fsck 等效的实用程序。此实用程序传统上有两个作用:文件系统修复和文件系统验证。
对于传统的文件系统,写入数据的方法本身容易出现导致文件系统不一致的意外故障。由于传统的文件系统不是事务性的,因此可能会出现未引用的块、错误的链接计数或其他不一致的文件系统结构。添加日志记录确实解决了其中的一些问题,但是在无法回滚日志时可能会带来其他问题。ZFS 配置中的磁盘上存在不一致数据的唯一原因是出现硬件故障(在这种情况下,应该已创建冗余池)或 ZFS 软件中存在错误。
fsck 实用程序可以解决 UFS 文件系统特有的已知问题。大多数 ZFS 存储池问题一般都与硬件故障或电源故障有关。使用冗余池可以避免许多问题。如果硬件故障或断电导致池损坏,请参见修复 ZFS 存储池范围内的损坏。
如果没有冗余池,则始终存在因文件系统损坏而造成无法访问某些或所有数据的风险。
除了文件系统修复外,fsck 实用程序还能验证磁盘上的数据是否没有问题。过去,此任务要求取消挂载文件系统并运行 fsck 实用程序,在该过程中可能会使系统进入单用户模式。此情况导致的停机时间的长短与所检查文件系统的大小成比例。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 配置所存在的问题:
使用 zpool status 命令可以显示 ZFS 存储池的详细信息。
通过 ZFS/FMA 诊断消息报告池和设备故障。
使用 zpool history 命令可以显示以前修改了池状态信息的 ZFS 命令。
大多数 ZFS 故障排除工作都会涉及到 zpool status 命令。此命令对系统中的各种故障进行分析并确定最严重的问题,同时为您提供建议的操作和指向知识文章(用于获取更多信息)的链接。请注意,虽然池可能存在多个问题,但是此命令仅确定其中的一个问题。例如,数据损坏错误一般意味着一台设备发生故障,但更换故障设备可能无法解决所有数据损坏问题。
此外,ZFS 诊断引擎也会诊断和报告池故障和设备故障。另外还会报告与这些故障关联的校验和、I/O、设备和池错误。fmd 报告的 ZFS 故障在控制台上以及系统消息文件中显示。在大多数情况下,fmd 消息会指示您查看 zpool status 命令的输出,以便获得进一步的恢复说明。
基本的恢复过程如下所示:
如果合适,请使用 zpool history 命令错误情况出现以前的 ZFS 命令。例如:
# zpool history tank History for 'tank': 2010-07-15.12:06:50 zpool create tank mirror c0t1d0 c0t2d0 c0t3d0 2010-07-15.12:06:58 zfs create tank/erick 2010-07-15.12:07:01 zfs set checksum=off tank/erick |
在此输出中,注意对 tank/erick 文件系统禁用了校验和。建议不要使用此配置。
通过在系统控制台上或 /var/adm/messages 文件中显示的 fmd 消息来确定错误。
使用 zpool status -x 命令查找进一步的修复说明。
排除故障涉及到以下步骤:
更换故障设备或缺少的设备,并使其联机。
从备份恢复故障配置或损坏的数据。
使用 zpool status -x 命令验证恢复情况。
备份所恢复的配置(如果适用)。
本节介绍如何解读 zpool status 输出,以便诊断可能出现的故障类型。尽管大多数工作是由命令自动执行的,但是准确了解所确定的问题以便诊断故障是很重要的。后续部分将介绍如何解决可能遇到的各种问题。
确定系统上是否存在任何已知问题的最简单的方法是使用 zpool status -x 命令。此命令仅对出现问题的池进行说明。如果系统中不存在运行状态不佳的池,该命令将显示以下信息:
# zpool status -x all pools are healthy |
如果没有 -x 标志,则该命令显示所有池(如果在命令行上指定了池,则为请求的池)的完整状态,即使池的运行状况良好也是如此。
有关 zpool status 命令的命令行选项的更多信息,请参见查询 ZFS 存储池的状态。
完整的 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 输出中的这一部分包含以下字段(其中一些字段仅针对出现问题的池显示):
确定池的名称。
指示池的当前运行状况。此信息仅指池提供必要复制级别的能力。
描述池存在的问题。如果未发现错误,则省略此字段。
建议用于修复错误的操作。如果未发现错误,则省略此字段。
对包含详细修复信息的知识文章的引用。在线文章的更新频率高于本指南的更新频率。因此,务必参考这些文章以了解最新的修复程序。如果未发现错误,则省略此字段。
确定清理操作的当前状态,它可能包括完成上一清理的日期和时间、正在进行的清理或者是否未请求清理。
确定是否存在已知的数据错误。
zpool status 输出中的 config 字段说明池中的设备的配置,以及设备的状态和设备产成的任何错误。其状态可以是以下状态之一: ONLINE、FAULTED、DEGRADED、UNAVAIL 或 OFFLINE。如果状态是除 ONLINE 之外的任何状态,则说明池的容错能力已受到损害。
配置输出的第二部分显示错误统计信息。这些错误分为以下三类:
READ-发出读取请求时出现 I/O 错误
WRITE-发出写入请求时出现 I/O 错误
CKSUM – 校验和错误,意味着设备对读取请求返回损坏的数据
这些错误可用于确定损坏是否是永久性的。小量 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 还在发生相关事件时显示系统日志消息。以下情况将生成事件以通知管理员:
设备状态转换-如果设备变为 FAULTED 状态,则 ZFS 将记录一条消息,指出池的容错能力可能已受到危害。如果稍后将设备联机,将池恢复正常,则将发送类似的消息。
数据损坏-如果检测到任何数据损坏,则 ZFS 将记录一条消息,说明检测到数据损坏的时间和位置。仅在首次检测到数据损坏时才记录此消息。后续访问不生成消息。
池故障和设备故障-如果出现池故障或设备故障,则 Fault Manager 守护进程将通过 syslog 消息以及 fmdump 命令报告这些错误。
如果 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 设备现在是可用的并可以使用 zpool online 命令重新打开。例如:
# zpool online tank c0t1d0 |
有关使设备联机的更多信息,请参见使设备联机。
本节介绍如何确定设备故障类型、清除瞬态错误和替换设备。
位损坏-随着时间的推移,随机事件(如电磁感应和宇宙射线)可能会导致存储在磁盘上的位发生翻转。这些事件相对少见,但是通常足以导致大系统或长时间运行的系统出现潜在的数据损坏。
误导的读取或写入-固件错误或硬件故障可以导致整个块的读取或写入引用磁盘上的不正确位置。这些错误通常是瞬态的,尽管大量此类错误可能指示驱动器有故障。
管理员错误-管理员可能无意中用错误的数据覆写了部分磁盘(如在部分磁盘上复制 /dev/zero),从而导致磁盘上出现永久性损坏。这些错误始终是瞬态的。
临时故障-磁盘可能在某段时间内变得不可用,从而导致 I/O 失败。此情况通常与网络连接设备相关联,尽管本地磁盘也可能遇到临时故障。这些错误可能是也可能不是瞬态的。
劣质或不可靠的硬件–这种情况涵盖故障硬件表现出来的所有各种问题,包括一致的 I/O 错误、故障传输导致随机损坏或任何数量的故障。这些错误通常是永久性的。
脱机的设备-如果设备处于脱机状态,则假定是管理员因该设备有故障而将它置于此状态。将设备置于此状态的管理员可以确定此假定是否正确。
准确确定设备的问题可能是一个很困难的过程。第一步是检查 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 |
有关清除池错误的更多信息,请参见清除存储池设备错误。
如果设备损坏是永久性的,或者将来很可能出现永久性损坏,则必须替换该设备。是否可以替换设备取决于配置。
对于要替换的设备,池必须处于 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 存储池范围内的损坏。
确定可以替换设备后,可以使用 zpool replace 命令替换设备。如果要用不同的设备替换损坏的设备,请使用类似以下的语法:
# zpool replace tank c1t1d0 c2t0d0 |
此命令将数据从损坏的设备或从池中的其他设备(如果处于冗余配置中)迁移到新设备。此命令完成后,将从配置中拆离损坏的设备,此时可以将该设备从系统中移除。如果已移除设备并在同一位置中将它替换为新设备,请使用命令的单设备形式。例如:
# zpool replace tank c1t1d0 |
此命令接受未格式化的磁盘,适当地将它格式化,然后重新同步其余配置中的数据。
有关 zpool replace 命令的更多信息,请参见替换存储池中的设备。
以下示例说明如何替换 Oracle Sun Fire x4500 系统上的镜像存储池 tank 中的设备 (c1t3d0)。要在同一位置将磁盘 c1t3d0 替换为新磁盘 (c1t3d0),尝试替换磁盘之前必须取消磁盘配置。基本步骤如下:
使要替换的磁盘 (c1t3d0) 脱机。您不能取消配置当前正在使用的磁盘。
使用 cfgadm 命令确定要取消配置的磁盘 (c1t3d0) 并取消其配置。如果磁盘在此镜像配置中脱机,该池将降级,但该池将继续可用。
物理替换磁盘 (c1t3d0)。在物理移除故障驱动器之前,请确保蓝色的可以移除 LED 指示灯亮起。
重新配置磁盘 (c1t3d0)。
使新磁盘 (c1t3d0) 联机。
运行 zpool replace 命令以替换磁盘 (c1t3d0)。
如果先前将池属性 autoreplace 设置为 on,则会自动对在先前属于池的设备的同一物理位置处找到的任何新设备进行格式化和替换,而无需使用 zpool replace 命令。此功能可能并不是在所有硬件上都受支持。
如果已使用热备件自动替换了故障磁盘,则您可能需要在替换故障磁盘后分离该热备件。例如,如果替换故障磁盘后,c2t4d0 仍为活动热备件,则对其进行分离。
# zpool detach tank c2t4d0 |
以下示例分步显示了替换 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 |
以下示例说明如何从存储池 (pool) 中出现故障的日志设备 (c0t5d0) 进行恢复。基本步骤如下:
查看 zpool status -x 输出和 FMA 诊断消息。有关说明,请参见以下页面:
物理更换出现故障的日志设备。
使新日志设备联机。
清除池的错误状态。
# 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 消除了卷管理器的人为分层,因此它能够以更强大的受控方式执行重新同步。此功能的两个主要优点如下:
ZFS 仅重新同步最少量的必要数据。如果是短暂的断电(而不是设备替换),整个磁盘可以在几分钟或几秒内重新同步。替换整个磁盘时,重新同步过程所用的时间与磁盘上所用的数据量成比例。如果只使用了池中几 GB 的磁盘空间,则替换 500 GB 的磁盘可能只需要几秒的时间。
重新同步是可中断的和安全的。如果系统断电或者进行重新引导,则重新同步过程会准确地从它停止的位置继续,而无需手动干预。
要查看重新同步过程,请使用 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 ,可观察到此替换虚拟设备的事件。此设备不是真正的设备,不可能使用它创建池。此设备的用途仅仅是显示重新同步进度,以及确定被替换的设备。
请注意,当前正进行重新同步的任何池都处于 ONLINE 或 DEGRADED 状态,这是因为在重新同步过程完成之前,池无法提供所需的冗余级别。虽然 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 需要解析一定量的数据才能打开池和访问数据集。如果此数据被损坏,则整个池或部分数据集分层结构将变得不可用。
对象数据-在这种情况下,损坏发生在特定的文件或目录中。此问题可能会导致无法访问该文件或目录的一部分,或者此问题可能导致对象完全损坏。
数据是在常规操作期间和清理过程中验证的。有关如何验证池数据完整性的信息,请参见检查 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 |
包含持久性错误的文件名列表可能描述如下:
如果找到文件的全路径并且已挂载数据集,则会显示该文件的全路径。例如:
/monkey/a.txt |
如果找到文件的全路径但未挂载数据集,则会显示不带前导斜杠 (/) 的数据集名称,后面是数据集中文件的路径。例如:
monkey/ghost/e.txt |
如果由于错误或由于对象没有与之关联的实际文件路径而导致文件路径的对象编号无法成功转换(dnode_t 便是这种情况),则会显示数据集名称,后跟该对象的编号。例如:
monkey/dnode:<0x0> |
如果元对象集 (Metaobject Set, MOS) 中的对象已损坏,则会显示特殊标签 <metadata>,后跟该对象的编号。
如果损坏发生在目录或文件的元数据中,则唯一的选择是将文件移动到别处。可以安全地将任何文件或目录移动到不太方便的位置,以允许恢复原始对象。
如果损坏位于池元数据,并且该损坏阻止池被打开或导入,则可以使用下列选项:
尝试使用 zpool clear - F 命令或 zpool import -F 命令恢复池。这些命令尝试回滚最后几次池事务,使其回到运行状态。可以使用 zpool status 命令查看损坏的池和建议的恢复步骤。例如:
# zpool status pool: tpool state: FAULTED status: The pool metadata is corrupted and the pool cannot be opened. action: Recovery is possible, but will result in some data loss. Returning the pool to its state as of Wed Jul 14 11:44:10 2010 should correct the problem. Approximately 5 seconds of data must be discarded, irreversibly. Recovery can be attempted by executing 'zpool clear -F tpool'. A scrub of the pool is strongly recommended after recovery. see: http://www.sun.com/msg/ZFS-8000-72 scrub: none requested config: NAME STATE READ WRITE CKSUM tpool FAULTED 0 0 1 corrupted data c1t1d0 ONLINE 0 0 2 c1t3d0 ONLINE 0 0 4 |
上述恢复过程使用以下命令:
# zpool clear -F tpool |
如果您尝试导入损坏的存储池,将会看到类似如下的消息:
# zpool import tpool cannot import 'tpool': I/O error Recovery is possible, but will result in some data loss. Returning the pool to its state as of Wed Jul 14 11:44:10 2010 should correct the problem. Approximately 5 seconds of data must be discarded, irreversibly. Recovery can be attempted by executing 'zpool import -F tpool'. A scrub of the pool is strongly recommended after recovery. |
上述恢复过程使用以下命令:
# zpool import -F tpool Pool tpool returned to its state as of Wed Jul 14 11:44:10 2010. Discarded approximately 5 seconds of transactions |
如果损坏的池位于 zpool.cache 文件中,则系统引导时会发现该问题,并通过 zpool status 命令报告损坏的池。如果该池不在 zpool.cache 文件中,它将无法导入或打开,当您尝试导入该池时,会看到池受损消息。
如果无法用上述池恢复方法恢复池,则必须从备份副本中恢复池及其所有数据。所用的机制通常随池配置和备份策略的不同而有很大差别。首先,保存 zpool status 命令所显示的配置,以便在销毁池后可以重新创建它。然后,使用 zpool destroy -f 命令销毁池。此外,将说明数据集的布局和在本地设置的各种属性的文件保存在某个安全的位置(因为在使池无法访问后此信息将变得无法访问)。使用池配置和数据集布局,可以在销毁池后重新构造完整的配置。然后可以使用任何备份或恢复策略填充数据。
根据设计,即使在出错时 ZFS 也是强健而稳定的。尽管这样,在访问池时,软件错误或某些意外问题可能导致系统发出警告音。在引导过程中,必须打开每个池,这意味着这样的故障将导致系统进入应急重新引导循环。为了从此情况恢复,必须通知 ZFS 不要在启动时查找任何池。
ZFS 在 /etc/zfs/zpool.cache 中维护可用池及其配置的内部高速缓存。此文件的位置和内容是专用的,有可能更改。如果系统变得无法引导,则使用 m =none 引导选项引导到 -none 里程碑。系统启动后,将根文件系统重新挂载为可写入,然后重命名 /etc/zfs/zpool.cache 文件或将其移动到其他位置。这些操作使 ZFS 忘记系统上存在池,从而阻止它尝试访问导致问题的有问题池。然后可以通过发出 svcadm milestone all 命令进入正常系统状态。从备用根引导时,可以使用类似的过程执行修复。
系统启动后,可以尝试使用 zpool import 命令导入池。但是,这样做很可能会导致在引导期间出现的相同错误,因为该命令使用相同机制访问池。如果系统中存在多个池,请执行以下操作:
重命名 zpool.cache 文件或将其移动到其它位置,如上文所述。
使用 fmdump -eV 命令显示报告有致命错误的池,确定哪个池可能有问题。
逐个导入池,跳过有问题的池,如 fmdump 输出中所示。