批量删除ZFS上的大型目录,而无需递归遍历


9

我想删除一个包含大量数据的目录。这是我的备份阵列,它是一个ZFS文件系统,线性跨度,单个池称为“ san”。San已安装在上面,/san 因此我要批量删除/ san / thispc / certainFolder

$ du -h -d 1 certainFolder/
1.2T    certainFolder/

rm -rf certainFolder/无需我等待,我可以销毁该目录的句柄,使其可覆盖(即使我选择重新创建它,也可以使用相同的目录名)是不是可以?

因此,例如对于不太了解zfs fs内部mgmnt具体是如何映射目录的,但是如果我发现该映射表示例如,并删除了正确的条目,例如,该目录将不再显示,并且该目录以前保留的空间也必须从某种审计中删除。

即使在ext3 fs上,是否有一种简单的方法可以做到这一点,还是递归remove命令首先已经要做的事情,即窃取并编辑日志?

我只是希望做一些类似的事情,kill thisDir即它只是删除某种ID,并且poof目录不再显示在ls -la驱动器中,并且数据显然仍然存在于驱动器上,但是现在可以重用该空间了(被覆盖),因为ZFS就是那么酷吗?

我的意思是我认为zfs真的很酷,我们该怎么做?理想地?一起搓手:-)

我的特定用例(除了对zfs的热爱之外)是对备份存档的管理。该备份目录通过Windows盒子上的freefilesync(AWESOME PROG)推送到smb文件共享,但也具有旧文件所在的版本目录。我要删除驻留在主备份中的顶层目录,这些目录已复制到该版本中-例如/san/version/someStuff,每两个月rm -rf /san/version/someStuff/*从腻子终端清除一次,现在我必须打开另一个终端;不想每次都这样做,我已经厌倦了不得不监视rm -rf。

我的意思是,也许我应该将命令设置为只松开手柄,然后打印到标准输出,这可能很好。 更现实的是,在zfs destroy san/version; zfs create -p -o compression=on san/version@Gilles响应后,在几秒钟后重新创建数据集。


仅供参考,我跑这个命令使目前使用即时通讯,其数据集..`zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
布莱恩·托马斯

如果您解决了原始问题中描述的问题,请接受答案。您刚刚附加到问题上的问题看起来完全不同,因此应在新问题中提出。
jlliagre

Answers:


12

在任何体面的文件系统中,跟踪释放的块都是不可避免的,ZFS 也不例外但是,在ZFS下有一种简单的方法可以通过“推迟”基础清理来实现近乎瞬时的目录删除。从技术上讲,它与Gilles的建议非常相似,但是本质上是可靠的,不需要额外的代码。

如果在删除目录之前创建文件系统的快照,则目录删除将非常快,因为无需在目录下探索/释放任何内容,所有内容仍由快照引用。然后,您可以在后台销毁快照,以便逐渐恢复空间。

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}

好的,我对快照不熟悉。这可能对我有帮助。我整天都在删除/移动。我不仅为主备份目录创建了数据集,还为其中的顶级目录创建了数据集,每个目录均以主机名开头,并包含一些顶级..,因此我在删除和重新创建池方面有一定的灵活性,但它并不完美,因为我将永远不会想删除这些整个池目录,所以我将不得不创建更多目录,这就是很多数据集制作的原因,因此,我喜欢您的建议!
Brian Thomas

4
如果启用的话,feature@async_destroy(如果从用户或管理员的角度出发)也可能有助于加快速度;见zpool get all $pool。请注意,至少我最后看过了,如果在pool import上正在进行挂起的销毁,那么销毁将变为同步,并且直到销毁完成后,池导入才会完成。请注意是否需要重启!
CVn

我有一个带有freenas的客户,该客户在大型删除操作时丢失了SMB连接。启用定期快照(并自动删除)后,“消失”了。释放空间在后台花费的时间更长,但是SMB-Share始终可以访问。
Martin Seitl '17

6

您要的是不可能的。或者,更准确地说,删除目录及其文件时需要付费。如果您在删除时不付款,则必须在其他地方付款。

您不仅要删除目录,而且要立即删除。您将删除目录及其中的所有文件,并且同样以递归方式删除其所有子目录。删除文件意味着递减其链接计数,然后将其资源(如果链接计数达到0且文件不是打开。这是目录树中每个文件必须执行的操作,因此花费的时间至少与文件数成正比。

您可以延迟将资源标记为免费的成本。例如,有一些垃圾收集的文件系统,您可以在其中删除目录而不删除其中包含的文件。运行垃圾收集器将检测通过目录结构无法访问的文件,并将其标记为空闲。这样做rm -f directory; garbage-collect的一个垃圾回收文件系统做了同样的事情,rm -rf在传统文件系统上,具有不同的触发器。垃圾收集的文件系统很少,因为GC是额外的复杂性,几乎不需要。当文件系统需要一些空闲块且找不到任何空闲块时,GC时间可能随时出现,因此操作的性能将取决于过去的历史记录,而不仅取决于操作,这通常是不希望的。您只需要运行垃圾收集器即可获取实际的可用空间量。

如果要模拟普通文件系统上的GC行为,可以执行以下操作:

mv directory .DELETING; rm -rf .DELETING &

(我省略了许多重要的细节,例如错误检查,对断电的恢复能力等。)目录名立即不存在;逐步回收空间。

避免在没有GC的情况下在删除过程中支付费用的另一种方法是在分配过程中支付费用。将目录树标记为已删除,并在分配块时浏览已删除的目录。用硬链接很难做到这一点,但是在没有硬链接的文件系统上,可以通过增加O(1)分配成本来实现。但是,这会使非常普通的操作(创建或放大文件)更昂贵,唯一的好处是相对便宜的操作(删除大目录树)更便宜。

如果目录树存储为自己的块池,则可以批量删除该目录树。(注意:我使用的“池”一词与ZFS的“存储池”的含义不同。我不知道正确的术语是什么。)这可能会很快。但是您如何处理可用空间?如果将其重新分配给另一个池,则要付出一定的代价,尽管比单独删除文件要少得多。如果您将该空间保留为未使用的保留空间,则无法立即对其进行回收。为目录树拥有一个单独的池意味着增加或减少该池的大小(即时或显式)的成本。使树成为其自己的存储池还增加了将文件移入和移出树的成本。


好的答案!在常规系统上,上半部分是完全可以满足的。ZFS有一些技巧,例如,不需要格式化它,因此,如果我破坏了池,我认为下一次我要做的就是像我想的那样使池(复数),然后ti消失雷达立即打开,并且该空间立即可用。我想我正在尝试在zfs上,池中的目录上重新创建它,并且我认为由于它不是池本身,因此它的性质变得更加标准,并且您提到的方法似乎适用于这种情况。有趣。
Brian Thomas

我认为那是我犯错的地方,昨晚我读了一篇文章,看不到我是否能找到它,这表明在FS上池的使用应仅限于〜18,446,744万亿个最大池。如果我将上层备份目录分别作为池,则当备份要写入池时,该目录将保持完整,这是一个易于删除的池。如果该池不存在,则备份将仅创建目录,并且在游泳池中看不见游泳池zfs list。在此之前,希望其他人对如何在池的子目录中的ZFS上批量删除进行一些投入。:-)
Brian Thomas

另外,在阅读您的第一个答复时,我的第一个想法是;“对!”,“费用”!那就是我在谈论删除日记条目时所涉及的内容。所以我怀疑。该死!但是,您走在正确的轨道上。让我们在这里提出一些建议,以便我们可以编写一个脚本来完成此操作…………:)
Brian Thomas

Brian,请注意不要混淆zpool和数据集。虽然您可以创建的zpool数目确实没有可达到的硬编码限制,但是您将很快受到计算机上可用的基础设备(例如分区)数目的限制。而且,拥有专用于单个目录的池将破坏一些有价值的zfs功能,并使移动操作慢得多。
jlliagre

关于此评论,您在此处进行了@Gilles“但是,您如何处理可用空间?如果将其重新分配给另一个池,则要付出一定的代价,尽管比单独删除文件要少得多”,我不确定,但是我不认为有是创建新池的惩罚者,我认为我只在写时间内处理它。永远不需要出于相同的原因进行分区。.我相信这是相同的机制..
Brian Thomas

1

如果必须快速,我将生成一个新的临时目录,mv在其下的目录中,然后递归删除该临时目录:

t=`mktemp -d`
mv certainFolder $t/
rm -rf $t &

和删除句柄或压扁错误?
Brian Thomas

1
这与Gilles的建议并没有真正的不同,并且具有相同的缺陷。如果重新引导操作系统或由于rm某些其他原因命令未完成,则幻像目录将保留不变。
jlliagre

嗯,对,但是&对我来说是陌生的,这就是难题的一部分...我想摆脱处理。但是,是的,您的权利,如果有问题,不要垃圾
布莱恩·托马斯

@BrianThomas &只是后台处理该进程,因此您可以在删除运行时继续在同一shell中执行其他操作(受任何相关的性能损失)。
CVn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.