22.3.zpool 管理

ZFS 主要通过两个的工具来进行管理。工具 zpool 控制池的操作,允许添加、删除、替换和管理磁盘。工具 zfs 允许创建、销毁和管理数据集,包括文件系统

22.3.1.创建和销毁存储池

创建 ZFS 存储池是一个永久性决定,因为池的结构在创建后不能改变。最重要的决定是把物理磁盘分成哪种类型的 vdevs。关于可用选项的细节,请看 vdev 类型的列表。在创建池之后,大多数类型的 vdev 不允许向 vdev 添加磁盘。镜像和条带是例外,前者允许向 vdev 添加新的磁盘,后者通过将一个新的磁盘附加到 vdev 而升级到镜像。尽管添加新的 vdev 会扩大池,但池的布局在池创建后不能改变。若要更改,需要备份数据,销毁池,然后重新创建。

创建一个简单的镜像池:

# zpool create mypool mirror /dev/ada1 /dev/ada2
# zpool status
  pool: mypool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada1    ONLINE       0     0     0
            ada2    ONLINE       0     0     0

errors: No known data errors

要用一条命令创建多个的 vdev,请指定由 vdev 类型关键字分隔的磁盘组,在这个例子中是 mirror

# zpool create mypool mirror /dev/ada1 /dev/ada2 mirror /dev/ada3 /dev/ada4
# zpool status
  pool: mypool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada1    ONLINE       0     0     0
            ada2    ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            ada3    ONLINE       0     0     0
            ada4    ONLINE       0     0     0

errors: No known data errors

池也可以使用分区而不是整个磁盘。把 ZFS 放在一个单独的分区里,可允许同一磁盘有其他的分区用于其他目的。特别是,它允许添加启动所需的引导代码和文件系统的分区。这允许从也是一个池的成员的磁盘上启动。当使用一个分区而不是整个磁盘时,ZFS 在 FreeBSD 上没有增加任何性能损失。使用分区还允许管理员对磁盘进行 低配置,使用少于全部容量的磁盘。如果将来有一个与原来的名义大小相同的替换盘,实际的容量略小,那么较小的分区仍然适合使用替换盘。

使用分区创建一个 RAID-Z2 池:

# zpool create mypool raidz2 /dev/ada0p3 /dev/ada1p3 /dev/ada2p3 /dev/ada3p3 /dev/ada4p3 /dev/ada5p3
# zpool status
  pool: mypool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0
            ada4p3  ONLINE       0     0     0
            ada5p3  ONLINE       0     0     0

errors: No known data errors

可以销毁不再需要的池,以重新使用磁盘。销毁池需要先缷载该池中的文件系统。如果有任何数据集正在使用,缷载操作就会失败,且不会销毁这个池。用 -f 可强制销毁池。这可能会导致在这些数据集上有已打开文件的应用程序的未定义行为。

22.3.2.添加和删除设备

有两种方法可以将磁盘添加到池中:用 zpool attach 将磁盘附加到现有的 vdev 上,或者用 zpool add 将 vdev 添加到池中。有些 vdev 类型 允许在创建后向 vdev 添加磁盘。

用单个磁盘创建的池缺乏冗余性。它可以检测到损坏,但不能修复,因为没有其他的数据副本。副本 属性可能能够从一个小的故障中恢复,如坏扇区,但不能提供与镜像或 RAID-Z 相同的保护水平。从一个由单个磁盘 vdev 组成的池开始,使用 zpool attach 向 vdev 添加一个新磁盘,创建一个镜像。也可以使用 zpool attach 向镜像组添加新的磁盘,增加冗余度和读取性能。当对用于池的磁盘进行分区时,将第一个磁盘的布局复制到第二个磁盘上。使用 gpart backupgpart restore 来使这个过程更容易。

通过连接 ada1p3 将单磁盘(stripe)vdev ada0p3 升级为镜像:

# zpool status
  pool: mypool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          ada0p3    ONLINE       0     0     0

errors: No known data errors
# zpool attach mypool ada0p3 ada1p3
Make sure to wait until resilvering finishes before rebooting.

