1. 程式人生 > >已刪除的文件的進程占用空間導致根分區爆滿

已刪除的文件的進程占用空間導致根分區爆滿

color lib64 依然 win 文本文 程序 重啟 del 系統目錄結構

在登上服務器的時候,使用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    ./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中清除,而由於指針並未被刪除,那麽系統內核就認為文件並未被刪除

[[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

已刪除的文件的進程占用空間導致根分區爆滿