ZFS 镜像混乱

ZFS 镜像混乱

我有一个 ZFS 池,有 6 个驱动器,采用 RAID10——嗯,以前是这样。

我尝试将 146GB 驱动器升级到 1TB 驱动器,但结果很糟糕。

root@x7550:~# zpool status
  pool: stuffpool
 state: ONLINE
  scan: scrub repaired 0 in 0h6m with 0 errors on Mon May  9 15:26:39 2016
config:

    NAME                                               STATE     READ WRITE CKSUM
    stuffpool                                          ONLINE       0     0     0
      mirror-0                                         ONLINE       0     0     0
        ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1  ONLINE       0     0     0
        ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1  ONLINE       0     0     0
      mirror-1                                         ONLINE       0     0     0
        ata-HGST_HTS541010A9E680_JA1000102MG9UR-part1  ONLINE       0     0     0
        ata-HGST_HTS541010A9E680_JA1009C03158BP-part1  ONLINE       0     0     0
      scsi-35000c50016ebcdfb-part1                     ONLINE       0     0     0
      ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1    ONLINE       0     0     0

scsi-35000c50016ebcdfb-part1用于位于mirror-2 中,并且ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1是我试图添加到mirror-2 的驱动器。

我能做些什么来解决这个问题吗?

我在 ubuntu 16.04 上运行

root@x7550:~# zpool history stuffpool | tail -n50
History for 'stuffpool':
2016-03-27.01:56:12 zpool create stuffpool mirror ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1 ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1 -f
2016-03-27.01:57:41 zpool add stuffpool mirror /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA1000102MG9UR-part1 /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA1009C03158BP-part1 -f
2016-03-27.01:59:25 zpool add stuffpool mirror /dev/disk/by-id/scsi-35000c50016ebcdfb-part1 /dev/disk/by-id/scsi-35000c50017675203-part1 -f
2016-03-27.02:12:38 zpool import -c /etc/zfs/zpool.cache -aN
2016-03-27.23:48:32 zfs create stuffpool/stuff
2016-03-27.23:54:47 zpool import -c /etc/zfs/zpool.cache -aN
2016-03-28.00:02:23 zfs create stuffpool/backup
2016-03-30.23:18:04 zpool scrub stuffpool
2016-04-03.01:06:06 zpool import -c /etc/zfs/zpool.cache -aN
2016-04-03.01:15:33 zfs create -p -o mountpoint=/var/lib/lxd/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9.zfs stuffpool/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9
2016-04-03.01:15:53 zfs set readonly=on stuffpool/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9
2016-04-03.01:15:54 zfs snapshot -r stuffpool/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9@readonly
2016-04-03.01:16:00 zfs clone -p -o mountpoint=/var/lib/lxd/containers/ux-1.zfs stuffpool/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9@readonly stuffpool/containers/ux-1
2016-04-08.01:31:47 zpool import -c /etc/zfs/zpool.cache -aN
2016-04-08.01:43:48 zpool import -c /etc/zfs/zpool.cache -aN
2016-04-19.00:00:30 zpool import -c /etc/zfs/zpool.cache -aN
2016-04-21.18:14:15 zfs create -p -o mountpoint=/var/lib/lxd/images/9b03bacc30bcfbe3378e8803daa48ca2d32baa99d111efada484876750e5cc20.zfs stuffpool/images/9b03bacc30bcfbe3378e8803daa48ca2d32baa99d111efada484876750e5cc20
2016-04-21.18:14:35 zfs set readonly=on stuffpool/images/9b03bacc30bcfbe3378e8803daa48ca2d32baa99d111efada484876750e5cc20
2016-04-21.18:14:36 zfs snapshot -r stuffpool/images/9b03bacc30bcfbe3378e8803daa48ca2d32baa99d111efada484876750e5cc20@readonly
2016-04-21.18:14:36 zfs set mountpoint=none stuffpool/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9
2016-04-21.18:14:41 zfs rename -p stuffpool/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9 stuffpool/deleted/images/f96b6b5d7587150b880e96f872393b7fee53741046b40a76c6db22ed40886bc9
2016-04-24.22:54:03 zpool scrub stuffpool
2016-05-07.22:55:42 zpool import -c /etc/zfs/zpool.cache -aN
2016-05-09.15:20:27 zpool scrub stuffpool
2016-05-17.22:56:53 zfs create -p -o mountpoint=/var/lib/lxd/images/4f7a1fe6b71446eba6ee56f49698bd6592f193f731f1c0d9d51b1d199b9b75a5.zfs stuffpool/images/4f7a1fe6b71446eba6ee56f49698bd6592f193f731f1c0d9d51b1d199b9b75a5
2016-05-17.22:57:12 zfs set readonly=on stuffpool/images/4f7a1fe6b71446eba6ee56f49698bd6592f193f731f1c0d9d51b1d199b9b75a5
2016-05-17.22:57:13 zfs snapshot -r stuffpool/images/4f7a1fe6b71446eba6ee56f49698bd6592f193f731f1c0d9d51b1d199b9b75a5@readonly
2016-05-17.22:57:18 zfs destroy -r stuffpool/images/9b03bacc30bcfbe3378e8803daa48ca2d32baa99d111efada484876750e5cc20
2016-05-21.16:47:49 zpool import -c /etc/zfs/zpool.cache -aN
2016-06-09.22:59:47 zpool import -c /etc/zfs/zpool.cache -aN
2016-06-13.20:59:10 zpool import -c /etc/zfs/zpool.cache -aN
2016-06-13.20:59:34 zfs create -p -o mountpoint=/var/lib/lxd/images/49fc7d0d6f01a7639129308b73ad27f5fb7b9d3bb783d905393b6b9e9c4bf1c5.zfs stuffpool/images/49fc7d0d6f01a7639129308b73ad27f5fb7b9d3bb783d905393b6b9e9c4bf1c5
2016-06-13.20:59:54 zfs set readonly=on stuffpool/images/49fc7d0d6f01a7639129308b73ad27f5fb7b9d3bb783d905393b6b9e9c4bf1c5
2016-06-13.20:59:54 zfs snapshot -r stuffpool/images/49fc7d0d6f01a7639129308b73ad27f5fb7b9d3bb783d905393b6b9e9c4bf1c5@readonly
2016-06-13.21:00:00 zfs destroy -r stuffpool/images/4f7a1fe6b71446eba6ee56f49698bd6592f193f731f1c0d9d51b1d199b9b75a5
2016-06-18.02:18:55 zpool import -c /etc/zfs/zpool.cache -aN
2016-06-18.02:27:08 zpool offline stuffpool 1759097636360003165
2016-06-18.02:33:28 zpool detach stuffpool 1759097636360003165
2016-06-18.12:23:26 zpool export stuffpool
2016-06-18.12:24:38 zpool import stuffpool
2016-06-18.12:27:34 zpool add -f stuffpool ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1
2016-06-18.12:31:05 zpool export stuffpool
2016-06-18.13:19:17 zpool import stuffpool

