在登上服务器的时候,使用Vim编辑一个文本文件,突然爆出swap错误,但是退出检查没有出现swap文件,查阅知可能是根分区爆满,报错
查看分区挂载使用
[root@www ~]# df -hT
发现是因为根分区使用率百分百
然后进入根目录下
使用明亮查看各个目录的大小
[root@www /]# du --max-depth=1 ./ -h
发现是jenkins的一个大量日志占用空间,删除日志,就可以了
但是第二天登录上服务器,又发现一个奇怪的问题,根分区再次爆满
[root@www /]# df -hT
但是检查发现,根下的目录根本就没有使用那么大的空间
[root@www /]# du --max-depth=1 ./ -h
4.0K ./selinux 14M ./sbin 587M ./var 16G ./opt 28M ./etc 59G ./backup 139M ./lib 6.9M ./bin 3.4G ./usr 16K ./lost+found 777M ./root 20M ./databak 0 ./proc 15G ./data 4.0K ./srv 0 ./sys 22M ./boot 1.7M ./tmp 639M ./home 4.0K ./mnt 200K ./dev 4.0K ./media 22M ./lib64 95G ./
然后尝试删除其他分区的文件,发现并没有减少,排除其他分区占用根的情况,后续查阅得知,是由于Jenkins的进程依然占用着已删除的文件
在Linux或者Unix系统中,通过rm或者文件管理器删除文件,只是将它会从文件系统的目录结构上解除链接(unlink),也就是说只是删除了文件和系统目录结构的链接;如果文件在删除时是被打开的(有一个进程正在使用该文件,文件被进程锁定或者有进程一直在向这个文件写数据等)状态,那么进程将仍然可以读取该文件,也就是说没有删除掉文件在读取的状态,所以磁盘空间也就会一直被占用。 一个文件在文件系统中的存放分为两个部分:数据部分和指针部分,指针位于文件系统的meta-data中,数据被删除后,这个指针就从meta-data中清除了,而数据部分存储在磁盘中,数据对应的指针从meta-data中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以出现删除文件后,空间还没释放,就是因为有进程还在一直向这个文件写入内容,导致虽然删除了文件,但文件对应的指针部分由于进程锁定,并未从meta-data中清除,而由于指针并未被删除,那么系统内核就认为文件并未被删除
[root@www /]# lsof |grep delete
java 28893 jenkins 19r REG 8,3 1484022 5376261 /tmp/jna4374897431416021330jar (deleted) java 28893 jenkins 21w REG 8,3 82550824960 6165218 /var/log/jenkins/jenkins.log (deleted) java 28893 jenkins 22r REG 8,3 2351351 5376263 /tmp/winstone6467252256712090451.jar (deleted)
杀掉这个进程
[root@www /]# kill -9 28893
再次查看分区使用情况
[root@www /]# df -hT
已经恢复正常,可以正常操作
但是这种方法并不可取,因为kill进程是通过截断proc文件系统中的文件可以强制要求系统回收分配给正在使用的的文件。必须要确定不会对运行中的进程造成影响时才能使用,应用程序对这种方式支持的并不好,当一个正在使用的文件被截断可能会引发不可预知的问题。
也可以重启使用该文件的进程,或者重启服务器
最优解决,在线清理,对待这种进程不停对文件写日志的操作,要释放文件占用的磁盘空间,最好的方法是在线清空这个文件
通过这种方法,磁盘空间不但可以马上释放,也可保障进程继续向文件写入日志。 在线清空文件(比如/var/log/jenkins/jenkins.log)的方式: # echo " " > /var/log/jenkins/jenkins.log # cat /dev/null > /var/log/jenkins/jenkins.log # >/var/log/jenkins/jenkins.log