如何对 ext4 上的“目录文件”进行碎片整理或最小化?

如何对 ext4 上的“目录文件”进行碎片整理或最小化?

我的硬盘上有一个相当旧的主目录。有很多文件被创建和删除,现在 /home/username 的大小为 995328 字节。请注意,我指的是“目录文件”的大小(每个目录都是一个特殊文件,其中包含指向其他文件和目录的链接),而不是其中文件的总大小。换句话说,这就是您在 ls -la 输出中看到的“.”(点)目录的大小。

我的主目录中只有 244 个文件+目录。在另一台电脑上,我的主目录中有 203 个文件+目录,而“.”目录只有 4096 字节。这可能并不令人担忧,但我注意到在玩 Natural Selection 2 时性能大幅下降。特别是,它将编译的着色器和模块保存在“~/.config/Natural Selection 2”中,因此每次访问那里的文件时,它都必须遍历这个巨大的~1 Mb 主目录。

为了加快速度,我将其目录移至 /opt/confs(我的根分区在 SSD 上,游戏本身也驻留在 /opt 中),这很有帮助。但是,其他玩家仍然在我之前加载,他们也在 Windows 和 SSD 上。我还尝试将该目录从“/opt/confs/Natural Selection 2”挂载到“~/.config/Natural Selection 2”,但我没有看到任何改进。

确实有帮助的是,在 /opt/home(即 SSD 上)中创建一个新用户,并使用它来启动游戏,这样 /home/username 就不再使用了。我有了很大的改进,比如翻了一番,37 秒而不是 1 分 15 秒。我有 32 Gb 的 RAM(任何时候只占用 10-12 Gb),所以所有这些都应该被大量缓存,HDD 速度不应该干扰路径遍历。

我认为主目录文件现在充满了删除旧文件和 .* 目录后留下的空洞,因此查找速度很慢。除了创建一个新目录并将文件和目录移入其中,删除现在为空的旧主目录并重命名这个新目录外,我找不到其他方法使它更小更快。但这是一种黑客方法,如果这真的是个问题,应该有一种方法可以处理稀疏目录。尤其是当每个人都说 ext 文件系统根本不需要碎片整理时。好吧,对于文件来说这是真的,但似乎没有人关心目录。

编辑:忘记测试其他情况以排除其他可能性。我将该用户的主目录移至 /home(位于 HDD 上),并将游戏的配置目录移至 /opt/confs(SSD)。所以现在路径如下 /(SSD)/home/(HDD)/newuser/.config/(仍为 HDD)Natural Selection 2(符号链接到 /opt/confs/Natural Selection 2,SSD)。仍然加载得相当快,与纯 SSD 路径(43 秒)没有区别。然后我做了一个控制测量:我将新用户的主目录移到我的主要用户的主目录中,因此它的路径是 /home/rkfg/newuser,其中 /home/rkfg 是有问题的碎片目录。游戏的配置目录仍然符号链接到 SSD,其他一切都相同。而且长时间的加载时间又回来了:1 分 39 秒!现在它必须遍历大型目录文件,而且由于游戏每秒执行数十次,所以加起来就很多了。是的,这部分优化得不是很好,希望它会变得更好。但关键是:巨大且碎片化的目录文件确实会产生更长的寻道时间。尽管进行了所有优化,但缓存并没有多大帮助。

答案1

我优化这些目录文件的方法基本上是:创建一个新目录来替换原目录,将所有剩余文件移至新目录并清理。这样就创建了一个经过优化的新目录文件。

mv ORGDIR ORGDIR_MOVED
mkdir ORGDIR
chown ... ORGDIR  # Replicate ownership
chmod ... ORGDIR  # Replicate permissions
mv ORGDIR_MOVED/* ORGDIR_MOVED/ ORGDIR_MOVED/..?* .[^.]* ORGDIR/
rmdir ORGDIR_MOVED  # Should be empty, check if issue.

您也可以先将文件移出目录;

mkdir ORGDIR_NEW
chown ... ORGDIR_NEW  # Replicate ownership
chmod ... ORGDIR_NEW  # Replicate permissions
mv ORGDIR/* ORGDIR/.[^.]* ORGDIR/..?* ORGDIR_NEW/
mv ORGDIR ORGDIR_OLD
mv ORGDIR_NEW ORGDIR
rmdir ORGDIR_OLD  # Should be empty, check if issue.

我同意存在性能问题(我自己有时也会遇到这些问题)。

答案2

这个问题很老了,但有一个简单的解决方案,不需要重新创建目录,但是,它需要卸载分区(因此对于根分区,您需要从实时 USB 或类似设备启动)。运行fsck.ext4 -f -D /dev/sdXN(其中 X 是设备字母,N 是分区号),它将检查文件系统并优化目录,使它们恢复正常大小。-D默认情况下不使用该标志。我不确定所述问题是否仍然存在,因为相关游戏现在将其数据存储在不同的位置,并且我现在使用的内核更新得多(6.x)。

man fsck.ext4

-D 优化文件系统中的目录。此选项使 e2fsck 尝试优化所有目录,如果文件系统支持目录索引,则通过重新索引它们,或者通过对较小目录或使用传统线性目录的文件系统进行排序和压缩目录。

即使没有 -D 选项,e2fsck 有时也会优化一些目录 --- 例如,如果启用了目录索引,而某个目录尚未编入索引,并且编入索引会对其有益,或者索引结构已损坏且需要重建。-D 选项会强制优化文件系统中的所有目录。这有时可以使它们变得更小,搜索速度更快,但实际上,您很少需要使用此选项。

-D 选项将检测单个目录中具有重复名称的目录条目,出于性能原因,e2fsck 通常不会强制执行该操作。

相关内容