管理 ZFS 存储池

ZFS 存储池的组件
以下各节提供有关以下存储池组件的详细信息:
使用 ZFS 存储池中的磁盘
使用 ZFS 存储池中的文件
标识存储池中的虚拟设备
使用 ZFS 存储池中的磁盘
存储池的最基本元素是一个物理存储器 。物理存储器可以是大小至少为 128 MB 的任何块设备 。通常,此设备是 /dev/dsk 目录中对系统可见的一个硬盘驱动器 。
存储设备可以是整个磁盘 (c1t0d0) 或单个片 (c0t0d0s7) 。建议的操作模式是使用整个磁盘,在这种情况下,无需对磁盘专门进行格式化 。ZFS 可格式化使用 EFI 标签的磁盘以包含单个大片 。以此方式使用磁盘时,format 命令显示的分区表与以下信息类似:
Current partition table (original):
Total disk sectors available: 7167095316384 (reserved sectors)
Part TagFlag First SectorSizeLast Sector
 0usrwm34 34.18GB 71670953
 1 unassignedwm 0 0 0
 2 unassignedwm 0 0 0
 3 unassignedwm 0 0 0
 4 unassignedwm 0 0 0
 5 unassignedwm 0 0 0
 6 unassignedwm 0 0 0
 7 unassignedwm 0 0 0
 8reservedwm 716709548.00MB 71687337
