我有一块 5 TB 的硬盘,里面有 3.3 TiB(据 报告du
)的媒体文件,这些文件和目录有 119k 个;平均文件大小约为 28 MiB。我用 将 ext4 分区转换为 btrfs btrfs-convert
。这个过程耗时 10.4 小时,并且 CPU 占用高。转换后:
# btrfs fi df /mnt/btrfs/
Data, single: total=3.03TiB, used=2.21TiB
System, single: total=32.00MiB, used=236.00KiB
Metadata, single: total=1.52TiB, used=1.10TiB
btrfs 分配了硬盘上的所有空间(3.03 + 1.52 TiB ≈ 5 TB),并且显然将约 1 TiB 的文件内容放入元数据块中(使用了 1.10 TiB)。这是出乎意料的,因为我的文件很少能放入叶节点中。
解决元数据分配量过大问题的标准方法是重新平衡元数据。btrfs balance start -m
耗时 8.0 小时,且受 I/O 限制。之后,btrfs 似乎不仅释放了未使用的元数据块,还将文件内容从元数据块移到了数据块中。
# btrfs fi df /mnt/btrfs/
Data, single: total=3.32TiB, used=3.31TiB
System, single: total=32.00MiB, used=104.00KiB
Metadata, single: total=3.00GiB, used=2.18GiB
有人能解释一下发生了什么吗?为什么“元数据”最初会消耗 1.10 TiB,为什么平衡会将其减少到 2.18 GiB?是否btrfs balance
将文件内容从元数据块移动到数据块?
我使用的是 Linux 内核 3.13.0-46。我的文件没有硬链接、xattrs、SELinux 上下文和 ACL。我没有打开压缩,也没有删除 ext4 回滚映像。
答案1
首先,转换过程会在新元数据中保存所有先前系统元数据的副本,这会占用大型驱动器上的大量空间。
其次,转换过程很混乱,导致范围非常大,因为 EXT4 中的范围也很大,而 BTRFS 会继承它们的大小。
分配的大小大约是已用元数据大小的 1.5 倍。碎片整理过程将减少已用元数据的大小,但不会改变分配。还有一个精简范围选项可以进一步减少元数据,但这在具有大量小文件的系统上更有帮助;您的元数据分配不到百分之十分之一,非常小。
平衡命令应该根据当前元数据使用情况将分配大小减少到新值,这似乎做得正确。平衡命令不应该从元数据移动到数据,但这可能与原始 EXT4 元数据映像副本位于原始元数据分配中,现在移动到数据(ext2_saved 子卷)有关。检查 EXT4 映像的大小以查看它是否为 1.1TB。无论如何,我会对文件系统进行碎片整理。
需要注意的是,运行 balance 时若没有进行碎片整理,则会导致错误。建议使用较新版本的内核,以防止出现文件系统问题,特别是 3.17 及更高版本。