在遍历 HDD 上的目录树时,碎片似乎会产生许多不必要的搜索:
# stat -c %F 00 01 02
directory
directory
directory
# filefrag -v 00 01 02
Filesystem type is: ef53
File size of 00 is 12288 (3 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 428351942.. 428351942: 1:
1: 1.. 2: 428352760.. 428352761: 2: 428351943: last,eof
00: 2 extents found
File size of 01 is 12288 (3 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 428351771.. 428351771: 1:
1: 1.. 2: 428891667.. 428891668: 2: 428351772: last,eof
01: 2 extents found
File size of 02 is 12288 (3 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 428351795.. 428351795: 1:
1: 1.. 2: 428352705.. 428352706: 2: 428351796: last,eof
02: 2 extents found
e4defrag 无法对它们进行碎片整理
# e4defrag -v 00
ext4 defragmentation for directory(00)
[1/116] "00"
File is not regular file [ NG ]
那么如何对目录进行碎片整理呢?不是它的内容,而是目录本身。这些目录正在使用中,因此应该以原子方式完成,就像对常规文件进行碎片整理不会干扰它们的使用一样。
答案1
由于似乎没有任何用于目录索引的在线碎片整理工具,甚至离线碎片整理程序似乎也没有帮助,我不得不递归地重建目录树。
我写了一个小工具(碎片整理目录) 为了这个目的。遗憾的是,这种方法需要在碎片整理期间删除使用目录树的应用程序,这在处理数百万个文件时可能会花费大量时间。
答案2
如果您有可用空间,您可以在同一设备上创建新目录的并行树并将文件硬链接到它们,然后交换头目录的名称,然后在重新启动或其他应用程序关闭后删除原始目录树。我们过去常常用最小的文件空间来制作这样的克隆树来测试更改,或者在运行生产之外安装软件版本。
您可以首先构建每个目录目录(加速树遍历),然后首先构建最旧的文件,因为最年轻的文件很可能是短暂的。
我不确定这对于平面文件和目录以外的文件类型如何工作。我希望符号链接本身可以是硬链接的,并且可能是命名管道,但是设备呢?当然,我非常确定 Linux 中的 /prod 和 /dev 等反映内核表的假树是禁止的。