If you boot from pool 'mypool', you may need to update boot code on newly attached disk _ada1p3_.

Assuming you use GPT partitioning and _da0_ is your new boot disk you may use the following command:

        gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
bootcode written to ada1
# zpool status
  pool: mypool
 state: ONLINE
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.
  scan: resilver in progress since Fri May 30 08:19:19 2014
        527M scanned out of 781M at 47.9M/s, 0h0m to go
        527M resilvered, 67.53% done
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0  (resilvering)

errors: No known data errors
# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 0h0m with 0 errors on Fri May 30 08:15:58 2014
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors

当向现有的 vdev 添加磁盘不是一种选择,如 RAID-Z,另一种方法是向池中添加另一个 vdev。增加 vdevs 可以通过在 vdevs 上分配写操作而提供更高的性能。每个 vdev 都提供自己的冗余。混合 vdev 类型如镜像和 RAID-Z 是可能的,但不建议这样做。在一个包含镜像或 RAID-Z vdevs 的池中添加一个非冗余的 vdev,会给整个池的数据带来风险。分散写入意味着非冗余磁盘的故障将导致写入池中的每个块的一部分丢失。

ZFS 在每一个 vdevs 上进行数据条带化。例如,对于两个镜像 vdevs,这实际上是一个 RAID 10,它在两组镜像上进行条带化写入。ZFS 分配空间,使每个 vdev 在同一时间达到 100% 满载。拥有不同数量的可用空间的 vdev 将降低性能,因为更多的数据写入到未满的 vdev 上。

当把新设备连接到启动池时,记得要更新引导代码。

在现有的镜像上附加第二个镜像组(ada2p3ada3p3):

# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 0h0m with 0 errors on Fri May 30 08:19:35 2014
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors
# zpool add mypool mirror ada2p3 ada3p3
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
bootcode written to ada2
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada3
bootcode written to ada3
# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0 in 0h0m with 0 errors on Fri May 30 08:29:51 2014
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0

errors: No known data errors

如果有足够的剩余冗余,从池中移除 vdevs 是不可能的,而从镜像中移除磁盘是代价高昂的。如果在一个镜像组中只保留一个磁盘,该组就不再是镜像,而成为条带,如果剩余的磁盘发生故障,整个池就会有风险。

如需从三路镜像组中删除一个磁盘:

# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0 in 0h0m with 0 errors on Fri May 30 08:29:51 2014
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0

errors: No known data errors
# zpool detach mypool ada2p3
# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0 in 0h0m with 0 errors on Fri May 30 08:29:51 2014
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors

22.3.3.检查池的状态

池的状态是很重要的。如果一个磁盘脱机或 ZFS 检测到一个读、写或校验错误,相应的错误计数会增加。status 输出显示池中每个设备的配置和状态,以及整个池的状态。还显示了要采取的操作和关于最后一次清洗 的详细信息。

# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub repaired 0 in 2h25m with 0 errors on Sat Sep 14 04:25:50 2013
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0
            ada4p3  ONLINE       0     0     0
            ada5p3  ONLINE       0     0     0

errors: No known data errors

22.3.4.清除错误

当检测到一个错误时,ZFS 会增加读取、写入或校验的错误计数。用 zpool clear mypool 来清除错误信息并重置计数。清除错误状态对自动脚本很重要,这些脚本在池遇到错误的时候会提醒管理员。如果不清除旧的错误,脚本可能无法报告进一步的错误。

22.3.5.替换一个正常工作的设备

用不同的磁盘替换一个磁盘可能是可取的。当替换一个工作磁盘时,该过程在替换期间保持旧磁盘在线。池永远不会进入降级 状态,减少数据丢失的风险。运行 zpool replace 以将数据从旧磁盘复制到新磁盘。在操作完成后,ZFS 将旧磁盘从 vdev 上断开连接。如果新的磁盘比旧的磁盘大,可能有可能使用新的空间来扩大 zpool。请参阅 扩大池

替换池中一个正常工作的设备:

