1、介紹
阿里雲監控發來郵件通知,磁盤使用率超過90%,提示需要清理磁盤,但是明明文件已刪除:
登錄阿里雲后台查看,曲線圖也是占用了90%
如圖:
du -sh *
//查看根目錄文件大小,發現並沒有什么特大的文件
df -h
//看到dec占用了300多個G
這是系統根目錄,之前我刪除了很多日志文件,但是目前看來,空間沒有釋放
2、解決思路
一般來說不會出現刪除文件后空間不釋放的情況,但是也存在例外,比如文件被進程鎖定,或者有進程一直在向這個文件寫數據等,要理解這個問題,就需要知道Linux下文件的存儲機制和存儲結構。
一個文件在文件系統中的存放分為兩個部分:數據部分和指針部分,指針位於文件系統的meta-data中,在將數據刪除后,這個指針就從meta-data中清除了,而數據部分存儲在磁盤中。在將數據對應的指針從meta-data中清除后,文件數據部分占用的空間就可以被覆蓋並寫入新的內容,之所以在出現刪除日志文件后,空間還沒釋放,就是因為httpd進程還在一直向這個文件寫入內容,導致雖然刪除了日志文件,但是由於進程鎖定,文件對應的指針部分並未從meta-data中清除,而由於指針並未刪除,系統內核就認為文件並未刪除,因此通過df命令查詢空間並未釋放也就不足為奇了。
3、問題排查
既然有了解決問題的思路,那么接下來看看是否有進程一直在向access_log文件中寫數據,這里需要用到Linux下的lsof命令,通過這個命令可以獲取一個仍然被應用程序占用的已刪除文件列表,命令執行如下:
一般可能沒安裝這個命令,需自己yum install lsof -y
安裝(以centos為例)
lsof | grep deleted
如圖:
從輸出結果可以看到,日志文件被進程php鎖定,而php進程還一直向這個文件寫入日志數據。從第7列可知,可得知日志文件大小,由此可知,刪除的這些日志,才是最終禍首。最后一列的“deleted”狀態說明這個日志文件已經被刪除,但由於進程還在一直向此文件寫入數據,因此空間並未釋放。
4、解決問題
到這里問題就基本排查清楚了,解決這一類問題的方法有很多種,最簡單的方法是關閉或重啟php進程,當然也可以重啟操作系統,不過這些並不是最好的方法。對待這種進程不停對文件寫日志的操作,要釋放文件占用的磁盤空間,最好的方法是在線清空這個文件,具體可以通過如下命令完成:
echo " " >xx.log
通過這種方法,磁盤空間不但可以馬上釋放,也可保障進程繼續向文件寫入日志,這種方法經常用於在線清理Apache、Tomcat、Nginx等Web服務產生的日志文件。
某種情況下,不能重啟服務或者服務器,可以使用
kill -9 pid
殺死這些進程,然后再使用
df -h
查看
已經釋放了