ZFS pool 恢复

警告

因为是测试环境,我自己的homelab,所以我不太重视数据安全性,采用了 zpool destory 来一次性销毁存储。

但是,我强烈建议你不要直接使用 zpool destroy ,这个命令和 rm -rf / 没有什么差别,几乎是瀑布式递归删除所有的被删除存储池下所有数据集数据。大杀器,慎用!!!

如果要清理数据,建议采用反向,从最低层的 dataset 开始,一点点删除和不断核对数据安全性完整性。避免出现盛昌环境故障!!!

我在移动硬盘上完成了 ZFS 复制(replication) ,意味着已经完成了ZFS数据的备份。我当时有点大意了,想着备份完成,可以缩容(删除zfs pool):

删除zpool
zpool destroy zstore-1
zpool destroy zdata

删除到第二个 zdata zpool时候报错了:

报错
cannot unmount '/zdata/jails/templates/14.3-RELEASE-base': pool or dataset is busy
could not destroy 'zdata': could not unmount datasets

突然发现我的开发容器处于 Docker容器使用NFS 状态,突然间无法读写挂载的NFS了。

一脸懵逼,突然想起来还有一些最近修订的文档没有提交git,不会丢失了吧?

ZFS pool删除前的系统变化

警告

虽然 zpool destory 过程打断依然可以恢复 zpool ,但是我发现有些 dataset 已经删除了。所以有可能恢复会比较麻烦,并不一定像我这里写得这么简单。例如,我发现我之前创建的 zdata/vms 卷集已经消失了(我已经备份,所以也没有再折腾)

检查发现,原来

  • ZFS pool在 destroy 步骤中会调用停止使用ZFS dataset的NFS服务,我的docker容器之所以突然无法读写NFS,只是因为NFS服务被停止了

  • ZFS pool的 destroy 时,如果数据集还有进程在使用(例如我这里因为 FreeBSD Jail 正处于运行状态),就会阻断pool删除( 此时有可能部分卷集还没有删除 )

很幸运, zdata 没有销毁,可以通过 zpool list 看到:

zpool list 显示 zdata 没有删除
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zdata  6.25T  1.75T  4.50T        -         -     0%    28%  1.00x    ONLINE  -
zroot   254G  13.5G   240G        -         -     1%     5%  1.00x    ONLINE  -

检查了 zdata/docs 数据集,发现数据还在。

  • 重新启动ZFS上NFS,也就是激活 nfsshare 参数就可以恢复 Docker容器使用NFS 访问(我尝试了重启NFS服务但是没有解决,后来发现原来是 nfsshare 参数关闭了,恢复就可以了)

设置ZFS数据集 sharenfs 属性
#zfs set sharenfs="-rw,-alldirs,-network=192.168.7.0/24" zdata/docs
#zfs set sharenfs="[email protected]/24" zdata/docs

# 暂时没有解决权限问题,官方文档没有找到案例
# 参考solaris zfs文档存在实现偏差,例如solaris zfs文档是先设置sharefs参数,然后再设置 sharefs=on ,但是在FreeBSD上on直接覆盖了前面设置的参数
zfs set sharenfs=on zdata/docs

# 参考 https://man.freebsd.org/cgi/man.cgi?query=zfsprops&sektion=7&manpath=freebsd-release
# sharenfs=on 相当于默认共享参数: sec=sys,rw,crossmnt,no_subtree_check

恢复已经 destroy 的zpool

如前述,我的 zstore-1 确实已经 destroy 了,那么有没有可能恢复呢?(这里只是为了做一个测试)

  • 检查当前系统已经被 destroy 的 zpool 可以使用 -D 参数:

检查当前有哪些已经处于 destoryed 状态的zpool ( -D )
zpool import -D

可以看到 zstore-1 状态是ONLINE,但是已经 DESTROYED :

检查当前有哪些已经处于 destoryed 状态的zpool ( -D )
   pool: zstore-1
     id: 15275943804102813621
  state: ONLINE (DESTROYED)
 action: The pool can be imported using its name or numeric identifier.
 config:

        zstore-1                      ONLINE
          diskid/DISK-54UA4062K7ASp1  ONLINE
  • 只要使用 -D 参数并指定zpool,依然可以导入已经 destroyed 的zpool:

导入已经 destroyed 的zpool
zpool import -D zstore-1

没有报错,此时再次使用 zpool list 命令就可以看到 zstore-1 zpool已经可以使用了

可以看到已经导入了 zstore-1
NAME       SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zdata     6.25T  1.75T  4.50T        -         -     0%    28%  1.00x    ONLINE  -
zroot      254G  13.6G   240G        -         -     1%     5%  1.00x    ONLINE  -
zstore-1   254G   681K   254G        -         -     0%     0%  1.00x    ONLINE  -

参考