已刪除的文件的進程占用空間導致根分區爆滿
在登上服務器的時候,使用Vim編輯一個文本文件,突然爆出swap錯誤,但是退出檢查沒有出現swap文件,查閱知可能是根分區爆滿,報錯
查看分區掛載使用
[[email protected] ~]# df -hT
發現是因為根分區使用率百分百
然後進入根目錄下
使用明亮查看各個目錄的大小
[[email protected] /]# du --max-depth=1 ./ -h
發現是jenkins的一個大量日誌占用空間,刪除日誌,就可以了
但是第二天登錄上服務器,又發現一個奇怪的問題,根分區再次爆滿
[[email protected] /]# df -hT
但是檢查發現,根下的目錄根本就沒有使用那麽大的空間
[[email protected] /]# 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 ./srv0 ./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中清除,而由於指針並未被刪除,那麽系統內核就認為文件並未被刪除
[[email protected] /]# 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)
殺掉這個進程
[[email protected] /]# kill -9 28893
再次查看分區使用情況
[[email protected] /]# 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
已刪除的文件的進程占用空間導致根分區爆滿