# zpool status
  pool: mypool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0

errors: No known data errors
# zpool replace mypool ada1p3 ada2p3
Make sure to wait until resilvering finishes before rebooting.

When booting from the pool 'zroot', update the boot code on the newly attached disk 'ada2p3'.

Assuming GPT partitioning is used and [.filename]#da0# is the new boot disk, use the following command:

        gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
# zpool status
  pool: mypool
 state: ONLINE
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.
  scan: resilver in progress since Mon Jun  2 14:21:35 2014
        604M scanned out of 781M at 46.5M/s, 0h0m to go
        604M resilvered, 77.39% done
config:

        NAME             STATE     READ WRITE CKSUM
        mypool           ONLINE       0     0     0
          mirror-0       ONLINE       0     0     0
            ada0p3       ONLINE       0     0     0
            replacing-1  ONLINE       0     0     0
              ada1p3     ONLINE       0     0     0
              ada2p3     ONLINE       0     0     0  (resilvering)

errors: No known data errors
# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 0h0m with 0 errors on Mon Jun  2 14:21:52 2014
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0

errors: No known data errors

22.3.6.处理故障设备

当池中的一个磁盘发生故障时,该磁盘所属的 vdev 会进入降级 状态。数据仍然可用,但性能下降,因为 ZFS 从可用的冗余中计算缺失的数据。为了将 vdev 恢复到完全功能的状态,替换故障的物理设备。然后 ZFS 被指示开始 resilver 操作。ZFS 从可用的冗余中重新计算故障设备上的数据,并将其写入替换设备中。完成后,vdev 返回到在线状态。

如果 vdev 没有任何冗余,或者如果设备已经故障,并且没有足够的冗余来补偿,池就会进入故障状态。除非有足够的设备可以重新连接,否则这个池就无法运行,需要从备份中进行数据恢复。

当替换一个故障磁盘时,故障磁盘的名称将变为新磁盘的 GUID。如果替换的设备具有相同的设备名称,则无需为 zpool replace 提供新的设备名称参数。

使用 zpool replace 替换一个故障磁盘:

# zpool status
  pool: mypool
 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://illumos.org/msg/ZFS-8000-2Q
  scan: none requested
config:

        NAME                    STATE     READ WRITE CKSUM
        mypool                  DEGRADED     0     0     0
          mirror-0              DEGRADED     0     0     0
            ada0p3              ONLINE       0     0     0
            316502962686821739  UNAVAIL      0     0     0  was /dev/ada1p3

errors: No known data errors
# zpool replace mypool 316502962686821739 ada2p3
# zpool status
  pool: mypool
 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.
  scan: resilver in progress since Mon Jun  2 14:52:21 2014
        641M scanned out of 781M at 49.3M/s, 0h0m to go
        640M resilvered, 82.04% done
config:

        NAME                        STATE     READ WRITE CKSUM
        mypool                      DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            ada0p3                  ONLINE       0     0     0
            replacing-1             UNAVAIL      0     0     0
              15732067398082357289  UNAVAIL      0     0     0  was /dev/ada1p3/old
              ada2p3                ONLINE       0     0     0  (resilvering)

errors: No known data errors
# zpool status
  pool: mypool
 state: ONLINE
  scan: resilvered 781M in 0h0m with 0 errors on Mon Jun  2 14:52:38 2014
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0

errors: No known data errors

22.3.7.刷新池

定期清洗 池,最好是每月一次以上。scrub 操作是磁盘密集型的,在运行中会降低性能。在调度 scrub 时要避开高需求期,或者使用 `vfs.zfs.scrub_delay <https://docs.freebsd.org/en/books/handbook/zfs/#zfs-advanced-tuning-scrub_delay>`__ 来调整 scrub 的相对优先级,以免拖累其他工作负载。

# zpool scrub mypool
# zpool status
  pool: mypool
 state: ONLINE
  scan: scrub in progress since Wed Feb 19 20:52:54 2014
        116G scanned out of 8.60T at 649M/s, 3h48m to go
        0 repaired, 1.32% done
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0p3  ONLINE       0     0     0
            ada1p3  ONLINE       0     0     0
            ada2p3  ONLINE       0     0     0
            ada3p3  ONLINE       0     0     0
            ada4p3  ONLINE       0     0     0
            ada5p3  ONLINE       0     0     0

