linux下du和df結果不一致的原因及處理

巡完南山巡南山發表於2019-01-19

本實驗結果是在RHEL6.4-64bit下得出

1. 原理介紹

1 .1du 的工作原理

du 命令會對待統計檔案逐個呼叫fstat這個系統呼叫,獲取檔案大小。它的資料是基於檔案獲取的,所以有很大的靈活性,不一定非要針對一個分割槽,可以跨越多個分割槽操作。如果針對的目錄中檔案很多,du速度就會很慢了。

1.2 df 的工作原理

df 命令使用的事statfs這個系統呼叫,直接讀取分割槽的超級塊資訊獲取分割槽使用情況。它的資料是基於分割槽後設資料的,所以只能針對整個分割槽。由於df直接讀取超級塊,所以執行速度不受檔案多少影響。

2. 實驗模擬

常見的df和du不一致情況就是檔案被刪除的而程式控制程式碼還在導致的問題。當一個檔案被刪除後,在檔案系統目錄中已經不可見了,所以du就不會再統計它了。然而如果此時還有執行的程式持有這個已經被刪除了的檔案的控制程式碼,那麼這個檔案就不會真正在磁碟中被刪除,分割槽超級塊中的資訊也就不會更改,這樣df仍舊會統計這個被刪除了的檔案。

首先檢視磁碟和路徑

[root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   42G   201G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

[root@zhjk115 app]#

[root@zhjk115 app]# pwd

/app

dd 命令建立 1G 大學的檔案

[root@zhjk115 app]# dd if=/dev/zero of=/app/test.iso bs=1024k count=1000

1000+0 records in

1000+0 records out

1048576000 bytes (1.0 GB) copied, 4.31891 s, 243 MB/s

檢視 df du 結果,目前是一致的

[root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   43G   200G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

[root@zhjk115 app]# du -sh

43G

模擬程式在使用 test.iso 檔案

[root@zhjk115 app]# tail -f test.iso &

[1] 22349

[root@zhjk115 app]# ps -ef |grep tail

root     22349 21633 28 09:56 pts/1    00:00:01 tail -f test.iso

root     22353 21633  0 09:56 pts/1    00:00:00 grep tail

刪除 test.iso 檔案, 可以看出 df du 的結果是不一致的

[root@zhjk115 app]# rm -rf test.iso

 [root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   43G   200G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

 [root@zhjk115 app]# du -sh

42G

lsof 檢視哪個程式在使用 /app/test.iso

[root@zhjk115 app]# lsof |grep test.iso

tail   22349   root    3r   REG   253,2 1048576000  12 /app/test.iso

手動 kill 佔有 test.iso 檔案的程式,此時, du df 的結果一致

[root@zhjk115 app]# kill -9 22349

[1]+  Killed                  tail -f test.iso

[root@zhjk115 app]# du -sh

42G 

[root@zhjk115 app]# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/mapper/VolGroup-lv_root

                       45G  8.0G   35G  19% /

tmpfs                 4.0G  1.5G  2.5G  37% /dev/shm

/dev/mapper/VolGroup-lv_app

                      255G   42G   201G  18% /app

/dev/sda1             485M   38M  422M   9% /boot

   

結論:

本實驗主要是針對Linux環境的使用,該問題是由於程式的檔案控制程式碼釋放問題導致的,很多情況為清理完日誌等檔案是du顯示為已釋放空間,但df空間還在使用,此時可以透過echo(或者>)代替rm來避免這種情況,同時也可以檢視是哪個程式在使用,可以根據情況手動清理、重啟應用或者等待釋放。


注:當oracle主機某些日誌被清理後但df顯示空間沒有被釋放也是同樣的道理,一般來說等一段時間即可,否則需要重啟資料庫例項來釋放空間。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26964624/viewspace-2564207/,如需轉載,請註明出處,否則將追究法律責任。

相關文章