要使用整个磁盘,必须使用标准 Solaris 约定命名磁盘,如 /dev/dsk/cXtXdXsX 。一些第三方驱动程序使用不同的命名约定,或者将磁盘放置在除 /dev/dsk 目录以外的位置中 。要使用这些磁盘,必须手动标记磁盘并为 ZFS 提供片 。
创建包含整个磁盘的存储池时,ZFS 会应用 EFI 标签 。创建包含磁盘片的存储池时,可以使用传统的 Solaris VTOC 标签来标记磁盘 。
应仅在以下情况下使用片:
设备名称是非标准名称 。
【管理 ZFS 存储池】ZFS 和其他文件系统(如 UFS)之间共享单个磁盘 。
磁盘用作交换设备或转储设备 。
可以使用全路径(如 /dev/dsk/c1t0d0)或构成 /dev/dsk 目录中设备名称的缩略名称(如 c1t0d0)来指定磁盘 。例如,以下是有效的磁盘名称:
c1t0d0
/dev/dsk/c1t0d0
c0t0d6s2
/dev/foo/disk
如果为存储池指定整个磁盘,ZFS 将使用整个磁盘 。这意味着将删除已定义的任何现有 fdisk 分区 。如果要在具有现有 fdisk 分区的磁盘上创建 ZFS 存储池,则可以通过指定片 (c1t0d0s7) 而不是整个磁盘 (c1t0d0) 来创建存储池 。
创建 ZFS 存储池的最简单方法是使用整个物理磁盘 。在从磁盘片、硬件 RAID 阵列中的 LUN 或基于软件的卷管理器所提供的卷中生成池时,无论从管理、可靠性还是性能的角度而言,ZFS 配置都变得越来越复杂 。以下注意事项可能有助于确定如何用其他硬件或软件存储解决方案来配置 ZFS:
如果在硬件 RAID 阵列中的 LUN 上构建 ZFS 配置,则需要了解 ZFS 冗余功能与该阵列所提供的冗余功能之间的关系 。有些配置可能会提供足够的冗余和性能,而其他配置可能不会提供足够的冗余和性能 。
可以使用基于软件的卷管理器(如 SolarisTM 卷管理器 (Solaris Volume Manager, SVM) 或 Veritas 卷管理器 (Veritas Volume Manager, VxVM))所提供的卷来为 ZFS 构建逻辑设备 。但是,建议不要使用这些配置 。尽管 ZFS 可在这类设备上正常运行,但结果可能是实际性能低于最佳性能 。
磁盘由其路径及其设备 ID(如果可用)标识 。使用此方法,可以在系统中重新配置设备,而不必更新任何 ZFS 状态 。如果磁盘在控制器 1 和控制器 2 之间切换,则 ZFS 可使用设备 ID 检测到该磁盘已移动,并且现在应使用控制器 2 对其进行访问 。设备 ID 对于驱动器固件是唯一的 。尽管不大可能,但确实有一些固件更新更改了设备 ID 。如果发生这种情况,ZFS 仍可以按路径访问设备,并自动更新存储的设备 ID 。如果无意中同时更改了设备的路径和 ID,则将池导出再重新导入后才能使用该池 。
使用 ZFS 存储池中的文件
ZFS 还允许将 UFS 文件用作存储池中的虚拟设备 。此功能主要用于测试和启用简单的实验,而不是用于生产 。原因是文件的任何使用都依赖于基础文件系统以实现一致性 。如果创建了由 UFS 文件系统中的文件支持的 ZFS 池,即会隐式依赖于 UFS 来保证正确性和同步语义 。
但是,如果首次试用 ZFS,或者在没有足够的物理设备时尝试更复杂的布局,则文件会非常有用 。所有文件必须以完整路径的形式指定,并且大小至少为 64 MB 。如果移动或重命名某个文件,则必须将池导出再重新导入才能使用该池,这是因为没有设备 ID(可以按其查找文件)与文件相关联 。
标识存储池中的虚拟设备
每个存储池都由一个或多个虚拟设备组成 。虚拟设备是存储池的内部表示形式,用于说明物理存储的布局及其故障特征 。因此,虚拟设备表示用于创建存储池的磁盘设备或文件 。
两种顶层虚拟设备可提供数据冗余:镜像虚拟设备和 RAID-Z 虚拟设备 。这些虚拟设备由磁盘、磁盘片或文件构成 。
在镜像虚拟设备和 RAID-Z 虚拟设备之外的池中使用的磁盘、磁盘片或文件本身用作顶层虚拟设备 。
存储池通常由多个顶层虚拟设备构成 。ZFS 将在池内的所有顶层虚拟设备中以动态方式对数据进行条带化 。
ZFS 存储池的复制功能
ZFS 在镜像配置和 RAID-Z 配置中提供数据冗余和自我修复属性 。
镜像存储池配置
RAID-Z 存储池配置
冗余配置中的自我修复数据
存储池中的动态条带化
镜像存储池配置
镜像存储池配置至少需要两个磁盘,而且磁盘最好位于不同的控制器上 。可以在一个镜像配置中使用许多磁盘 。此外,还可以在每个池中创建多个镜像 。从概念上讲,简单的镜像配置与以下内容类似:
mirror c1t0d0 c2t0d0
从概念上讲,更复杂的镜像配置与以下内容类似:
mirror c1t0d0 c2t0d0 c3t0d0 mirror c4t0d0 c5t0d0 c6t0d0
RAID-Z 存储池配置
除镜像存储池配置外,ZFS 还提供具有单奇偶校验容错性或双奇偶校验容错性的 RAID-Z 配置 。单奇偶校验 RAID-Z 与 RAID-5 类似 。双奇偶校验 RAID-Z 与 RAID-6 类似 。
所有与 RAID-5 类似的传统算法(例如 RAID-4、RAID-6、RDP 和 EVEN-ODD)都存在称为“RAID-5 写入漏洞的问题 。如果仅写入了 RAID-5 条带的一部分,并且在所有块成功写入磁盘之前断电,则奇偶校验将永远与数据不同步,因此是无用的,除非后续的完全条带化写操作将其覆写 。在 RAID-Z 中,ZFS 使用可变宽度的 RAID 条带,以便所有写操作都是完全条带化写操作 。这是唯一可行的设计,因为 ZFS 通过以下方式将文件系统和设备管理集成在一起:文件系统的元数据包含有关基础数据冗余模型的足够信息以处理可变宽度的 RAID 条带 。RAID-Z 是世界上针对 RAID-5 写入漏洞的第一个仅使用软件的解决方案 。
一个 RAID-Z 配置包含 N 个大小为 X 的磁盘,其中有 P 个奇偶校验磁盘,该配置可以存放大约 (N-P)*X 字节的数据,并且只有在 P 个设备出现故障时才会危及数据完整性 。单奇偶校验 RAID-Z 配置至少需要两个磁盘,双奇偶校验 RAID-Z 配置至少需要三个磁盘 。例如,如果一个单奇偶校验 RAID-Z 配置中有三个磁盘,则奇偶校验数据占用的空间与其中一个磁盘的空间相等 。除此之外,创建 RAID-Z 配置无需任何其他特殊硬件 。
从概念上讲,包含三个磁盘的 RAID-Z 配置与以下内容类似:
raidz c1t0d0 c2t0d0 c3t0d0
从概念上讲,更复杂的 RAID-Z 配置与以下内容类似:
raidz c1t0d0 c2t0d0 c3t0d0 c4t0d0 c5t0d0 c6t0d0 c7t0d0 raidz c8t0d0 c9t0d0 c10t0d0 c11t0d0
c12t0d0 c13t0d0 c14t0d0
如果要创建包含许多磁盘的 RAID-Z 配置(如本示例所示),则最好将包含 14 个磁盘的 RAID-Z 配置拆分为两个包含 7 个磁盘的分组 。若 RAID-Z 配置包含的分组中的磁盘数目为一位数 (1-9),则该配置的性能应该更好 。
冗余配置中的自我修复数据
ZFS 在镜像配置或 RAID-Z 配置中提供了自我修复数据 。
检测到坏的数据块时,ZFS 不仅会从另一个冗余副本中提取正确的数据,还会通过将错误数据替换为正确的副本对其进行修复 。
存储池中的动态条带化
对于添加到池中的每个虚拟设备,ZFS 会跨越所有可用设备以动态方式对数据进行条带化 。由于是在写入时确定放置数据的位置,因此在分配时不会创建固定宽度的条带 。
向池中添加虚拟设备时,ZFS 会将数据逐渐分配给新设备,以便维护性能和空间分配策略 。每个虚拟设备也可以是包含其他磁盘设备或文件的镜像或 RAID-Z 设备 。使用此配置,可以灵活地控制池的故障特征 。例如,可以通过 4 个磁盘创建以下配置:
使用动态条带化的四个磁盘
一个四向 RAID-Z 配置
使用动态条带化的两个双向镜像
尽管 ZFS 支持在同一池中组合不同类型的虚拟设备,但是建议不要采用这种做法 。例如,可以创建一个包含一个双向镜像和一个三向 RAID-Z 配置的池 。但是,容错能力几乎与最差的虚拟设备(在本示例中为 RAID-Z)相同 。建议做法是使用相同类型的顶层虚拟设备,并且每个设备的冗余级别相同 。
创建和销毁 ZFS 存储池
以下各节介绍创建和销毁 ZFS 存储池的不同情况 。
创建 ZFS 存储池
处理 ZFS 存储池创建错误
销毁 ZFS 存储池
根据设计,可快速轻松地创建和销毁池 。但是,执行这些操作请务必谨慎 。虽然进行了检查,以防止在新的池中使用现已使用的设备,但是 ZFS 无法始终知道设备何时已在使用中 。销毁池更为容易 。请谨慎使用 zpool destroy 。这是一个会产生重大后果的简单命令 。
创建 ZFS 存储池
要创建存储池,请使用 zpool create 命令 。此命令采用池名称和任意数目的虚拟设备作为参数 。池名称必须符合ZFS 组件命名要求中概述的命名约定 。
创建基本存储池
以下命令创建了一个名为 tank 的新池,该池由磁盘 c1t0d0 和 c1t1d0 组成:
# zpool create tank c1t0d0 c1t1d0
这些整个磁盘可在 /dev/dsk 目录中找到,并由 ZFS 适当标记以包含单个大片 。数据通过这两个磁盘以动态方式进行条带化 。
创建镜像存储池
要创建镜像池,请使用 mirror 关键字,后跟将组成镜像的任意数目的存储设备 。可以通过在命令行中重复使用 mirror 关键字指定多个镜像 。以下命令创建了一个包含两个双向镜像的池:
# zpool create tank mirror c1d0 c2d0 mirror c3d0 c4d0
第二个 mirror 关键字表示将指定新的顶层虚拟设备 。数据通过这两个镜像以动态方式进行条带化,并会相应地在每个磁盘之间创建冗余数据 。
目前,ZFS 镜像配置中支持以下操作:
向现有镜像配置中添加用于其他顶层 vdev 的另一组磁盘 。
向现有镜像配置中附加其他磁盘 。或者,向非复制配置中附加其他磁盘,以创建镜像配置 。
只要可供替换的磁盘大于或等于要被替换的设备,便可替换现有镜像配置中的一个或多个磁盘 。
只要剩余设备可为配置提供足够冗余,便可分离镜像配置中的一个或多个磁盘 。
目前,镜像配置中不支持以下操作:
不能从镜像存储池中彻底删除设备 。对于此功能,已经申请了 RFE(请求提高) 。
不能出于备份目的而分割或中断镜像 。对于此功能,已经申请了 RFE(请求提高) 。
创建 RAID-Z 存储池
创建单奇偶校验 RAID-Z 池与创建镜像池基本相同,不同之处是使用 raidz 或 raidz1 关键字而不是 mirror 。以下示例说明如何创建一个包含由 5 个磁盘组成的单个 RAID-Z 设备的池:
# zpool create tank raidz c1t0d0 c2t0d0 c3t0d0 c4t0d0 /dev/dsk/c5t0d0
本示例表明可以使用全路径指定相应的磁盘 。/dev/dsk/c5t0d0 设备与 c5t0d0 设备相同 。
可以使用磁盘片创建类似的配置 。例如:
# zpool create tank raidz c1t0d0s0 c2t0d0s0 c3t0d0s0 c4t0d0s0 c5t0d0s0
但是,必须预先格式化磁盘,使其包含适当大小的片 0 。
可在创建池时使用 raidz2 关键字来创建双奇偶校验 RAID-Z 配置 。例如:
# zpool create tank raidz2 c1t0d0 c2t0d0 c3t0d0
# zpool status -v tank
 pool: tank
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE0 0 0
 raidz2 ONLINE0 0 0
