1、介绍
阿里云监控发来邮件通知,磁盘使用率超过90%,提示需要清理磁盘,但是明明文件已删除:
登录阿里云后台查看,曲线图也是占用了90%
如图:
du -sh *
//查看根目录文件大小,发现并没有什么特大的文件
df -h
//看到dec占用了300多个G
这是系统根目录,之前我删除了很多日志文件,但是目前看来,空间没有释放
2、解决思路
一般来说不会出现删除文件后空间不释放的情况,但是也存在例外,比如文件被进程锁定,或者有进程一直在向这个文件写数据等,要理解这个问题,就需要知道Linux下文件的存储机制和存储结构。
一个文件在文件系统中的存放分为两个部分:数据部分和指针部分,指针位于文件系统的meta-data中,在将数据删除后,这个指针就从meta-data中清除了,而数据部分存储在磁盘中。在将数据对应的指针从meta-data中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以在出现删除日志文件后,空间还没释放,就是因为httpd进程还在一直向这个文件写入内容,导致虽然删除了日志文件,但是由于进程锁定,文件对应的指针部分并未从meta-data中清除,而由于指针并未删除,系统内核就认为文件并未删除,因此通过df命令查询空间并未释放也就不足为奇了。
3、问题排查
既然有了解决问题的思路,那么接下来看看是否有进程一直在向access_log文件中写数据,这里需要用到Linux下的lsof命令,通过这个命令可以获取一个仍然被应用程序占用的已删除文件列表,命令执行如下:
一般可能没安装这个命令,需自己yum install lsof -y
安装(以centos为例)
lsof | grep deleted
如图:
从输出结果可以看到,日志文件被进程php锁定,而php进程还一直向这个文件写入日志数据。从第7列可知,可得知日志文件大小,由此可知,删除的这些日志,才是最终祸首。最后一列的“deleted”状态说明这个日志文件已经被删除,但由于进程还在一直向此文件写入数据,因此空间并未释放。
4、解决问题
到这里问题就基本排查清楚了,解决这一类问题的方法有很多种,最简单的方法是关闭或重启php进程,当然也可以重启操作系统,不过这些并不是最好的方法。对待这种进程不停对文件写日志的操作,要释放文件占用的磁盘空间,最好的方法是在线清空这个文件,具体可以通过如下命令完成:
echo " " >xx.log
通过这种方法,磁盘空间不但可以马上释放,也可保障进程继续向文件写入日志,这种方法经常用于在线清理Apache、Tomcat、Nginx等Web服务产生的日志文件。
某种情况下,不能重启服务或者服务器,可以使用
kill -9 pid
杀死这些进程,然后再使用df -h
查看
已经释放了