服务器写入文件的时候出现错误,使用touch 1.txt 后出现 no space left on device, 然j就使用 df 看到 硬盘分区 使用率 100% 后,找到自旧日志文件进行删除操作后,看到空余的硬盘空间,可仍旧无法写入文件。

这就是 Linux/unix 文件系机制的问题,Linux/Unix like OS 的文件系统中每个目录树中的节点并不是像 Windows 直接包含文件的具体信息,而只包含了文件名和 Inode number 。通过 Inode number 所找到对应于文件名的 Inode 节点中才真正记录了文件的大小/物理地址/所有者/访问权限/时间戳/被硬链接的次数等实际的metadata。因此你可以在 Linux 系统中通过硬链接( hard link ) 的方式给某个文件创建无数个位于不同目录下的文件名,而实际的文件数据只需要一份拷贝。

Inode是索引节点,每个存储设备(例如硬盘)或存储设备的分区被格式化为文件系统后,有两部份,一部份是inode,另一部份是 Block,Block是用来存储数据用的。而inode呢,就是用来存储这些数据的信息,这些信息包括文件大小、属主、归属的用户组、读写权限等。 inode为每个文件进行信息索引,所以就有了inode的数值。操作系统根据指令,能通过inode值最快的找到相对应的文件。

缺省情况下, Linux 在系统安装过程中按照1个 Inode 对应 2k 硬盘空间来计算每个分区的最大 Inode 数。一旦文件系统创建之后,每个分区可用 Inode 数就无法进行动态调整。但也正因为这种文件系统的结构,当你在 Linux 中进行 IO 操作的时候,需要的资源除了硬盘空间以外,还要有剩余的 Inode 才可继续操作。

也就是检查硬盘 block空间之外也检查 系统的 Inode占用率。

检查

检查 block

# df -h
Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/xvda1     ext4    20G  6.2G   13G  34% /
tmpfs          tmpfs  3.9G     0  3.9G   0% /dev/shm

检查 Inodes*

# df -i
Filesystem     Type  Inodes IUsed IFree IUse% Mounted on
/dev/xvda1     ext4    1.3M  1.3M     0  100% /
tmpfs          tmpfs   984K     1  984K    1% /dev/shm

可以看出 Inodes 空间已被占用 100%了, 这个说明有很多的文件占用了硬盘空间的 Inodes。 这个时检查文件数量。

解决

检查文件

cd /
for i in ./*; do echo $i; find $i | wc -l; done

从文件数量最大的文件继续检查。我这里检查到 maildrop 文件夹占用了大量的文件节点。

cd /var/spool/postfix/maildrop
ls | wc -l

使用 find + xargs 形式删除文件,当然也可以使用 rm -f ./* 来删除文件。

find ./ -type f -name "*"|xargs rm -f

postfix/maildrop 文件夹占用大量的文件,多是系统邮件发送导致。如果系统中有用户开启了cron,而cron中执行的程序有输出内容,输出内容会以邮件形式发给cron的用户,而sendmail没有启动所以就产生了这些文件; 将crontab里面的命令后面加上 > /dev/null 2>&1 或者crontab里面的命令后面加上 > /dev/null 基本上可以避免如此多的垃圾文件生产。

来100个文件检查下是否可以创建文件了。

cd 
touch {1..100}.txt
ls

超出系统中同时运行的最大 message queue 个数限制 ,可以在root下用sysctl kernel.msgmni检查该参数,sysctl -w kernel.msgmni=xxx 重新设定即可。