所有 ATA 驱动器均为 1tb,SCSI 驱动器为 146GB

这是使用信息

root@x7550:~# zpool list
NAME        SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
stuffpool  2.85T   162G  2.69T         -     2%     5%  1.00x  ONLINE  -

这是我的个人服务器,因此停机不是问题。

答案1

好吧,你把自己弄得有点乱了,但看起来是可以解决的。

您犯的第一个错误是zpool add新驱动器,而不是zpool attach(将附加设备附加到镜像),或者更好的zpool replace是旧设备仍然存在于池元数据中。更换设备的正确方法是

# zpool replace stuffpool 1759097636360003165 ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1

或者甚至更好,如果您有物理能力,zpool replace旧设备与新设备都连接(这将在整个过程中保持池冗余)。

你的旧泳池基本上已经坏了无法修复此时:您无法在添加 vdev 后将其从池中删除(vdev 冗余级别不匹配可能是您需要-f将新磁盘放入池中的原因),并且您没有硬件来转换这两个磁盘非冗余 vdev 进入双向镜像。

但是,您可以用你现有的资源建一个新池。

在采取任何行动之前,请通读所有内容,并确保您了解每个步骤的内容和原因。你真的不想再添乱了。

首先,绝对确保您拥有最新的、可靠的备份您的数据。鉴于您的存储空间只有 160 GB 多一点,这应该不是什么大问题。我还强烈建议zpool scrub确保池中存储的所有数据没有任何错误。对于 160 GB,并且正如您之前的清理所示,应该不会花很长时间即可完成。

然后,通过将一个驱动器从镜像上拆下来释放该驱动器。例如,要分解镜像 0 并使用其中的一个驱动器,您可以

# zpool detach stuffpool ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1

这将为您留下stuffpool由三个单设备 vdev 和一个双向镜像 vdev (mirror-1) 组成的结果。然后清除从镜像中脱离的驱动器上的所有 ZFS 标签,以便您可以重新调整其用途:

