Linux中刪除文件,磁盤空間未釋放問題追蹤


    在客戶使用我們產品后,發現一個問題:在刪除了文件后。磁盤空間卻沒有釋放。是有進程在打開這個文件,還是其它情況?我們一起來看看一下兩個場景


一. 場景一:進程打開此文件

    當一個文件正在被一個進程使用時。用戶刪除此文件,文件僅僅會從文件夾結構中刪除,但並沒有從磁盤刪除。當使用這個文件的進程結束后,文件才會真正的從磁盤刪除,釋放占有的空間。

    我們發現剩余磁盤空間比較少時,回去刪除一些大的暫時文件或者log文件。假設刪除之后會發現磁盤空間並未降低。那么能夠通過“lsof”命令去查看正在使用該文件的進程。然后再重新啟動該進程或者服務。

    【樣例】

    如今發現磁盤空間的占用了99%。剩余空間僅僅剩下522M。

SUSE11X64-001:/test # df -h
Filesystem                       Size  Used Avail Use% Mounted on
/dev/sda2                         29G   27G  522M  99% /
devtmpfs                         972M  116K  972M   1% /dev
tmpfs                            972M     0  972M   0% /dev/shm

     找到一個文件"vmcore"占用了接近900M空間。但這個文件不須要再使用了,於是採用“rm”命令刪除此文件,但是刪除后,發現磁盤空間並沒有真正的降低。

SUSE11X64-001:/test # rm vmcore 
SUSE11X64-001:/test # df -h
Filesystem                       Size  Used Avail Use% Mounted on
/dev/sda2                         29G   27G  522M  99% /
devtmpfs                         972M  116K  972M   1% /dev
tmpfs                            972M     0  972M   0% /dev/shm
//10.204.16.2/home/splx/iceking  6.3T  1.6T  4.7T  25% /mnt/iceking
    也就是說非常有可能有其它進程正在使用這個文件,使用“ lsof”命令去查看正在使用該文件的進程。
SUSE11X64-001:/test # lsof | grep vmcore
a.out      2610       root    3r      REG                8,2 941331144    1643779 /test/vmcore (deleted)
    進程號為 2610(進程名為" a.out")的進程,正在使用vmcore文件。也能夠看到其后有“ deleted”:其表示正在使用的文件被刪除,但並沒有真正從磁盤上移除。

    如今我們刪除這個進程,並查看磁盤空間此時占用率減少為95%。剩余空間添加到1.4G。

SUSE11X64-001:/test # df -h
Filesystem                       Size  Used Avail Use% Mounted on
/dev/sda2                         29G   26G  1.4G  95% /
devtmpfs                         972M  116K  972M   1% /dev
tmpfs                            972M     0  972M   0% /dev/shm

二. 場景二:內核模塊Bug

    在文件系統處理文件須要的信息都存放在索引節點(inode)中,假設在刪除文件的時候索引節點的引用計數不為0(表示文件正在被使用),則不會在磁盤中真正的刪除文件。從而保證正在使用此文件的進程可以正常的處理文件。

    首先我們一起來看一下內核中關於文件系統的一些重要數據結構的關聯。當一個進程打開一個文件后,便會在內核中創建一個file對象,這個對象主要描寫敘述了進程怎樣與文件進行交互。file對象中將指向一個dentry結構(文件夾項)。文件夾項中描寫敘述了文件夾項名稱,父文件夾項信息,子文件夾項信息等。而dentry中的d_inode所指向的inode節點中則包括了實際的文件存儲在磁盤上的信息。


    當多個進程打開同一個文件時,內核中變會創建對應的file對象,可是他們都公用同一個dentry,僅僅只是每一次打開文件dentry的引用計數d_count加1。

而且對於打開的同一個文件而言,inode也是唯一的。inode的引用計數i_count一般為文件硬鏈接的數目。

看過一些中文博客,說“同一個文件。每打開一次,則inode中引用計數i_count則加1”。這樣的說法通過我的驗證結果是錯誤的。實驗結果是:對於同一個文件。每打開一次,則inode中的引用計數不變,但對應的dentry引用計數加1.

    這次客戶在刪除文件后。磁盤空間沒有釋放,通過"lsof"命令也沒有找到正在占用此文件的進程。於是再次懷疑這是因為產品的內核模塊早成的。后經分析得到:在上一篇博文《Linux Kernel模塊內存泄露查找 (2)》中解釋過因為在產品內核模塊中,對dentry引用,並使用完之后並沒有對其引用計數減1。從而造成內存泄露。

在這樣的情況下。dentry不會被釋放。則inode也就一直被引用着,從而也導致了即使刪除文件,也不會從磁盤刪除。

    並且針對以上的問題和分析,假設不能及時給客戶修這個問題,那也僅僅能讓其又一次啟動OS,空暇的磁盤空間才會釋放出來。



免責聲明!

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



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