ZFS 分离池中的镜像驱动器

ZFS 分离池中的镜像驱动器

我有一台运行 FreeNAS 的较旧(2-3 年)的 NAS。我认为是时候升级一些硬盘了。这是当前状态:

    NAME        STATE     READ WRITE CKSUM                                  
    Pool1       ONLINE       0     0     0                                  
      raidz1    ONLINE       0     0     0                                  
        ada3p2  ONLINE       0     0     0                                  
        ada4p2  ONLINE       0     0     0                                  
        ada5p2  ONLINE       0     0     0                                  
      mirror    ONLINE       0     0     0                                  
        ada1p2  ONLINE       0     0     0                                  
        ada2p2  ONLINE       0     0     0 

RaidZ1 中的驱动器均为 1GB,并将保留。

在 RaidZ1 中添加 2 或 3 个 1GB 硬盘并完全删除镜像驱动器(只有 500GB)的最佳方法是什么,而不需要:

  • 将数据复制到临时保存位置
  • 重新创建池
  • 复制回来

该池大约已满 50%,因此我什至不确定镜像驱动器上是否有数据。

如何检查或从哪里开始?

答案1

唯一的方法就是按照您的建议进行操作:将所有数据集复制到一个新池并重建该池。 zfs 不支持通过添加驱动器来扩展 raidz1,也不支持删除顶级 vdev(这就是“镜像”)。

答案2

简短回答:

将...更多...驱动器添加到RaidZ1并完全删除镜像驱动器的最佳方法是什么,...没有:

  • 将数据复制到临时保存位置
  • 重新创建池
  • 复制回来

你不能。句号。根据您的配置,如果不创建新池并复制到其中,您将无法删除镜像驱动器。特别是考虑到您发帖的时间,ZFS 不支持从池中删除 VDEV。对于最近遇到此问题的读者,截至撰写本文时,zpool remove不支持从包含一个或多个 VDEV 的池中删除 VDEV raidzzpool remove不支持删除串联磁盘或串联镜像。

长答案:

raidz1您的vdev 与镜像 vdev 连接的配置有点不寻常。您将无法从池中删除镜像 vdev,除非创建新池,将数据从旧池复制到新池,然后销毁旧池。

但是,只要不更改其 vdev 结构,您当然可以扩展当前池的容量。

所以而不是添加更多的驱动器,您可以切换到更大驱动器。尽管需要多次迭代将池重新同步到每个新驱动器上,一次一个,但它相对轻松。但 ZFS 在重新同步方面比传统 RAID 更高效,因此根据池的满度,情况可能不会那么糟糕。

关键是这个必须一次完成一张磁盘。首先确保您拥有池的完整且经过测试的备份。

这是一个测试沙箱,设置了三个 1G 驱动器、设备 /dev/md0 到 /dev/md2,每个驱动器上都有一个 GPT 分区表:

# gpart show md{0..2}
=>     40  2097072  md0  GPT  (1.0G)
       40      200    1  linux-swap  (100K)
      240  2096872    2  freebsd-zfs  (1.0G)

=>     40  2097072  md1  GPT  (1.0G)
       40      200    1  linux-swap  (100K)
      240  2096872    2  freebsd-zfs  (1.0G)

=>     40  2097072  md2  GPT  (1.0G)
       40      200    1  linux-swap  (100K)
      240  2096872    2  freebsd-zfs  (1.0G)

我用这些驱动器构建了一个raidz1池:

# zpool create tank raidz1 /dev/md{0..2}p2
# zpool status tank; echo; zpool list tank
  pool: tank
 state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    tank        ONLINE       0     0     0
      raidz1-0  ONLINE       0     0     0
        md0p2   ONLINE       0     0     0
        md1p2   ONLINE       0     0     0
        md2p2   ONLINE       0     0     0

errors: No known data errors

NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH
tank  2.75G   196K  2.75G        -         -     0%     0%  1.00x    ONLINE

迷人的。现在,假设我有三个新驱动器:/dev/md3、md4 和 md5。但这些驱动器不仅仅是 1G 驱动器,而是 10G 驱动器。它们还设置了 GPT 分区表并准备就绪:

# gpart show md{3..5}
=>      40  20971440  md3  GPT  (10G)
        40       200    1  linux-swap  (100K)
       240  20971240    2  freebsd-zfs  (10G)

=>      40  20971440  md4  GPT  (10G)
        40       200    1  linux-swap  (100K)
       240  20971240    2  freebsd-zfs  (10G)

=>      40  20971440  md5  GPT  (10G)
        40       200    1  linux-swap  (100K)
       240  20971240    2  freebsd-zfs  (10G)

