无法在大型 XFS 文件系统上创建文件

无法在大型 XFS 文件系统上创建文件

我们有一台 Linux 服务器,文件系统大小为 4 TB,用于存储 Subversion 存储库。有许多存储库,其中几个已经使用了好几年。

该磁盘最初约为 1 TB,但我们开始用尽空间,并在大约一年前将其增加到 4 TB。现在,人们报告无法将文件签入他们的存储库。错误消息是No space left on device

磁盘有大约 1.5 TB 的可用空间,并且还报告有可用的 inode - 但是,无法在其上创建新文件。仍然可以更新旧文件,并且间歇性地会更新某些存储库,但下一次尝试时同一个存储库可能会失败。

答案1

问题原因

问题在于 XFS 如何分配 inode。与大多数文件系统不同,分配是在创建新文件时动态进行的。但是,除非您另行指定,否则 inode 限制为 32 位值,这意味着它们必须适合文件系统上的第一个 TB 存储空间。因此,如果您完全填满了第一个 TB,然后扩大磁盘,您仍然无法创建新文件,因为无法在新空间上创建 inode。

解决方案 1 - 更改安装选项

一种解决方案是使用 mount 选项重新挂载文件系统inode64。但是某些应用程序在此情况下会表现异常(例如 MySQL),并且 NFS 会非常混乱。因此,如果您不确定您的系统是否可以使用此选项,您可以转到下一个选项。

解决方案 2 - 移动文件

第二种解决方案是找到当前存储在第一个 TB 中的一些文件,并将它们移动到文件系统的另一个区域。

按年龄移动

在我们的例子中,这很容易 - 文件系统已经使用多年,因此我们可以简单地找到最旧的文件并将它们从文件系统中移出,然后再将它们移回。这很容易使用 find 完成:

find /extra -mindepth 3 -maxdepth 3 -type d -mtime +730 -exec du -sh {} \; > /tmp/olddirs.txt

给出了一个列表,其中包含挂载点以下 3 级的所有目录的大小和目录名称,这些目录超过 2 年。然后我们可以对列表进行排序以找到最大的目录,并将mv它们移到另一个文件系统并再次移回。

按分配组移动

如果您不能简单地按照年龄来判断,例如当大量文件同时创建时,您仍然可以找到要移动的正确文件,但这需要更多的时间。

XFS 具有分配组(又称s),从 0 开始。您可以使用 检查每个 AG 的块大小和块数来确定哪些组位于第一个 TB 上xfs_info /path/to/mountpoint。或者您可以只检查前几个 AG 以查看哪些已满,然后清除它们。

  1. 检查前四个 AG 中的可用空间:
对于 `seq 0 1 5` 中的 ag;在 AG $ag 中执行 echo freespace;xfs_db -r -c "freesp -s -a $ag" /dev/CACHE/CACHE ;grep "total free";完成

如果任何组中的总可用空间少于 40,则您将无法在其中创建新文件。

  1. 在该 AG 中查找文件

这需要检查文件系统上每个文件的元数据。这将需要长的时间...这里有一个建议:

   查找/extra -mindepth 3 -type f -exec xfs_bmap -v {} \; > /tmp/agfilelist.txt

然后,您可以使用 grep for " 0 "(即一个空格、一个零和另一个空格)来查找 AG 0 上的所有文件,使用 grep for" 1 "来查找 AG 1 上的文件,等等...从 AG 0 开始,将最大的文件移开(使用mv,而不是cp!)然后再移回。重复此操作,直到您有足够的可用空间。

结果

一旦我们将足够多的文件从 /extra 移出然后再移回来,AG 0 中就会有大量空间,并且可以再次创建新文件。

相关内容