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

Jen*_*y D 24 linux xfs

我们有一个带有 4 TB 文件系统的 Linux 服务器,用于存储 subversion 存储库。有许多存储库,其中一些已经使用了好几年。

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

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

Jen*_*y D 44

问题的原因

问题出在 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
Run Code Online (Sandbox Code Playgroud)

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

按分配组移动

如果您不能简单地按时间排序,例如,当同时创建了大量文件时,您仍然可以找到要移动的正确文件,但需要更多时间。

XFS 有分配组(又名AG),从 0 开始。您可以检查每个 AG 的块大小和块数,以使用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“完全免费”;完毕

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

  1. 在该 AG 中查找文件

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

   find /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 中有很多空间,可以再次创建新文件。