errors: No known data errors

如果需要,可以运行 zpool scrub -s mypool 以取消刷新操作。

22.3.8.自我修复

与数据块一起存储的校验和使文件系统能够 自我修复。这个功能将自动修复那些校验和与另一个属于存储池的设备上记录的校验和不一致的数据。例如,有两个磁盘的镜像配置,其中一个磁盘开始出现故障,无法再正常存储数据。当数据很长时间没有被访问时,这种情况就更严重了,就像长期的档案存储一样。传统的文件系统需要运行检查和修复数据的命令,如 fsck(8)。这些命令需要时间,而且在严重的情况下,管理员必须决定执行哪种修复操作。当 ZFS 检测到一个具有不匹配校验和的数据块时,它试图从镜像磁盘读取数据。如果该磁盘能够提供正确的数据,ZFS 将把它交给应用程序,并纠正磁盘上有错误校验和的数据。在正常的池操作中,这种情况无需系统管理员的任何互动。

下一个例子通过创建一个 /dev/ada0/dev/ada1 磁盘的镜像池来展示这种自修复行为:

# zpool create healer mirror /dev/ada0 /dev/ada1
# zpool status healer
  pool: healer
 state: ONLINE
  scan: none requested
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0     ONLINE       0     0     0
       ada1     ONLINE       0     0     0

errors: No known data errors
# zpool list
NAME     SIZE  ALLOC   FREE   CKPOINT  EXPANDSZ   FRAG   CAP  DEDUP  HEALTH  ALTROOT
healer   960M  92.5K   960M         -         -     0%    0%  1.00x  ONLINE  -

将一些重要的数据复制到池中,利用自修复功能防止数据错误,并创建池的校验和,以便以后进行比较:

# cp /some/important/data /healer
# zfs list
NAME     SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
healer   960M  67.7M   892M     7%  1.00x  ONLINE  -
# sha1 /healer > checksum.txt
# cat checksum.txt
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f

通过向镜像中的一个磁盘的开头写入随机数据来模拟数据损坏。为了防止 ZFS 在检测到数据时进行修复,在损坏之前导出池,之后再导入。

警告

这是一个危险的操作,可能会破坏重要的数据,这里仅作示范。在存储池的正常操作中,不要尝试它。这个故意破坏的例子也不应该在任何不使用 ZFS 文件系统的磁盘或分区上运行。不要使用不在池中的任何其他磁盘设备名称。在运行该命令之前,请确保有适当的存储池备份,并对其进行测试!

# zpool export healer
# dd if=/dev/random of=/dev/ada1 bs=1m count=200
200+0 records in
200+0 records out
209715200 bytes transferred in 62.992162 secs (3329227 bytes/sec)
# zpool import healer

pool status 显示,有一个设备出现错误。请注意,从池中读取数据的应用程序并没有收到任何不正确的数据。ZFS 从 ada0 设备提供具有正确校验和的数据。要找到有错误校验和的设备,寻找其 CKSUM 列包含一个非零值的设备。

# zpool status healer
    pool: healer
   state: ONLINE
  status: One or more devices has experienced an unrecoverable error.  An
          attempt was made to correct the error.  Applications are unaffected.
  action: Determine if the device needs to be replaced, and clear the errors
          using 'zpool clear' or replace the device with 'zpool replace'.
     see: http://illumos.org/msg/ZFS-8000-4J
    scan: none requested
  config:

      NAME        STATE     READ WRITE CKSUM
      healer      ONLINE       0     0     0
        mirror-0  ONLINE       0     0     0
         ada0     ONLINE       0     0     0
         ada1     ONLINE       0     0     1

errors: No known data errors

ZFS 检测到这个错误,并通过使用未受影响的 ada0 镜像盘中存在的冗余来处理它。与原始磁盘的校验和比较将揭示池是否再次一致:

