文件已经删除,但是空间没有释放的异常
[[email protected] ~]#du -sh /tmp/* | sort -nr |head -3
通过命令发现在 /tmp 目录下有个 66G 大小的文件 access_log,这个文件应该是 apache 产生的访问日志文件,从日志大小来看,应该是很久没有清理的 apache 日志文件了,基本判定是这个文件导致的根空间爆满,在确认此文件可以删除后,执行如下删除命令,
[[email protected] ~]#rm /tmp/access_Iog
[[email protected] ~]#df -h
从输出来看,根分区空间仍然没有释放,这是怎么回事?
一般来说不会出现删除文件后空间不释放的情况,但是也存在例外,比如文件进程锁定,或者有进程一直在向这个文件写数据,要理解这个问题,就需要知道 linux 下文件的存储机制和存储结构。
一个文件在文件系统中存放分为两个部分:数据部分和指针部分,指针位于文件系统的 meta-data 中,在将数据删除后,这个指针就从 meta-data 中清除了,而数据部分存储在磁盘中。在将数据对应的指针从 meta-data 中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以出现删除 access_log 文件后,空间还没有释放,就是因为 httpd 进程还在一直向这个文件写入内容,导致虽然删除了 access_Ilog 文件,但是由于进程锁定,文件对应的指针部分并未从 meta-data 中清除,而由于指针并未删除,系统内核就认为文件并未被删除,因此通过 df 命令查询空间并未释放。
问题排查:
既然有了解决思路,那么接下来看看是否有进程一直在向 access_log 文件中写入数据,这里需要用到 linux 下的 losf 命令,通过这个命令可以获取一个仍然被应用程序占用的已删除文件列表。
[[email protected] ~]# lsof | grep delete
从输出可以看出,/tmp/access_log 文件被进程 httpd 锁定,而 httpd 进程还一直向这个文件写入日志数据,最后一列的‘deleted’状态说明这个日志文件已经被删除,但是由于进程还在一直向此文件写入数据,因此空间并未释放。
解决问题:
到这里问题就基本排查清楚了,解决这一类问题的方法有很多,最简单的方法就是关闭或者重启 httpd 进程,当然重启操作系统也可以。不过这些并不是最好的办法,对待这种进程不停对文件写日志的操作,要释放文件占用的磁盘空间,最好的方法是在线清空这个文件,具体可以通过如下命令完成:
[[email protected] ~]# echo “”>/tmp/access_log
通过这种方法,磁盘空间不但可以马上释放,也可以保障进城继续向文件写入日志,这种方法经常用于在线清理 apache /tomcat/nginx 等 web 服务产生的日志文件。
上一篇: LeetCode1两数之和C语言暴力版
下一篇: LeetCode1 两数之和(C++)