Skip to main content Link Menu Expand (external link) Document Search Copy Copied

如何“杀死”一个ZFS Pool

起因

我家里有一个NAS服务器,存储空间由一个ZFS Pool提供。因为平常只是存一些共享的文档数据,数据增长不快,且ZFS一直工作得很稳定,我也就不需要经常折腾这个设备。但是最近我多了一块空闲磁盘,我觉得空放着挺可惜,想将这块磁盘用起来。一个危险的想法就生成了,我想把这个磁盘加到ZFS Pool中去。

事件经过

我查了zpool的文章,有个zpool add和zpool attach的命令。我感觉zpool attach应该是追加磁盘的,但是试了几个命令都是失败的。

root@my-server:/home/user# zpool attach pool_name sdb sdd
invalid vdev specification
use '-f' to override the following errors:
/dev/sdd1 contains a filesystem of type 'ntfs'
root@my-server:/home/user# zpool attach -f pool_name sdb sdd
cannot attach sdd to sdb: no such device in pool
root@my-server:/home/user# zpool attach -f pool_name raidz1-0 sdd
cannot attach sdd to raidz1-0: can only attach to mirrors and top-level disks

我的磁盘是sdd,ZFS的报错信息感觉很没有头绪,什么“no such device in pool”,难道我需要先将我的盘加到pool里面么?attach命令不行,不是还有add命令么?我应该知道,存储系统是不能随便胡乱操作的。我转而尝试add命令,这个命令也失败了。

root@my-server:/home/user# zpool add pool_name  sdd
invalid vdev specification
use '-f' to override the following errors:
mismatched replication level: pool uses raidz and new vdev is disk

我看到了“use ‘-f’ to override the following errors”,但没有理解下面一行的意思。可以用“-f”太好了,加上“-f”果然可以了。查看pool的状态。

root@my-server:/home/user# zpool status
  pool: pool_name
 state: ONLINE
status: Some supported and requested 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: scrub repaired 0B in 02:38:28 with 0 errors on Sun Apr 13 03:02:29 2025
config:

    NAME               STATE     READ WRITE CKSUM
    pool_name          ONLINE       0     0     0
      raidz1-0         ONLINE       0     0     0
        sdc            ONLINE       0     0     0
        sde            ONLINE       0     0     0
        sdb            ONLINE       0     0     0
      sdd              ONLINE       0     0     0

sdd已经在pool里了,但是没有加到原来的raid组里。我想sdd已经在pool里了,应该可以使用attach命令了吧。再次执行attach命令。

root@my-server:/home/user# zpool attach pool_name sdc sdd
/dev/sdd is in use and contains a unknown filesystem.

什么意思?难道是因为sdd原来的数据没有清空,事后回过神来才知道这个“a unknown filesystem”是因为sdd已经加到pool里面了。我在错误的道路上继续狂奔,是不是需要用dd将原来的数据清除掉?因为觉得这个sdd是个空闲的盘,觉得不会有什么问题,但其实并不是。我用dd命令把整个盘都写了一遍零。这个时候已经铸成大错了。在我重启了服务器之后,啊…,pool不见了。使用“zpool import”命令也失败了。第一次import告诉我sdd是UNAVAIL状态,使用“-f”也不行,最后直接让我重建存储池了,可惜我并没有备份啊。

root@my-server:/home/user# zpool import
   pool: pool_name
     id: 16650549184859894038
  state: UNAVAIL
status: One or more devices contains corrupted data.
 action: The pool cannot be imported due to damaged devices or data.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-5E
 config:

    pool_name          UNAVAIL  insufficient replicas
      raidz1-0         ONLINE
        sdc            ONLINE
        sde            ONLINE
        sdb            ONLINE
      sdd              UNAVAIL
root@my-server:/home/user# zpool import -f -F pool_name
cannot import 'pool_name': no such pool or dataset
    Destroy and re-create the pool from
    a backup source.

这个时候我已经头皮发麻了。赶紧上网搜索解决方案,原来“zfs add”是给pool增加vdev,这样这个sdd和原来raidz1-0会形成一个raid0的存储池,数据会在两个设备间打散开来。好家伙,这样子整个存储池基本就没有冗余度了,只要sdd挂了,存储池就挂了,而我还来了个大杀器。我当时真是欲哭无泪,积攒了十年的数据,好多手机和相机拍的照片,还有很多好看的电影,可能全都没了。

一线生机

由于在我把sdd加到原来的pool之后,并没有写什么数据,我想原来的数据都应该还在之前盘上,感觉还有恢复的可能。我上网找数据恢复方法,实在不行研究ZFS代码也行。幸运地我找到了一个Github Issue “Import a pool with missing top-level vdevs”。原来对于这种有顶层设备损坏的pool,ZFS支持采用只读的方式导入。只能试一试了,方法并不复杂。先修改OpenZFS配置项,然后使用import命令。

root@my-server:/home/user# echo 1 > /sys/module/zfs/parameters/zfs_max_missing_tvds
root@my-server:/home/user# cat /sys/module/zfs/parameters/zfs_max_missing_tvds
1
root@my-server:/home/user# zpool import -o readonly=on pool_name

成功了!因为sdd上分出去的空间不多,大部分数据都还在,赶紧备份数据。但这个pool没法恢复正常了,只能在数据备份后重建存储池。需要倒腾数据,不过也是没有办法的事情。

血泪教训

向ZFS池中添加磁盘和替换磁盘是个危险操作,一定要在清醒时执行。至于attach命令是否支持对raidz追加磁盘,原来OpenZFS 2.3版才开始支持这个特性。我的OpenZFS是2.2.x版,还不支持此特性,而我看的是2.3版本的文档。好吧,这个有点伤心,不过我现在知道怎么去”杀死”一个ZFS存储池。