Linux 上的 ZFS:无法销毁快照,数据集正忙

Linux 上的 ZFS:无法销毁快照,数据集正忙

我正在尝试删除一堆旧的 ZFS 快照,但收到错误消息,指出数据集正忙:

[root@pool-01 ~]# zfs list -t snapshot -o name -S creation | grep ^pool/nfs/public/mydir | xargs -n 1 zfs destroy -vr
will destroy pool/nfs/public/mydir@autosnap_2019-02-24_03:13:17_hourly
will reclaim 408M
cannot destroy snapshot pool/nfs/public/mydir@autosnap_2019-02-24_03:13:17_hourly: dataset is busy
will destroy pool/nfs/public/mydir@autosnap_2019-02-24_02:13:17_hourly
will reclaim 409M
 cannot destroy snapshot pool/nfs/public/mydir@autosnap_2019-02-24_02:13:17_hourly: dataset is busy
will destroy pool/nfs/public/mydir@autosnap_2019-02-24_01:13:18_hourly will reclaim 394M

运行lsof显示没有进程访问这些快照:

[root@pool-01 ~]# lsof | grep pool/nfs/public/mydir

任何快照似乎都没有保留:

[root@pool-01 ~]# zfs holds pool/nfs/public/mydir@autosnap_2019-02-24_03:13:17_hourly
NAME                                                              TAG  TIMESTAMP

还有什么我应该注意的吗?除了reroot还能做什么吗?

答案1

最初,我使用以下方法来停止繁忙的数据集,以便我能够导出该数据集以进行池重建。我的目录使用 ZFS 数据集/home,但无法找到使其繁忙的进程。当您无法使用数据集找到流程时,这是我的解决方案,它也应该适合您:

  1. 在您希望导出(但导出时遇到问题)的所有数据集上设置:

    zfs set canmount=noauto dataset1
    zfs set canmount=noauto dataset2
    ...
    # and so on where you substitute your datasets' names for dataset1, dataset2, ...
    

    设置canmount=noauto确保数据集不会在重新启动时挂载

  2. 创建一个不使用数据集的用户帐户(或使用根帐户)/home等...授予此帐户 sudo 权限。

  3. 重新启动并登录到上述帐户,即您刚刚在步骤 2 中创建的帐户。该帐户应该在启动时不安装您在步骤 1 中修改的数据集,因此,拒绝任何守护程序/程序使用这些数据集。

  4. 由于数据集现在不忙,您现在可以销毁它们和/或其快照。

  5. 务必:

    zfs set canmount=on dataset1
    zfs set canmount=on dataset2
    ...
    

    到您想要在启动时安装的任何数据集。这是 zfs 默认值。

答案2

这似乎是 ZoL 上的意外行为,我将 ZFS 盒子单独放置了几天,最后放弃并重新启动了该盒子,并且在重新启动后我能够销毁这些快照。

答案3

我注意到我的快照由于某种原因确实很忙 - 它们都显示在输出中

mount

所以我做了一些鲁莽的事,只是投了

sudo umount /.zfs/snapshot/*

出乎所有人的意料,似乎没有什么不好的事情发生。然后我的sudo zfs destroy工作了。

答案4

我建议使用“zfs-way”,
这为我解决了这个问题,我认为它被认为更正确/干净:

#Use a variable so we need less hard-coding:
THE_DATA_SET=pool/nfs/public/mydir

#Make mounting impossible for a while (this also umounts it):
zfs canmount=off $THE_DATA_SET

#Find all snapshots and destroy them:
#("tail -n +2" is needed to remove the header in the "zfs list" output)
zfs list $THE_DATA_SET -t snapshot -o name | tail -n +2  | xargs -n 1 zfs destroy

#Make mounting possible again and do it:
zfs canmount=on $THE_DATA_SET
zfs mount $THE_DATA_SET

#And now we longer need the variable:
unset THE_DATA_SET

相关内容