跳过导航链接 | |
退出打印视图 | |
Oracle Solaris ZFS 管理指南 Oracle Solaris 10 1/13 Information Library (简体中文) |
1. Oracle Solaris ZFS 文件系统(介绍)
4. 安装和引导 Oracle Solaris ZFS 根文件系统
6. 使用 Oracle Solaris ZFS 快照和克隆
7. 使用 ACL 和属性保护 Oracle Solaris ZFS 文件
10. Oracle Solaris ZFS 故障排除和池恢复
由于损坏的磁盘或控制器而导致的瞬态 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 list 和 zfs list 命令要比以前的 df 和 du 命令出色。使用传统命令,既不能轻易分辨池和文件系统空间,也不能对后代文件系统或快照使用的空间做出解释。
例如,以下根池 (rpool) 有 5.46 GB 的已分配空间和 68.5 GB 的空闲空间。
# zpool list rpool NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT rpool 74G 5.46G 68.5G 7% 1.00x ONLINE -
如果通过查看各个文件系统的 USED 列来比较池空间记帐和文件系统空间记帐,则会看到 ALLOC 中报告的池空间可以用文件系统的 USED 总和来计算。例如:
# zfs list -r rpool NAME USED AVAIL REFER MOUNTPOINT rpool 5.41G 67.4G 74.5K /rpool rpool/ROOT 3.37G 67.4G 31K legacy rpool/ROOT/solaris 3.37G 67.4G 3.07G / rpool/ROOT/solaris/var 302M 67.4G 214M /var rpool/dump 1.01G 67.5G 1000M - rpool/export 97.5K 67.4G 32K /rpool/export rpool/export/home 65.5K 67.4G 32K /rpool/export/home rpool/export/home/admin 33.5K 67.4G 33.5K /rpool/export/home/admin rpool/swap 1.03G 67.5G 1.00G -
由 zpool list 命令报告的 SIZE 值通常为池中的物理磁盘空间量,具体大小视池的冗余级别而异。请参见下面的示例。zfs list 命令列出了可供文件系统使用的可用空间,该空间等于磁盘空间减去 ZFS 池冗余元数据开销(如果有)。
非冗余存储池-当池是使用一个 136 GB 的磁盘创建时,zpool list 命令会将 SIZE 值和初始的 FREE 值报告为 136 GB。由于存在少量的池元数据开销,因此 zfs list 命令报告的初始 AVAIL 空间为 134 GB。例如:
# zpool create tank c0t6d0 # zpool list tank NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT tank 136G 95.5K 136G 0% 1.00x ONLINE - # zfs list tank NAME USED AVAIL REFER MOUNTPOINT tank 72K 134G 21K /tank
镜像的存储池-当使用两个 136 GB 的磁盘创建一个池时,zpool list 命令会报告 SIZE 为 136 GB,初始 FREE 值为 136 GB。此处报告的是已压缩空间值。由于存在少量的池元数据开销,因此 zfs list 命令报告的初始 AVAIL 空间为 134 GB。例如:
# zpool create tank mirror c0t6d0 c0t7d0 # zpool list tank NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT tank 136G 95.5K 136G 0% 1.00x ONLINE - # zfs list tank NAME USED AVAIL REFER MOUNTPOINT tank 72K 134G 21K /tank
RAID-Z 存储池-当 raidz2 池是使用三个 136 GB 的磁盘创建时,zpool list 命令会将 SIZE 值和初始 FREE 值均报告为 408 GB。此处报告的是已解压磁盘空间值,其中包括冗余开销,如奇偶校验信息。由于存在池冗余开销,因此 zfs list 命令报告的初始 AVAIL 空间为 133 GB。zpool list 和 zfs list 输出的 RAID-Z 池空间之间存在差异的原因在于,zpool list 报告的是“已解压的”池空间。
# zpool create tank raidz2 c0t6d0 c0t7d0 c0t8d0 # zpool list tank NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT tank 408G 286K 408G 0% 1.00x ONLINE - # zfs list tank NAME USED AVAIL REFER MOUNTPOINT tank 73.2K 133G 20.9K /tank
以下各节介绍如何确定数据损坏的类型以及如何修复数据(如有可能)。
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 status -v 命令无法显示所有损坏数据的路径。当前 zpool status 对损坏数据的报告受以下项的限制:元数据的损坏量以及执行 zpool status 命令后是否重用了任何块。删除了重复数据的块使得对所有损坏数据的报告更加复杂。
如果有数据损坏,并且 zpool status -v 命令确定有快照数据受影响,请考虑运行以下命令来确定额外的损坏数据路径:
如果池元数据发生损坏,并且该损坏导致池无法打开或导入,则可以使用以下选项:
可以尝试使用 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 import -o readonly=on tpool
有关在只读模式下导入池的更多信息,请参见在只读模式下导入池。
您可以使用 zpool import -m 命令导入缺少日志设备的池。有关更多信息,请参见导入缺少日志设备的池。
如果无法使用上述池恢复方法恢复池,则必须从备份副本中恢复池及其所有数据。所用的机制通常随池配置和备份策略的不同而有很大差别。首先,保存 zpool status 命令所显示的配置,以便在销毁池后可以重新创建它。然后,使用 zpool destroy -f 命令销毁池。
此外,将描述数据集的布局和在本地设置的各种属性的文件保存在某个安全的位置(因为在使池无法访问后此信息将变得无法访问)。使用池配置和数据集布局,可以在销毁池后重新构造完整的配置。然后可以使用任何备份或恢复策略填充数据。