我们有一个带有 4 TB 文件系统的 Linux 服务器,用于存储 subversion 存储库。有许多存储库,其中一些已经使用了几年。
该磁盘最初约为 1 TB,但大约一年前我们开始用完空间并将其增加到 4 TB。现在,人们报告无法将文件签入他们的存储库。错误消息是No space left on device
。
该磁盘有大约 1,5 TB 的可用空间,并且还报告有可用的 inode - 但是,无法在其上创建新文件。仍然可以更新旧文件,并且会间歇性地更新一些存储库,但同一存储库可能会在下一次尝试时失败。
问题的原因
问题在于 XFS 如何分配 inode。与大多数文件系统不同,分配会随着新文件的创建而动态发生。但是,除非您另外指定,否则 inode 被限制为 32 位值,这意味着它们必须适合文件系统上的第一个 TB 存储空间。因此,如果您完全填满了第一个 TB,然后扩大了磁盘,您仍然无法创建新文件,因为无法在新空间上创建 inode。
解决方案 1 - 更改安装选项
一种解决方案是使用 mount 选项重新挂载文件系统
inode64
。然而,一些应用程序在这方面会表现得很奇怪(例如 MySQL),而 NFS 会很困惑。因此,如果您不确定您的系统是否可以使用此选项,您可以继续下一个选项。解决方案 2 - 移动文件
第二种解决方案是找到一些当前存储在第一个 TB 中的文件,并将它们移动到文件系统的另一个区域。
按年龄移动
在我们的例子中,这很容易——文件系统已经使用了多年,所以我们可以简单地找到最旧的文件并将它们从文件系统中移开,然后再将它们移回。这很容易使用 find 完成:
给了我们一个列表,其中包含所有目录的大小和目录名称,这些目录正好位于挂载点以下 3 级,这些目录早于 2 年。然后我们可以对列表进行排序以找到最大的目录,并使用
mv
将它们移到另一个文件系统并再次返回。按分配组移动
如果您不能简单地按年龄划分,例如同时创建大量文件时,您仍然可以找到要移动的正确文件,但需要更多时间。
XFS 有分配组(又名AG),从 0 开始。您可以使用
xfs_info /path/to/mountpoint
. 或者您可以只检查前几个 AG 以查看哪些已满,然后清除它们。如果任何组中的总可用空间小于 40,您将无法在其中创建新文件。
这需要检查文件系统上每个文件的元数据。这将需要很长时间......这是一个建议:
然后,您可以 grep for
" 0 "
(这是一个空格、一个零和另一个空格)查找 AG 0 上的所有文件,grep for" 1 "
查找 AG 1 上的文件等...从 AG 0 开始,将最大的文件移开(使用mv
,不是cp
!)然后再返回。重复直到你有足够的可用空间。结果
一旦我们将足够多的文件从 /extra 中移出然后再移回来,AG 0 中就有大量空间,并且再次可以创建新文件。