# sha1 /healer >> checksum.txt
# cat checksum.txt
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f
SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f

在故意篡改之前和之后生成校验和,而池的数据仍然匹配。这表明当校验和不同时,ZFS 能够自动检测并纠正任何错误。注意这是在池中存在足够的冗余的情况下才可能实现的。一个由单一设备组成的池没有自我修复的能力。这也是为什么校验和在 ZFS 中如此重要的原因;不要以任何理由禁用它们。ZFS 不需要 fsck(8) 或类似的文件系统一致性检查程序来检测和纠正这一点,并可在有问题时保持池的可用性。现在需要一次清洗操作来覆盖 ada1 上的损坏的数据。

# zpool scrub healer
# zpool status healer
  pool: healer
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
            attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
            using 'zpool clear' or replace the device with 'zpool replace'.
   see: http://illumos.org/msg/ZFS-8000-4J
  scan: scrub in progress since Mon Dec 10 12:23:30 2012
        10.4M scanned out of 67.0M at 267K/s, 0h3m to go
        9.63M repaired, 15.56% done
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0     ONLINE       0     0     0
       ada1     ONLINE       0     0   627  (repairing)

清洗操作从 ada0 读取数据,并在 ada1 上重写任何有错误校验的数据,由 zpool status(repairing) 输出显示。操作完成后,池的状态变成:

# zpool status healer
  pool: healer
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
             using 'zpool clear' or replace the device with 'zpool replace'.
   see: http://illumos.org/msg/ZFS-8000-4J
  scan: scrub repaired 66.5M in 0h2m with 0 errors on Mon Dec 10 12:26:25 2012
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0     ONLINE       0     0     0
       ada1     ONLINE       0     0 2.72K

errors: No known data errors

在清洗操作完成后,所有数据会从 ada0 同步到 ada1,通过运行 zpool clear 清除 池状态中的错误信息。

# zpool clear healer
# zpool status healer
  pool: healer
 state: ONLINE
  scan: scrub repaired 66.5M in 0h2m with 0 errors on Mon Dec 10 12:26:25 2012
config:

    NAME        STATE     READ WRITE CKSUM
    healer      ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
       ada0     ONLINE       0     0     0
       ada1     ONLINE       0     0     0

errors: No known data errors

现在池已经恢复到完全工作的状态,所有的错误计数都是零。

22.3.9.扩大池

每个 vdev 中最小的设备限制冗余池的可用大小。用一个更大的设备替换最小的设备。在完成替换resilver 操作后,池就可以增长到使用新设备的容量。以一个 1TB 磁盘和一个 2TB 磁盘组成的镜像为例。可用的空间是 1TB。当用另一个 2TB 的磁盘替换 1TB 的磁盘时,resilver 程序会将现有数据复制到新的磁盘上。由于这两台设备现在都有 2TB 的容量,镜像的可用空间增长到 2TB。

通过在每个设备上使用 zpool online -e 开始扩展。在扩展所有设备后,额外的空间就成为池的可用空间。

22.3.10.导入和导出池

在把池移到另一个系统之前,先 导出 池。ZFS 解除对所有数据集的挂载,将每个设备标记为已导出但仍被锁定,以防止被其他磁盘使用。这允许在其他机器、其他支持 ZFS 的操作系统、甚至不同的硬件架构上 导入 池(有一些注意事项,见 zpool(8))。当一个数据集有已打开的文件时,使用 zpool export -f 来强制导出池。使用这个方法时要注意。数据集被强制卸载,可能会导致在这些数据集上有已打开文件的应用程序出现意外行为。

导出一个不使用的池:

# zpool export mypool

导入一个池会自动挂载数据集。zpool import -o 为这个特定的导入设置临时属性。zpool import altroot= 允许导入一个具有基本挂载点而不是文件系统根目录的池。如果这个池最后是在不同的系统上使用,并且没有被正确导出,请使用 zpool import -f 强制导入。 zpool import -a 会导入所有看起来没有被其他系统使用的池。

列出所有可供导入的池:

# zpool import
   pool: mypool
     id: 9930174748043525076
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        mypool      ONLINE
          ada2p3    ONLINE

用另一个根目录导入池。

# zpool import -o altroot=/mnt mypool
# zfs list
zfs list
NAME                 USED  AVAIL  REFER  MOUNTPOINT
mypool               110K  47.0G    31K  /mnt/mypool

22.3.11.升级存储池

在升级 FreeBSD 之后,或者从使用旧版本的系统中导入一个池,请手动将池升级到最新的 ZFS 版本,以支持更多的新功能。在升级之前,请考虑是否需要在旧系统上导入这个池。升级是一个单向的过程。可以升级较旧的池,但是不可以降级具有较新功能的池。

升级池到 v28 以支持 Feature Flags

# zpool status
  pool: mypool
 state: ONLINE
status: The pool is formatted using a legacy on-disk format.  The pool can
        still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the
        pool will no longer be accessible on software that does not support feat
        flags.
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
        ada0    ONLINE       0     0     0
        ada1    ONLINE       0     0     0

errors: No known data errors
# zpool upgrade
This system supports ZFS pool feature flags.

The following pools are formatted with legacy version numbers and are upgraded to use feature flags.
After being upgraded, these pools will no longer be accessible by software that does not support feature flags.

VER  POOL
---  ------------
28   mypool

Use 'zpool upgrade -v' for a list of available legacy versions.
Every feature flags pool has all supported features enabled.
# zpool upgrade mypool
This system supports ZFS pool feature flags.

Successfully upgraded 'mypool' from version 28 to feature flags.
Enabled the following features on 'mypool':
  async_destroy
  empty_bpobj
  lz4_compress
  multi_vdev_crash_dump

zpool upgrade 完成之前,ZFS 的较新功能将无法使用。使用 zpool upgrade -v 查看升级提供哪些新功能,以及哪些功能已经被支持。

升级池以支持新的 feature flags:

# zpool status
  pool: mypool
 state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
        still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
        the pool may no longer be accessible by software that does not support
        the features. See zpool-features(7) for details.
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
        ada0    ONLINE       0     0     0
        ada1    ONLINE       0     0     0

errors: No known data errors
# zpool upgrade
This system supports ZFS pool feature flags.

All pools are formatted using feature flags.

Some supported features are not enabled on the following pools. Once a
feature is enabled the pool may become incompatible with software
that does not support the feature. See zpool-features(7) for details.

POOL  FEATURE
---------------
zstore
      multi_vdev_crash_dump
      spacemap_histogram
      enabled_txg
      hole_birth
      extensible_dataset
      bookmarks
      filesystem_limits
# zpool upgrade mypool
This system supports ZFS pool feature flags.

Enabled the following features on 'mypool':
  spacemap_histogram
  enabled_txg
  hole_birth
  extensible_dataset
  bookmarks
  filesystem_limits

警告

在从池中启动的系统上更新引导代码,以支持新的池版本。在包含引导代码的分区上使用 gpart bootcode。根据系统引导的方式,有两种类型的引导码可用。GPT(最常见的选项)和 EFI(用于更现代的系统)。

对于使用 GPT 的传统启动,使用以下命令:

# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1

对于使用 EFI 启动的系统,执行以下命令:

# gpart bootcode -p /boot/boot1.efifat -i 1 ada1

将启动代码应用于池中的所有可启动磁盘。参见 gpart(8) 以了解更多信息。

22.3.12.显示已记录的池历史

ZFS 记录改变池的命令,包括创建数据集、改变属性或替换磁盘。回顾池的创建历史是很有用的,就像检查哪个用户在什么时候执行一个特定的动作一样。历史记录不保存在日志文件中,而是池本身的一部分。查看这个历史的命令被恰当地命名为 zpool history

# zpool history
History for 'tank':
2013-02-26.23:02:35 zpool create tank mirror /dev/ada0 /dev/ada1
2013-02-27.18:50:58 zfs set atime=off tank
2013-02-27.18:51:09 zfs set checksum=fletcher4 tank
2013-02-27.18:51:18 zfs create tank/backup

