有一个很好的问题,遗憾的是在我写一个相当广泛的答案时被删除了:(
不想让这种努力白费,让我从问题文本和评论中解释一下这个问题:
我观察到使用
dd
覆盖文件确实会增加碎片。我正在寻找一种dd
不会导致碎片化的替代方案。作为碎片如何发生的示例:想象一个占据整个文件系统的文件。开始覆盖它,您将立即看到该分区如何变得完全“空闲”,同时您将能够向其中写入另一个文件。块是动态分配的,并且当文件被覆盖时,零保证旧块将被重用。
我在多个文件系统(ext2、3 和 4、XFS、以及 FAT32 和 NTFS)和多个操作系统(win95 到现代 Fedora)上观察到这种行为。
我确信这与文件系统和操作系统无关。
我的主文件系统是 Bog 标准 ext4。 FedoraROOT:103874/1310720 个文件(0.2% 不连续)、1754833/5242880 个块。最小的整体碎片。
注意我我自己无法观察到这一点,我相信这些碎片声明的原始提问者!
答案1
太长了;博士!我应该使用什么工具来代替dd
?:是的cp
,如果您的 GNU coreutils 足够新的话。
实际的文件系统来救援
这根本不独立于文件系统和操作系统!块到文件的分配是特定文件系统的特定情况,它们之间存在差异。所以不能严格独立!
Ext4 的延迟分配来拯救
Ext4 支持刷新时分配:块是在数据刷新到磁盘时分配给文件的,而不是更早。这意味着,如果您的系统(现代 Fedora 肯定会这样做)使用文件系统缓冲区,则顺序扩展的文件的分配大小会非常大,因此碎片会非常低。您可以激活它,之后无需执行任何操作,而只需使用cp
or dd
(我更喜欢cp
,因为这不仅解决了您的第一个问题,还解决了您的第二个问题!)。
在 ext4 中,这称为延迟分配;只需添加delalloc
安装选项即可! (看man ext4
)
使用cp
will (在现代 Fedora 上)使用调用copy_file_range
,然后在将内容刷新到磁盘时导致连续分配。
XFS 来救援
XFS默认做延迟分配;参见 ext4。
相同的文件系统:reflink
当您使用cp
Fedora >=34 或 GNU coreutils >=9.0时cp
,它支持reflinks
,即简单地不是复制数据,而是简单地将块标记为由两个文件使用,并在其中一个发生更改时仅制作一份副本。这是一个非常好的功能,但当然只有当源文件和目标文件位于同一文件系统上时才有效。
其效果是目标文件与源文件完全相同(无碎片),因为它们实际上是相同的块。
不同的文件系统:XFS 分配组
XFS 不会将整个文件系统的可用空间和已用空间作为“一件事”来管理,它有多个分配组。引用man xfs
:
数据部分包含所有文件系统元数据(索引节点、目录、间接块)以及普通(非实时)文件的用户文件数据和日志区域(如果日志位于数据部分内部)。数据部分被分为多个分配组。分配组的数量和大小由 mkfs.xfs(8) 选择,因此通常有少量相同大小的组。分配组的数量控制文件和块分配中可用的并行度。如果有足够的内存和大量的分配活动,则应增加默认值。分配组的数量不应设置得太高,因为这可能会导致文件系统使用大量 CPU 时间,尤其是当文件系统接近满时。运行 xfs_growfs(8) 时会添加更多分配组(原始大小)。
所以,要解决“并发分配导致碎片”的问题,你只需要足够的分配组即可!我期望大小合理的文件系统有几个,但只需从默认值增加计数(我对 4 设备条带化 LVM 卷使用 5 个,这样看起来性能良好)就可以了。但是,您需要重新格式化或添加更多存储,才能增加分配组的数量。
救援工具
dd
不是用另一个文件覆盖文件的首选工具:cp
是;它会在当前版本(9.0)和 Fedora 附带的版本(带有 Fedora 补丁的 8.32)中使用copy_file_range
,它告诉底层文件系统最终将复制多少数据 - 这样分配就可以在块上进行。