# zpool labelclear /dev/disk/by-id/ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1

此时,ZFS 不会将该驱动器识别为旧池的一部分。你可能需要-fzpool labelclear但不要盲目添加;确保您了解为什么您可能需要它。

重命名旧池(假设您想保留该名称,否则根据需要在下面进行调整):

# zpool export stuffpool
# zpool import stuffpool stuffpoolold

在释放的驱动器上创建一个新池:

# zpool create -o ashift=12 -O checksum=sha256 -m none -f stuffpool /dev/disk/by-id/ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1

我建议使用 SHA-256 进行校验,但如果您不想这样做,可以省略该-O checksum=sha256部分。-o ashift=12告诉 ZFS 使用 4,096 字节块作为最小分配单元,这样可以以较小的存储空间成本更好地与“高级格式”驱动器配合使用。

如果您不使用池上的根文件系统来存储数据,则某些故障情况更容易恢复。我建议您在池上创建一个代理根文件系统:

# zfs create -o mountpoint=/mnt/stuffpoolnew stuffpool/data

现在,将所有内容从旧池转移到新池。首先创建旧池当前状态的快照:

# zfs snapshot stuffpoolold@transfer -r

确保快照创建成功。然后:

# zfs send -R stuffpoolold@transfer | zfs receive -uvF stuffpool/data

这需要一段时间。让它运行完成,然后获取同时发生的任何更改:

# zfs snapshot stuffpoolold@transfer2 -r
# zfs send -I stuffpoolold@transfer stuffpoolold@transfer2 -Rv | zfs receive stuffpool/data -uv

此时,池上的数据在所有意图和目的上都应该是相同的。如果您正在运行 cron 作业或类似的任务来写入池,请考虑zfs send -I ...在单用户模式下制作第二个快照,以降低数据添加到池中的风险。

设置新池以取代旧池:

# zfs get mountpoint stuffpoolold
... this will give you a mountpoint directory ...
# zpool export stuffpoolold
# zfs set mountpoint=...mountpoint_directory_from_above... stuffpool/data
# zpool export stuffpool
# zpool import stuffpool

此时,您已拥有仅由单个设备组成的新 zpool。擦洗以确保数据正常:

# zpool scrub stuffpool

当它完成且未发现任何错误时,继续将旧磁盘迁移到新池。从旧的剩余镜像 1 对的第二个驱动器开始(因为我们使用了上面镜像 0 的第二个驱动器),以尽可能长时间地保持旧池的可导入性:

# zpool labelclear /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA1009C03158BP-part1
# zpool attach stuffpool /dev/disk/by-id/ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1 /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA1009C03158BP-part1

检查zpool status stuffpool以确保您现在拥有一个由单个双向镜像 vdev 组成的池,如下所示:

root@x7550:~# zpool status stuffpool
  pool: stuffpool
 state: ONLINE
  scan: scrub repaired 0 in 0h6m with 0 errors on ...
config:

    NAME                                               STATE     READ WRITE CKSUM
    stuffpool                                          ONLINE       0     0     0
      mirror-0                                         ONLINE       0     0     0
        ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1  ONLINE       0     0     0
        ata-HGST_HTS541010A9E680_JA1009C03158BP-part1  ONLINE       0     0     0

现在继续按照您最初想要的方式添加两个镜像 vdev。您需要首先对设备进行标记清除(否则 ZFS 会抱怨它们已经是导出池的一部分)。同样,您可能需要-fzpool labelclear但是绝对不盲目地添加-fzpool add。(如果你必须这样做,那么我在某个地方犯了一个错误。)

# zpool labelclear /dev/disk/by-id/ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1
# zpool labelclear /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA1000102MG9UR-part1
# zpool labelclear /dev/disk/by-id/scsi-35000c50016ebcdfb-part1
# zpool labelclear /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1
# zpool add stuffpool mirror /dev/disk/by-id/ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1 /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA1000102MG9UR-part1
# zpool add stuffpool mirror /dev/disk/by-id/scsi-35000c50016ebcdfb-part1 /dev/disk/by-id/ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1

再次擦洗(因为每个人都喜欢干净整洁的泳池):

# zpool scrub stuffpool

此时,您的池应该看起来像您从一开始就想要的那样:

root@x7550:~# zpool status
  pool: stuffpool
 state: ONLINE
  scan: scrub repaired 0 in 0h6m with 0 errors on ...
