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

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

磁盘最初大约是1TB,但是一年前我们开始空间不足,增加到4TB。 现在,人们正在报告无法检查文件到他们的回购。 错误消息是No space left on device

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

问题的原因

问题原来在于XFS如何分配inode。 与大多数文件系统不同,在创build新文件时会dynamic分配。 但是,除非另外指定,否则索引节点仅限于32位值,这意味着它们必须在文件系统的第一兆字节的存储空间内。 因此,如果您完全填充第一个TB,然后放大磁盘,则仍然无法创build新文件,因为无法在新空间创buildinode。

解决scheme1 ​​ – 更改安装选项

一种解决scheme是使用mount选项inode64重新安装文件系统。 然而,一些应用程序会在这个(例如MySQL)上performance怪异,NFS将会非常混乱。 所以如果你不确定你的系统是否可以使用这个选项,你可以转到下一个选项。

解决scheme2 – 移动文件

第二个解决scheme是find当前存储在第一兆字节的一些文件,并将它们移动到文件系统的另一个区域。

按年龄移动

在我们的例子中,这很容易 – 文件系统已经使用多年了,所以我们可以简单地find最旧的文件,并将它们从文件系统中移走,然后将它们移回。 这很容易使用find来完成:

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

给了我们一个包含所有目录的大小和目录名的列表,它们在挂载点以下的正下方3个级别,大于2年。 然后,我们可以对列表进行sorting以find最大的目录,并使用mv将它们移动到另一个文件系统,然后再返回。

按分配组移动

如果你不能简单地按年龄去做,例如,当同时创build大量文件时,仍然可以find正确的文件移动,但需要更多的时间。

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

  1. 检查前四个AG中的可用空间:
 对于农业部门0 1 5`; 在AG $ ag中使用echo freespace;  xfs_db -r -c“freesp -s -a $ ag”/ dev / CACHE / CACHE;  grep“完全免费”;  DONE 

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

  1. 在该AG中查找文件

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

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

然后,你可以grep为" 0 " (这是一个空格,一个零和另一个空格)findAG 0上的所有文件,grep为" 1 "findAG 1上的,等等…开始AG 0,移动最大的文件(使用mv ,而不是cp !),然后再回来。 重复,直到你有相当数量的空间免费。

结果

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