我的ext4
(磁性)硬盘上有一个 900GB 的分区,没有缺陷,也没有坏扇区。除了一个空lost+found
目录之外,该分区完全是空的。该分区使用默认参数进行格式化,只是我将保留文件系统块的数量设置为 1%。
我使用 .zip 文件将 ~900MB 文件下载xubuntu-15.04-desktop-amd64.iso
到分区的挂载点目录中wget
。下载完成后,我发现文件被分成了四个片段:
filefrag -v /media/emma/red/xubuntu-15.04-desktop-amd64.iso
Filesystem type is: ef53
File size of /media/emma/red/xubuntu-15.04-desktop-amd64.iso is 1009778688 (246528 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 32767: 34816.. 67583: 32768:
1: 32768.. 63487: 67584.. 98303: 30720:
2: 63488.. 96255: 100352.. 133119: 32768: 98304:
3: 96256.. 126975: 133120.. 163839: 30720:
4: 126976.. 159743: 165888.. 198655: 32768: 163840:
5: 159744.. 190463: 198656.. 229375: 30720:
6: 190464.. 223231: 231424.. 264191: 32768: 229376:
7: 223232.. 246527: 264192.. 287487: 23296: eof
/media/emma/red/xubuntu-15.04-desktop-amd64.iso: 4 extents found
考虑到这可能与某种原因有关wget
,我从分区中删除了 ISO 文件,使其再次为空,然后v1.mp4
使用 .txt 文件将 ~700MB 文件复制到分区cp
。该文件也支离破碎。它被分成三个片段:
filefrag -v /media/emma/red/v1.mp4
Filesystem type is: ef53
File size of /media/emma/red/v1.mp4 is 737904458 (180153 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 32767: 34816.. 67583: 32768:
1: 32768.. 63487: 67584.. 98303: 30720:
2: 63488.. 96255: 100352.. 133119: 32768: 98304:
3: 96256.. 126975: 133120.. 163839: 30720:
4: 126976.. 159743: 165888.. 198655: 32768: 163840:
5: 159744.. 180152: 198656.. 219064: 20409: eof
/media/emma/red/v1.mp4: 3 extents found
为什么会发生这种情况?有没有办法防止这种情况发生?我认为ext4
这是为了抵抗碎片化。相反,我发现当该卷的所有其余部分均未使用时,它会立即将一个单独的文件碎片化。这似乎比FAT32
和更糟糕NTFS
。
答案1
900mb 文件中包含 3 或 4 个片段是非常好。当该大小的文件有超过 100 个碎片时,碎片就会成为一个问题。对于 fat 或 ntfs,将这样的文件分成数百个片段的情况并不罕见。
至少在较旧的 ext4 文件系统上,您通常不会看到比这更好的结果,因为块组的最大大小为 128 MB,因此每 128 MB,连续空间就会被几个块打破,用于分配位图和索引节点表。下一个块组。一个更新的 ext4 功能称为弹性背景允许将这些表的多个(通常是 16 个)块组打包在一起,留下更长的可分配块运行,但根据您的发行版以及用于格式化它的 e2fsprogs 版本,可能尚未使用此选项。
您可以用来tune2fs -l
检查格式化文件系统时启用的功能。
答案2
我无法真正回答,但我认为这可能会有所帮助:
请注意每个片段的大小最多为 32768 个块(2 的幂,这应该会引发一个正在发生某些事情的标志,并且还会提示您要查找的内容)。
另外值得注意的是,范围之间的物理偏移量彼此非常接近。
ext4 文件系统分为一系列块组。为了减少碎片造成的性能困难,块分配器尽力将每个文件的块保留在同一组中,从而减少查找时间。块组的大小在 中指定
sb.s_blocks_per_group blocks
,但也可以计算为 8 *block_size_in_bytes
。默认块大小为 4KiB,每组将包含 32,768 个块,长度为 128MiB
再往下:
ext4 用来对抗碎片的第一个工具是多块分配器。首次创建文件时,块分配器会推测性地将 8KiB 磁盘空间分配给该文件 [...] ext4 使用的第二个相关技巧是延迟分配。在这种方案下,当文件需要更多块来吸收文件写入时,文件系统会推迟决定磁盘上的确切位置,直到所有脏缓冲区都被写出到磁盘。通过在绝对必要之前不提交特定位置(达到提交超时,或调用sync(),或内核内存不足),希望文件系统可以做出更好的位置决策。
所以我只想说分配器关心关于块组(那些 32K 块)内的数据局部性,而不是关于块组彼此连续。