输出显示以某种方式改变池的 zpoolzfs 命令,以及一个时间戳。像 zfs list 这样的命令不包括在内。当没有指定池的名称时,ZFS 显示所有池的历史。

当提供 -i-l 选项时,zpool history 可以显示更多信息。-i 显示用户发起的事件以及内部记录的 ZFS 事件。

# zpool history -i
History for 'tank':
2013-02-26.23:02:35 [internal pool create txg:5] pool spa 28; zfs spa 28; zpl 5;uts  9.1-RELEASE 901000 amd64
2013-02-27.18:50:53 [internal property set txg:50] atime=0 dataset = 21
2013-02-27.18:50:58 zfs set atime=off tank
2013-02-27.18:51:04 [internal property set txg:53] checksum=7 dataset = 21
2013-02-27.18:51:09 zfs set checksum=fletcher4 tank
2013-02-27.18:51:13 [internal create txg:55] dataset = 39
2013-02-27.18:51:18 zfs create tank/backup

通过添加 -l 显示更多细节。以显示长格式的历史记录,包括执行命令的用户名称和发生变化的主机名等信息。

# zpool history -l
History for 'tank':
2013-02-26.23:02:35 zpool create tank mirror /dev/ada0 /dev/ada1 [user 0 (root) on :global]
2013-02-27.18:50:58 zfs set atime=off tank [user 0 (root) on myzfsbox:global]
2013-02-27.18:51:09 zfs set checksum=fletcher4 tank [user 0 (root) on myzfsbox:global]
2013-02-27.18:51:18 zfs create tank/backup [user 0 (root) on myzfsbox:global]

输出显示,root 用户用磁盘 /dev/ada0/dev/ada1 创建了镜像池。主机名 myzfsbox 也显示在池创建后的命令中。当从一个系统导出池并导入另一个系统时,主机名的显示变得很重要。可以通过每条命令记录的主机名来区分其他系统上执行的命令。

将这两个选项合并到 zpool history 中,可以为任何给定的池提供最详细的信息。当追踪所执行的操作或需要更详细的输出进行调试时,池的历史记录提供宝贵的信息。

22.3.13.性能监控

一个内置的监控系统可以实时显示池的 I/O 统计数据。它显示池上的可用空间和使用空间的数量,每秒执行的读写操作,以及使用的 I/O 带宽。默认情况下,ZFS 监控并显示系统中的所有池。提供一个池的名字来限制对该池的监控。一个基本的例子:

# zpool iostat
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
data         288G  1.53T      2     11  11.3K  57.1K

要看到连续的 I/O 活动,可以指定一个数字作为最后一个参数,表示更新之间的间隔时间,单位是秒。每隔一段时间就会打印出下一个统计行。按 Ctrl+C 停止这种连续监控。在间隔时间之后,在命令行中给出第二个数字,以指定要显示的统计数字的总数。

-v 显示更详细的 I/O 统计数据。池中的每个设备都会出现一个统计行。这对于查看每个设备上执行的读写操作很有用,可以帮助确定是否有任何单个设备拖累池子。这个例子显示了一个有两个设备的镜像池:

# zpool iostat -v
                            capacity     operations    bandwidth
pool                     alloc   free   read  write   read  write
-----------------------  -----  -----  -----  -----  -----  -----
data                      288G  1.53T      2     12  9.23K  61.5K
  mirror                  288G  1.53T      2     12  9.23K  61.5K
    ada1                     -      -      0      4  5.61K  61.7K
    ada2                     -      -      1      4  5.04K  61.7K
-----------------------  -----  -----  -----  -----  -----  -----

22.3.14.分割一个存储池

ZFS 可以将一个由一个或多个镜像 vdev 组成的池分割成两个池。除非另有规定,否则 ZFS 将分离每个镜像的最后一个成员,并创建一个包含相同数据的新池。请确保先用 -n 对该操作进行模拟运行。这将显示所请求的操作的细节,而不实际执行。这有助于确认该操作将完成用户的意图。