因为池是多余的,我可以小心代替驱动器在raidz1阵列中更大的驱动器,然后等待让池重新同步,然后继续更换下一个驱动器,一次一个。我将完成第一个任务,方法是offline-ing 驱动器,检查阵列以查看它是否仍在运行,然后用大驱动器替换小驱动器:

# zpool offline tank md0p2
# zpool status tank
  pool: tank
 state: DEGRADED
status: One or more devices has been taken offline by the administrator.
    Sufficient replicas exist for the pool to continue functioning in a
    degraded state.
action: Online the device using 'zpool online' or replace the device with
    'zpool replace'.
config:

    NAME        STATE     READ WRITE CKSUM
    tank        DEGRADED     0     0     0
      raidz1-0  DEGRADED     0     0     0
        md0p2   OFFLINE      0     0     0
        md1p2   ONLINE       0     0     0
        md2p2   ONLINE       0     0     0

errors: No known data errors

现在我可以/dev/md0p2用10G分区替换1G分区了/dev/md3p2。实际上,zpool offline上述步骤并不是绝对必要的。可以直接执行此zpool replace命令:

# zpool replace tank md0p2 md3p2
# zpool status tank; echo; zpool list tank
  pool: tank
 state: ONLINE
  scan: resilvered 128K in 00:00:02 with 0 errors on Wed Oct 13 13:46:23 2021
config:

    NAME        STATE     READ WRITE CKSUM
    tank        ONLINE       0     0     0
      raidz1-0  ONLINE       0     0     0
        md3p2   ONLINE       0     0     0
        md1p2   ONLINE       0     0     0
        md2p2   ONLINE       0     0     0

errors: No known data errors

NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH
tank  2.75G   265K  2.75G        -         -     0%     0%  1.00x    ONLINE

请注意,重新同步已完成。这一点至关重要。如果池中存储了大量数据,则必须等待zpool status tank并偶尔检查,直到重新同步完成。

重新同步完成后,我们可以继续更换第二个磁盘:

# zpool replace tank md1p2 md4p2

再说一次,我们必须等到zpool status说重新同步已完成:

# zpool status tank
  pool: tank
 state: ONLINE
  scan: resilvered 134K in 00:00:03 with 0 errors on Wed Oct 13 13:54:17 2021
config:

    NAME        STATE     READ WRITE CKSUM
    tank        ONLINE       0     0     0
      raidz1-0  ONLINE       0     0     0
        md3p2   ONLINE       0     0     0
        md4p2   ONLINE       0     0     0
        md2p2   ONLINE       0     0     0

errors: No known data errors

现在重新同步已完成,我们将用较大的替换磁盘替换第三个小磁盘:

# zpool replace tank md2p2 md5p2
# zpool status tank; echo; zpool list tank
  pool: tank
 state: ONLINE
  scan: resilvered 146K in 00:00:03 with 0 errors on Wed Oct 13 14:55:56 2021
config:

    NAME        STATE     READ WRITE CKSUM
    tank        ONLINE       0     0     0
      raidz1-0  ONLINE       0     0     0
        md3p2   ONLINE       0     0     0
        md4p2   ONLINE       0     0     0
        md5p2   ONLINE       0     0     0

errors: No known data errors

NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH
tank  2.75G   319K  2.75G        -         -     0%     0%  1.00x    ONLINE

所以现在旧的小磁盘 md0 md1 和 md2 不再在池中。该池在较大的磁盘 md3、md4 和 md5 上运行。但是没有额外的空间,因为我们没有告诉zpool要扩展raidz1数组。这很容易做到:

# zpool online -e tank md5p2
# zpool status tank; echo; zpool list tank
  pool: tank
 state: ONLINE
  scan: resilvered 146K in 00:00:03 with 0 errors on Wed Oct 13 14:55:56 2021
config:

    NAME        STATE     READ WRITE CKSUM
    tank        ONLINE       0     0     0
      raidz1-0  ONLINE       0     0     0
        md3p2   ONLINE       0     0     0
        md4p2   ONLINE       0     0     0
        md5p2   ONLINE       0     0     0

errors: No known data errors

NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH
tank  29.8G   394K  29.7G        -         -     0%     0%  1.00x    ONLINE

现在,我们不再使用 3G 池,而是使用 30G 池,这是通过一次小心地更换一个磁盘,然后扩展阵列来完成的。

答案3

首先,在进行任何更改之前,您可能需要考虑启动zpool scrub以确保一切正常。

离开记忆(所以你需要确认),我相信你想要的选择是zpool add能够扩大你现有的 raidz 池。

要轻松移动数据,您可以使用 zfs send|receive,以及使用快照进行增量发送|接收。

相关内容