Linux系統刪除文件后空間並沒有釋放的處理


 

一、現象描述

       操作系統:CentOS 6.8 x64

       使用 df -h 命令,看見 / 根目錄下磁盤空間已滿(100%),於是手動清理大日志文件。

[root@local ~]# df -h
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/rootvg-LogVol00    59G   59G     0 100% /
/dev/sda1                     190M   13M  168M   8% /boot
tmpfs                         2.0G     0  2.0G   0% /dev/shm

       通過 du -sh 命令,找到占用大量空間的日志文件,於是使用 rm -rf  刪除了它。

[root@local ~]# cd /var/nginx/logs/
[root@local ~]# rm -rf t-access.log t-error.log

      然后 查看磁盤空間的使用情況,發現 / (根目錄)的空間並沒有發生變化。但是可以看到 Used 發生了變化。

[root@local ~]# df -h
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/rootvg-LogVol00    59G   56G     0 100% /
/dev/sda1                     190M   13M  168M   8% /boot
tmpfs                         2.0G     0  2.0G   0% /dev/shm

       這是怎么回事呢?

 

二、原因

       未釋放磁盤空間的原因:

        在Linux或者Unix系統中,通過rm或者文件管理器刪除文件將會從文件系統的文件夾結構上解除鏈接(unlink),然而假設文件是被打開的(有一個進程正在使用),那么進程將仍然能夠讀取該文件,磁盤空間也一直被占用。而我刪除的是nginx的訪問日志文件,在刪除的時候該文件正在被使用。 

 

三、解決辦法

       首先獲得一個已經被刪除的可是仍然被應用程序占用的文件列表。操作如下:

[root@local ~]# lsof |grep deleted
nginx      4399      root   38w      REG              253,0   19304448   10835682 /var/nginx/logs/t-access.log (deleted)
nginx      4399      root   39w      REG              253,0    3502080   10835684 /var/nginx/logs/t-error.log (deleted)
nginx      4401    nobody   38w      REG              253,0   19304448   10835682 /var/nginx/logs/t-access.log (deleted)
nginx      4401    nobody   39w      REG              253,0    3502080   10835684 /var/nginx/logs/t-error.log (deleted)
nginx      4402    nobody   38w      REG              253,0   19304448   10835682 /var/nginx/logs/t-access.log (deleted)
nginx      4402    nobody   39w      REG              253,0    3502080   10835684 /var/nginx/logs/t-error.log (deleted)
nginx      4403    nobody   38w      REG              253,0   19304448   10835682 /var/nginx/logs/t-access.log (deleted)
nginx      4403    nobody   39w      REG              253,0    3502080   10835684 /var/nginx/logs/t-error.log (deleted)
nginx      4404    nobody   38w      REG              253,0   19304448   10835682 /var/nginx/logs/t-access.log (deleted)
nginx      4404    nobody   39w      REG              253,0    3502080   10835684 /var/nginx/logs/t-error.log (deleted)

       從輸出的結果可以看到 /var/nginx/logs/t-access.log 和 t-error.log 還在被使用中,所以導致未釋放空間。

 

       那么如何讓進程釋放呢?

方法1:直接 kill 掉相應的進程,或者停掉使用這個文件的應用,讓操作系統自己主動回收磁盤空間。

       由於還有其他項目正在使用該應用(nginx服務),所以不能停掉nginx服務,於是使用 kill 命令刪除相應的進程。

[root@local ~]# kill -9 4399
[root@local ~]# kill -9 4401
[root@local ~]# kill -9 4402
[root@local ~]# kill -9 4403
[root@local ~]# kill -9 4404

       再次,查看磁盤空間的使用情況,發現空間已經被回收了。

[root@local ~]# df -h
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/rootvg-LogVol00    59G   56G     0  95% /
/dev/sda1                     190M   13M  168M   8% /boot
tmpfs                         2.0G     0  2.0G   0% /dev/shm

 

方法2:以后清理正在被讀寫的大日志文件時,直接使用 echo "" > xxx.log 命令,即直接將文件置空,並不影響服務的使用,文件大小也被控制下來,磁盤空間也釋放了。

 

說明:

       當Linux打開一個文件的時候,Linux內核會為每個進程在/proc/ 『/proc/nnnn/fd/文件夾(nnnn為pid)』建立一個以其pid為名的文件夾用來保存進程的相關信息,而其子文件夾fd保存的是該進程打開的全部文件的fd(fd:file descriptor)。

       kill進程是通過截斷proc文件系統中的文件能夠強制要求系統回收分配給正在使用的的文件。這是一項高級技術,僅到管理員確定不會對執行中的進程造成影響時使用。應用程序對這樣的方式支持的並不好,當一個正在使用的文件被截斷可能會引發不可預知的問題。

 

四、刪除原理  

       一般來說,不會出現刪除文件后空間不釋放的情況,但是也存在例外,比如文件被進程鎖定,或者有進程在使用這個文件,例如輸出日志文件,要了解這個問題,就需要知道Linux下文件的存儲機制和存儲結構。

       一個文件在文件系統中由兩個部分構成:數據和指針。指針位於文件系統的meta-data中,數據被刪除后,指針被清除,而數部分還是存儲在磁盤中,只不過數據對應的指針被清除后,文件數據部分占用的空間就可以被覆蓋了。之所以出現刪除大文件后,空間還沒有釋放,就是因為有進程一直在使用這個文件的指針,日志文件的服務還在運行,導致雖然刪除了日志大文件,但文件對應的指針部分由於被進程鎖定,並未從meta-data中清除,而由於指針並未被刪除,那么系統就認為文件並未被刪除,所以使用 df 命令查看還是 100%。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM