减少收缩 ext4 文件系统的时间

减少收缩 ext4 文件系统的时间

我需要缩小一个大的 ext4 卷,并且我希望在尽可能减少停机时间的情况下完成此操作。根据我到目前为止所做的测试,看起来它可以在长达一周的时间内卸载以调整大小。有没有什么方法可以提前在线对文件系统进行碎片整理,以便调整大小时不必移动这么多块?

更新: 达到这一点需要一些时间,移动了相当多 TB 的数据以准备收缩,并且我一直在尝试使用下面答案中的信息。我最终想出了以下命令行,只需稍加修改,它就可以对其处于类似情况的其他人有用。另请注意,它应该以 root 身份运行,filefrag 和 e4defrag 命令才能正常工作 - 它不会影响文件所有权。它也可以在具有多个硬链接的文件上正常工作,我有很多硬链接。

find -type f -print0 | xargs -0 filefrag -v | grep '\.\.[34][0-9]\{9\}.*eof' -A 1 | awk '/extents found/ {match($0, /^(.*): [0-9]+ extents found/, res); print res[1]}' | xargs -n 1 -d '\n' e4defrag

快速解释以方便其他人修改/使用:

第一个“查找”命令构建要使用的文件列表。现在可能是多余的,或者可以用更好的方法来完成,但是在测试时我在那里有其他过滤器,并且我将其保留为修改命令其余部分范围的方便位置。

接下来将每个文件传递给“filefrag -v”以获取每个文件使用的所有物理块的列表。

grep 查找每个文件使用的最后一个块(以“eof”结尾的行),该块是一个以 3 或 4 开头的 10 位数字。在我的例子中,我的新文件系统大小将是 2980024320 块长,这样仅处理要删除的磁盘区域上的文件就足够好了。让 grep 还包含以下行(“-A 1”)还会在下一部分的输出中包含文件名。这是其他执行此操作的人必须根据其文件系统的大小修改命令的地方。它也可能以更好的方式完成,但这现在对我有用,而且我很懒。

awk 仅从 grep 留在 filefrag 输出中的所有其他垃圾中提取文件名。

最后调用 e4defrag - 我不关心实际的碎片计数,但它具有移动物理块的副作用(希望进入驱动器的早期部分),并且它适用于具有多个硬链接的文件无需额外的努力。

如果您只想知道它将对哪些文件进行碎片整理而不实际移动任何数据,则只需关闭命令的最后一部分即可。

find -type f -print0 | xargs -0 filefrag -v | grep '\.\.[34][0-9]\{9\}.*eof' -A 1 | awk '/extents found/ {match($0, /^(.*): [0-9]+ extents found/, res); print res[1]}'

答案1

据我所知,ext4fs支持在线碎片整理(它列在“完成”下,但状态字段为空;原来的补丁从 2006 年底开始)到e2fsprogs 1.42 或更高版本中的 e4defrag 在 Linux 2.6.28 或更高版本上运行时允许您查询目录或可能的文件系统的状态,并且至少对单个文件进行碎片整理。e2fsprogs截至今天,版本为 1.42.8。

不过,我不确定这是否对您有帮助,因为您想做的似乎并不多碎片整理数据为巩固磁盘上的数据。两者经常一起完成,但它们是截然不同的操作。

整合数据的简单方法可能假设您有合理数量的可用空间,工作是将每个文件复制到同一文件系统上的其他逻辑逻辑,然后使用 mv 用新副本替换 inode 指向的数据。这在很大程度上取决于 ext4 分配器的具体工作方式,但它可能值得尝试,而且编写脚本应该相当容易。只需留意从多个位置硬链接的文件(使用这样的方案,最简单的方法可能是简单地忽略链接计数 > 1 的任何文件,并让 resizefs 处理这些文件)。

相关内容