config:

    NAME                                               STATE     READ WRITE CKSUM
    stuffpool                                          ONLINE       0     0     0
      mirror-0                                         ONLINE       0     0     0
        ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1  ONLINE       0     0     0
        ata-HGST_HTS541010A9E680_JA1009C03158BP-part1  ONLINE       0     0     0
      mirror-1                                         ONLINE       0     0     0
        ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1  ONLINE       0     0     0
        ata-HGST_HTS541010A9E680_JA1000102MG9UR-part1  ONLINE       0     0     0
      mirror-2                                         ONLINE       0     0     0
        scsi-35000c50016ebcdfb-part1                   ONLINE       0     0     0
        ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1  ONLINE       0     0     0

您的池现在不平衡(几乎所有数据都在mirror-0上,并且将保留在那里直到重写;尽管ZFS缺乏类似的东西btrfs rebalance,您仍然可以通过明智地使用来修复它zfs send ... | zfs receive),但它具有您所需要的布局和冗余当你开始的时候就打算的。

这是一个漫长的过程,有很多步骤,但如果你慢慢地进行,并仔细考虑每一步你在做什么,那么它并不是特别危险。

可取之处在于,池中的数据比填充任何一个驱动器的数据要少得多。如果你的泳池几乎满了,事情就会复杂得多。

答案2

幸运的是,您的池中只有 160GB 的数据。

如果您在另一个文件系统上有一个目录,有足够的可用空间来存储约 160GB 的备份数据,或者压缩后更少(我将 /var/backup/在我的示例中使用),您可以:

首先,终止任何可能正在向stuffpool.如果有任何 cron 等作业可能会crond写入.atdstuffpool

stuffpool创建with的完整备份zfs send -R,并将其保存到文件中:

zfs snapshot stuffpool@fullbackup
zfs send -R stuffpool@fullbackup | gzip > /var/backup/stuffpool.zfs.send.gz

顺便说一句,压缩备份不仅占用更少的磁盘空间,而且备份和恢复所需的时间也更少......所使用的任何 CPU 时间gzip几乎总是远远小于通过读取/写入显着减少的数据所节省的时间磁盘。磁盘 I/O 是瓶颈,通常比压缩花费更多时间。

接下来,使用 销毁当前池zfs destroy stuffpool

使用以下命令重新创建 stuffpool:

zpool create -o ashift=12 -o checksum=sha256 -f \
  mirror \
    ata-HGST_HTS721010A9E630_JR10004M0M17TE-part1 \
    ata-HGST_HTS541010A9E680_JA1009C03158BP-part1 \
  mirror \
    ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1 \
    ata-HGST_HTS541010A9E680_JA1000102MG9UR-part1 \
  mirror \
    scsi-35000c50016ebcdfb-part1 \
    ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1

最后,stuffpool使用以下命令恢复:

zcat /var/backup/stuffpool.zfs.send.gz | zfs receive stuffpool -v -d

如果需要,您可以通过删除快照来整理池fullbackup

zfs destroy stuffpool@fullbackup

或者您可以将其保留为您必须重建池时的时间点快照。

可以/var/backup/stuffpool.zfs.send.gz删除。


如果现有文件系统上没有足够的空闲磁盘空间,您可以从现有的 stuffpool 中分离其中一个镜像磁盘,对其进行格式化并使用它来临时存储文件stuffpool.zfs.send.gz

ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1个例子:

zpool detach stuffpool ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1

mkfs.ext4 /dev/disk/by-id/ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1
mount /dev/disk/by-id/ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1 /mnt

zfs snapshot stuffpool@fullbackup
zfs send -R stuffpool@fullbackup | gzip > /mnt/stuffpool.zfs.send.gz

zfs destroy stuffpool

zpool create -o ashift=12 -o checksum=sha256 -f \
    ata-HGST_HTS541010A9E680_JA1009C03158BP-part1 \
  mirror \
    ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1 \
    ata-HGST_HTS541010A9E680_JA1000102MG9UR-part1 \
  mirror \
    scsi-35000c50016ebcdfb-part1 \
    ata-HGST_HTS541010A9E680_JA109NDW206MAS-part1

zcat /mnt/stuffpool.zfs.send.gz | zfs receive stuffpool -v -d

umount /mnt

zpool attach -f stuffpool \
    ata-HGST_HTS541010A9E680_JA1009C03158BP-part1 \
    ata-HGST_HTS721010A9E630_JR10004M0LGN6E-part1 

相关内容