c1t0d0ONLINE0 0 0
c2t0d0ONLINE0 0 0
c3t0d0ONLINE0 0 0
errors: No known data errors
目前,ZFS RAID-Z 配置中支持以下操作:
向现有 RAID-Z 配置中添加用于其他顶层 vdev 的另一组磁盘 。
只要可供替换的磁盘大于或等于要被替换的设备,便可替换现有 RAID-Z 配置中的一个或多个磁盘 。
目前,RAID-Z 配置中不支持以下操作:
向现有 RAID-Z 配置中附加其他磁盘 。
从 RAID-Z 配置中分离磁盘 。
不能从 RAID-Z 配置中彻底删除设备 。对于此功能,已经申请了 RFE(请求提高) 。
处理 ZFS 存储池创建错误
出现池创建错误可以有许多原因 。其中一些原因是显而易见的(如指定的设备不存在),而其他原因则不太明显 。
检测使用中的设备
格式化设备之前,ZFS 会首先确定 ZFS 或操作系统的某个其他部分是否正在使用磁盘 。如果磁盘正在使用,则可能会显示类似以下的错误:
# zpool create tank c1t0d0 c1t1d0
invalid vdev specification
use "-f" to override the following errors:
/dev/dsk/c1t0d0s0 is currently mounted on /. Please see umount(1M).
/dev/dsk/c1t0d0s1 is currently mounted on swap. Please see swap(1M).
/dev/dsk/c1t1d0s0 is part of active ZFS pool zeepool. Please see zpool(1M).
使用 -f 选项可以覆盖其中的一些错误,但是无法覆盖大多数错误 。使用 -f 选项无法覆盖使用以下各项产生的错误,必须手动对这些错误进行更正:
挂载的文件系统
磁盘或其中一片包含当前挂载的文件系统 。要更正此错误,请使用 umount 命令 。
/etc/vfstab 中的文件系统
磁盘包含 /etc/vfstab 文件中列出的文件系统,但当前未挂载该文件系统 。要更正此错误,请删除或注释掉 /etc/vfstab 文件中的相应行 。
专用转储设备
正在将磁盘用作系统的专用转储设备 。要更正此错误,请使用 dumpadm 命令 。
ZFS 池的一部分
磁盘或文件是活动 ZFS 存储池的一部分 。要更正此错误,请使用 zpool 命令销毁池 。
以下使用情况检查用作帮助性警告,并可以使用 -f 选项进行覆盖以创建池:
包含文件系统
磁盘包含已知的文件系统,尽管该系统未挂载并且看起来未被使用 。
卷的一部分
磁盘是 SVM 卷的一部分 。
实时升级
正在将磁盘用作 Solaris Live Upgrade 的替换引导环境 。
导出的 ZFS 池的一部分
磁盘是已导出的或者从系统中手动删除的存储池的一部分 。如果是后一种情况,则会将池的状态报告为可能处于活动状态,因为磁盘可能是也可能不是由其他系统使用的网络连接驱动器 。覆盖可能处于活动状态的池时请务必谨慎 。
以下示例说明如何使用 -f 选项:
# zpool create tank c1t0d0
invalid vdev specification
use "-f" to override the following errors:
/dev/dsk/c1t0d0s0 contains a ufs filesystem.
# zpool create -f tank c1t0d0
理想的情况是,更正错误而不是使用 -f 选项 。
不匹配的复制级别
建议不要创建包含不同复制级别的虚拟设备的池 。zpool 命令可尝试防止意外创建冗余级别不匹配的池 。如果尝试创建具有这样配置的池,则会显示类似以下的错误:
# zpool create tank c1t0d0 mirror c2t0d0 c3t0d0
invalid vdev specification
use "-f" to override the following errors:
mismatched replication level: both disk and mirror vdevs are present
# zpool create tank mirror c1t0d0 c2t0d0 mirror c3t0d0 c4t0d0 c5t0d0
invalid vdev specification
use "-f" to override the following errors:
mismatched replication level: 2-way mirror and 3-way mirror vdevs are present
可以使用 -f 选项覆盖这些错误,但建议不要采用这种做法 。此命令还会发出警告,指明正使用大小不同的设备创建镜像池或 RAID-Z 池 。尽管允许此配置,但是冗余级别不匹配会导致较大设备上产生未使用的空间,并要求使用 -f 选项覆盖警告 。
在预运行模式下创建存储池
由于创建池可能以不同方式意外失败,并且格式化磁盘这一操作可能产生危害,因此 zpool create 命令具有一个附加选项 -n,此选项可用于模拟创建池,而无需实际将数据写入磁盘 。此选项执行设备使用中检查和复制级别验证,并报告该过程中出现的任何错误 。如果未找到错误,则会显示类似以下的输出:
# zpool create -n tank mirror c1t0d0 c1t1d0
would create "tank" with the following layout:
tank
 mirror
c1t0d0
c1t1d0
如果不实际创建池,则无法检测到某些错误 。最常见的示例是在同一配置中两次指定同一设备 。由于不写入数据本身便无法可靠地检测到此错误,因此 create -n 命令可能会报告运行成功,但在实际运行时又无法创建池 。
存储池的缺省挂载点
创建池时,根数据集的缺省挂载点是 /pool-name 。此目录必须不存在或者为空 。如果目录不存在,则会自动创建该目录 。如果该目录为空,则根数据集会挂载在现有目录的顶层 。要使用不同的缺省挂载点创建池,请在 zpool create 命令中使用 -m 选项:
# zpool create home c1t0d0
default mountpoint "/home" exists and is not empty
use "-m" option to specify a different default
# zpool create -m /export/zfs home c1t0d0
# zpool create home c1t0d0
default mountpoint "/home" exists and is not empty
use "-m" option to provide a different default
# zpool create -m /export/zfs home c1t0d0