我正在尝试删除一堆旧的 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
,但无法找到使其繁忙的进程。当您无法使用数据集找到流程时,这是我的解决方案,它也应该适合您:
在您希望导出(但导出时遇到问题)的所有数据集上设置:
zfs set canmount=noauto dataset1 zfs set canmount=noauto dataset2 ... # and so on where you substitute your datasets' names for dataset1, dataset2, ...
设置
canmount=noauto
确保数据集不会在重新启动时挂载创建一个不使用数据集的用户帐户(或使用根帐户)
/home
等...授予此帐户 sudo 权限。重新启动并登录到上述帐户,即您刚刚在步骤 2 中创建的帐户。该帐户应该在启动时不安装您在步骤 1 中修改的数据集,因此,拒绝任何守护程序/程序使用这些数据集。
由于数据集现在不忙,您现在可以销毁它们和/或其快照。
务必:
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