【问题现象】
Linux系统中在磁盘空间占满时,普遍的做法是查看磁盘中占用空间较大的文件有哪些,然后对占用空间较大,而且删除后不会影响业务正常运行的文件进行删除。
但是有时会出现,明明大文件已经进行了删除,但是磁盘空间仍然未进行释放的现象。
【排查步骤】
1、查看磁盘空间状态
通过df -h命令查看磁盘空间状态显示根分区空间已满
[root@test ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 9.8G 9.7G 0 100% /
tmpfs 931M 0 931M 0% /dev/shm
/dev/sda1 190M 35M 145M 20% /boot
/dev/sda3 9.8G 23M 9.2G 1% /usr/local
/dev/sda5 9.8G 459M 8.8G 5% /var
/dev/sr0 3.7G 3.7G 0 100% /mnt
2、定位占空间较大的目录
通过du 命令查看根目录下的子目录空间大小状态并进行排序,可以看到/tmp目录最大
[root@test ~]# du -s /* | sort -nr | head -3
du: cannot access `/proc/2072/task/2072/fd/4': No such file or directory
du: cannot access `/proc/2072/task/2072/fdinfo/4': No such file or directory
du: cannot access `/proc/2072/fd/4': No such file or directory
du: cannot access `/proc/2072/fdinfo/4': No such file or directory
9420476 /tmp
3865227 /mnt
446564 /var
注意:这里使用du命令时不要加上-h参数,-h是使查询的结果输出更易读,但是sort排序时是以数字大小进行排序,加上-h之后不利于找出占用空间较大的目录。
3、查看目录下的文件大小
再次使用du命令对/tmp目录下的内容进行排查,可以看到access_log占用空间未9G左右,而根分区总的大小为10G,问题已经找到。
access_log为apache访问日志文件,这种状况一般是由于apache日志长期未进行清理导致。
[root@test ~]# du -s /tmp/* | sort -nr | head -3
9420468 /tmp/access_log
0 /tmp/yum.log
4、确认文件可以删除后,手动删除access_log文件
删除后再次查看,空间大小没有变化
[root@test ~]# rm -rf /tmp/access_log
[root@test ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 9.8G 9.7G 0 100% /
tmpfs 931M 0 931M 0% /dev/shm
/dev/sda1 190M 35M 145M 20% /boot
/dev/sda3 9.8G 23M 9.2G 1% /usr/local
/dev/sda5 9.8G 459M 8.8G 5% /var
/dev/sr0 3.7G 3.7G 0 100% /mnt
5、可能的原因
Linux系统中一个文件在文件系统中的存放分为两个部分:数据部分和指针部分,指针位于文件系统的meta-date中,在将数据删除后,这个指针就从meta-data中清除了,而数据部分存储在磁盘中。在将数据对应的指针从meta-data中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以在出现删除access_log文件后,空间还没释放,就是因为httpd进程还在一直向这个文件写入内容,导致虽然删除了access_log文件,但是由于进程锁定,文件对应的指针部分并未从meta-data中清除,而由于指针并未删除,系统内核就认为文件并未删除,因此通过df命令查询空间并未释放。
6、查看仍然被进程占用的删除文件列表
通过lsof命令可以看到httpd进程仍然在占用access_log文件
[root@test ~]# lsof | grep delete
httpd 2007 root 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2009 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2010 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2011 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2012 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2013 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2014 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2015 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
httpd 2016 apache 9w REG 8,2 9646555136 529815 /tmp/access_log (deleted)
7、解决方法
1)reboot重启
2)service httpd restart重启httpd服务
以上两种方法会导致业务中断
有效的方法是在不进行文件删除,使用echo命令在线清空文件,这种方法可以立即释放磁盘空间,也可保证进程继续向文件中写入日志。
[root@test ~]# echo " " > /tmp/access_log