在 Linux 的 Ext3/4 驱动器上快速删除大型目录

在 Linux 的 Ext3/4 驱动器上快速删除大型目录

我一直在研究一些重复数据删除技术,这迫使我将文件系统用作哈希表。这导致使用几乎所有合理方法(例如,,,等)删除某些目录需要花费数小时rm -rf的时间ls -f1 | xargs rmfind -delete

在 Ext2/3/4 文件系统下,目录是一个包含从文件名到 inode 编号的哈希表的文件(在我的情况下,大约 60 MB!)据我了解,运行rm -rf和朋友很慢,因为它遵循这种方法:

迭代目录文件中的哈希表。对于遇到的每个文件名-inode 对,原子地:

  1. 减少 inode 上的名称计数。
  2. 从哈希表中删除该条目。

(当文件/inode 的名称计数达到 0 并且没有打开文件描述符并指向这些 inode 的程序时,就会删除这些文件/inode。)

减少 inode 的名称计数很快。

删除文件(特别是小文件)也很快:只需在可用性表中将文件拥有的驱动器块指定为空闲即可。

据我所知,速度变慢是由于从哈希表中删除条目造成的。每次删除可能都有机会触发重新哈希,因为我观察到目录文件的大小随着文件被删除而减小。

我的要求有两个:

  • 我的推理是否正确,是哈希表操作减慢了这个过程?
  • 如果是,是否有一个工具可以执行以下操作(并且因此可能速度更快?)

    1. 减少目录文件中列出的每个 inode 的名称计数。
    2. 一次性删除整个目录的所有内容。

答案1

ext3/4 目录本身并不是哈希表。它实际上是一棵哈希树。也就是说,文件名被哈希化,哈希用作插入 b+ 树的索引。删除所有文件的最快方法是按 inode 编号对文件进行排序,因为这将最大限度地减少将 inode 从 inode 表拉入内存所需的磁盘寻道,以及在文件被释放时对 inode 表的更新。这还将倾向于按照文件的创建顺序删除文件,这将优化各种块和 inode 分配位图的更新方式。您可以做的另一件事是增加日志的大小(使用 tune2fs 删除日志,然后使用更大的日志大小重新创建它)。

最后,您应该记住,文件系统并未针对数据库进行优化。如果您想进行重复数据删除,您确实应该考虑使用数据库,而不是尝试使用 shell 脚本和使用目录作为快速而肮脏的数据库来破解它。正如您所发现的,这样做效果并不好……

答案2

删除整棵树是一项昂贵的操作,但有办法可以加快其速度。

您是否尝试过这个答案这个答案?似乎是最快的,因为它优化了删除操作,而不是像、、...rsync那样简单地遍历文件列表。rmfind

另外,你试过吗选择?

编辑:

请注意:我还没有对这些命令进行过基准测试。

如果将来链接中断,我指的是命令:

rsync前两个链接的命令:

mkdir blank
rsync -a --delete blank/ test/

第三个链接:“将它们移动到隐藏目录,然后在后台删除”:

mkdir ../.tmp_to_remove
mv -- * ../.tmp_to_remove
nohup rm -rf ../.tmp_to_remove &

正如该答案中所述,这种方法假设(即使删除非常昂贵)由于删除发生在另一棵树的后台,因此用户可能不关心实际成本。在我看来,只要您在删除操作发生之前不尝试关闭 bash/ssh 会话,情况就是如此。为了解决这个问题,我在命令nohup中添加了rm

答案3

那么,miravalis 的答案中两种方法的组合怎么样?当你想“rm -rf deldir/*”时,请执行

mkdir .tmp1 .tmp2
mv deldir .tmp2/
nohup rsync -a --delete .tmp1/ .tmp2/ &
mkdir deldir

相关内容