
當我總結文件的大小時,我得到了一個數字。如果我跑du
,我會得到另一個數字。如果我du
對分區上的所有檔案運行,則它與所df
使用的聲明不符。為什麼我的檔案總大小有這麼多不同的數字?電腦不能加嗎?
說到新增:當我新增 的「已使用」和「可用」列時df
,我沒有得到總數。這個總數小於我的分割區的大小。如果我將分割區大小相加,我就不會得到磁碟大小!是什麼賦予了?
答案1
將數字相加很容易。問題是,有許多不同的數字需要相加。
一個檔案使用多少磁碟空間?
基本想法是一個包含n位元組使用n位元組的磁碟空間,加上一些控制資訊:檔案的元資料(權限、時間戳記等),以及系統需要查找檔案儲存位置的資訊的一點開銷。然而,還有很多併發症。
微觀併發症
將每個文件視為圖書館中的一系列書籍。較小的文件僅構成一卷,但較大的文件由許多卷組成,就像一本百科全書。為了能夠找到文件,有一個引用每個卷的卡片目錄。由於封面的原因,每卷都有一些開銷。如果文件很小,這個開銷就比較大。此外,卡片目錄本身也佔據了一些空間。
更技術一點,在典型的簡單檔案系統中,空間被劃分為區塊。典型的區塊大小為 4KiB。每個文件佔用整數個區塊。除非檔案大小是區塊大小的倍數,否則僅部分使用最後一個區塊。因此,1 位元組檔案和 4096 位元組檔案均佔用 1 個區塊,而 4097 位元組檔案則佔用 2 個區塊。您可以使用ls
或來觀察這一點du
:如果您的檔案系統具有 4KiB 區塊大小,則ls -s
和du
將報告 1 位元組檔案為 4KiB。
如果檔案很大,則需要額外的區塊來儲存組成檔案的區塊清單(這些是間接區塊;更複雜的檔案系統可以透過以下形式對此進行最佳化範圍)。這些不會顯示在ls -l
GNU 或 GNU報告的檔案大小中du --apparent-size
。du
和ls -s
報告磁碟使用情況而不是大小,確實說明了這些問題。
一些檔案系統嘗試重複使用最後一個區塊中剩餘的可用空間將多個文件尾部打包在同一個區塊中。一些檔案系統(例如Linux 3.8 以後的 ext4對於完全適合 inode 的小檔案(只有幾個位元組)使用 0 塊。
宏觀併發症
一般來說,如上所示,報告的總大小du
是檔案使用的區塊或磁碟區大小的總和。
du
如果檔案被壓縮,則報告的大小可能會更小。 Unix 系統傳統上支援粗略形式的壓縮:如果檔案區塊僅包含空字節,則檔案系統可以完全忽略該區塊,而不是儲存零區塊。像這樣省略區塊的檔案稱為稀疏文件。當文件包含大量空字節時,不會自動建立稀疏文件,應用程式必須安排文件變得稀疏。
晚期併發症
zfs 和 btrfs 等非常現代的檔案系統的兩個主要功能使檔案大小和磁碟使用之間的關係變得更加遙遠:快照和重複資料刪除。
快照是檔案系統在特定日期的凍結狀態。支援此功能的檔案系統可以包含在不同日期拍攝的多個快照。當然,這些快照會佔用空間。一個極端情況是,如果您從文件系統的活動版本中刪除所有文件,如果還有剩餘快照,文件系統不會變空。
自拍攝快照以來或在拍攝兩個快照之間未更改的任何文件或區塊在快照和活動版本或其他快照中完全相同地存在。這是透過以下方式實現的寫時複製。在某些極端情況下,由於可用空間不足,刪除整個檔案系統上的檔案可能會失敗 - 因為刪除該檔案需要在目錄中複製一個區塊,而即使是那個區塊也沒有更多空間。
重複資料刪除是一種儲存最佳化技術,包括避免儲存相同的區塊。對於典型數據,尋找重複項並不總是值得付出努力。兩個都茲夫斯和BTFS支援重複資料刪除作為選用功能。
為什麼總大小du
與檔案大小的總和不同?
正如我們在上面看到的,每個文件報告的大小du
通常是文件使用的區塊或範圍的大小總和。請注意,預設情況下,ls -l
以位元組為單位列出大小,但du
在一些更傳統的系統上以 KiB 或 512 位元組單位(扇區)列出大小(du -k
強制使用千位元組)。大多數現代 unices 支援ls -lh
並du -h
使用「人類可讀」的數字,使用 K、M、G 等就足夠了(對於 KiB、MiB、GiB)。
當您du
在目錄上執行時,它會匯總目錄樹中所有檔案的磁碟使用情況,包括目錄他們自己。目錄包含資料(檔案的名稱以及指向檔案元資料所在位置的指標),因此它需要一些儲存空間。小目錄將佔用一個區塊,較大的目錄將需要更多區塊。目錄使用的存儲量有時不僅取決於它包含的文件,還取決於它們插入的順序以及刪除某些文件的順序(對於某些文件系統,這可能會留下漏洞- 磁碟空間和性能之間的折衷) ),但差異很小(到處都是額外的塊)。當您執行時ls -ld /some/directory
,會列出目錄的大小。 (請注意,輸出頂部的「total NNN」行ls -l
是一個不相關的數字,它是列出的項目的區塊大小的總和,以 KiB 或扇區表示。)
請記住,其中du
包括點文件ls
除非您使用-A
or選項,否則不會顯示-a
。
有時du
報告的金額少於預期金額。如果有的話就會發生這種情況硬連結在目錄樹內部:du
每個檔案只計數一次。使用du -l
switch 來統計檔案數量氮次如果他們有氮硬連結。
在某些檔案系統(例如ZFS
Linux)上,du
不報告檔案的擴充屬性所佔用的完整磁碟空間。
請注意,如果目錄下有掛載點,du
除非給予選項,否則也會計算這些掛載點上的所有檔案-x
。因此,如果您想要根檔案系統中檔案的總大小,請運行du -x /
,而不是du /
。
如果檔案系統安裝到非空目錄,該目錄中的檔案被安裝的檔案系統隱藏。他們仍然佔據著自己的空間,但du
找不到他們。
已刪除的文件
當一個文件是已刪除,這僅刪除目錄條目,不一定刪除檔案本身。要真正刪除檔案並回收其磁碟空間,需要滿足兩個條件:
- 文件的連結計數必須降至 0:如果文件有多個硬鏈接,刪除一個不會影響其他文件。
- 只要檔案被某個進程打開,資料就會保留。只有當所有進程都關閉該檔案時,該檔案才會被刪除。輸出
fuser -m
或者lsof
掛載點上包含在該檔案系統上開啟檔案的進程,即使該檔案已被刪除。 - 即使沒有進程開啟已刪除的文件,如果該文件是裝置的後端,也可能無法回收該文件的空間
loop
。losetup -a
(如root
)可以告訴您loop
目前設定了哪些設備以及在什麼文件上。losetup -d
在回收磁碟空間之前,必須銷毀循環設備(使用)。
如果您在某些文件管理器或 GUI 環境中刪除文件,它可能會被放入垃圾區域,並且可以在其中恢復刪除。只要檔案可以恢復,它的空間仍然會被消耗。
這些數字df
到底來自哪裡?
典型的檔案系統包含:
只報道了第一種du
。當涉及到時df
,「已使用」、「可用」和總列中的內容取決於檔案系統(當然,已使用的區塊(包括間接區塊)始終位於「已使用」列中,未使用的區塊始終位於“可用”欄)。
ext2/ext3/ext4 中的檔案系統預訂5%的空間給root使用者。這對於根檔案系統很有用,可以在系統已滿時保持系統繼續運作(特別是對於日誌記錄,並讓系統管理員在解決問題時儲存一些資料)。即使對於諸如 之類的資料分割區/home
,保留保留空間也是有用的,因為幾乎已滿的檔案系統很容易產生碎片。 Linux 試圖透過在寫入檔案時預先分配許多連續區塊來避免碎片(這會減慢檔案存取速度,尤其是在硬碟等旋轉機械裝置上),但如果連續區塊不多,那就無法運作。
傳統檔案系統(包括 ext4 但不包括 btrfs)保留固定數量的檔案系統索引節點建立檔案系統時。這顯著簡化了檔案系統的設計,但缺點是需要適當調整 inode 的數量:inode 太多,會浪費空間;如果 inode 太少,檔案系統可能會在空間耗盡之前耗盡 inode。該命令df -i
報告有多少 inode 正在使用中以及有多少 inode 可用(該概念不適用的檔案系統可能會報告 0)。
在包含 ext2/ext3/ext4 檔案系統的磁碟區上運行tune2fs -l
會報告一些統計信息,包括總數以及空閒 inode 和區塊的數量。
另一個可能混淆物質的特徵是子卷(支持於BTFS,並在 zfs 中的名稱下數據集)。多個子卷共享相同的空間,但具有單獨的目錄樹根。
如果檔案系統透過網路(NFS、Samba 等)安裝,並且伺服器會匯出該檔案系統的一部分(例如伺服器有一個/home
檔案系統,並導出/home/bob
),然後df
在客戶端上反映整個檔案系統的數據,而不僅僅是匯出並安裝在客戶端上的部分的數據。
我的磁碟空間被用來做什麼?
正如我們在上面看到的,報告的總大小df
並不總是考慮檔案系統的所有控制資料。如果需要,請使用特定於檔案系統的工具來取得檔案系統的確切大小。例如,對於 ext2/ext3/ext4,運行tune2fs -l
並將區塊大小乘以區塊計數。
建立檔案系統時,它通常會填滿封閉分割區或磁碟區上的可用空間。有時,當您移動檔案系統或調整磁碟區大小時,您最終可能會得到較小的檔案系統。
在 Linux 上,lsblk
提供了可用儲存卷的良好概述。如需更多信息,或者如果您沒有lsblk
,請使用專門的捲管理或分區工具來檢查您擁有哪些分區。在 Linux 上,有lvs
, vgs
,pvs
代表左心室容量,fdisk
對於傳統的 PC 風格(“MBR”)分區(以及最新系統上的 GPT),gdisk
為了GPT分區,disklabel
對於 BSD 磁碟標籤,分手了等Linux下,cat /proc/partitions
簡單總結一下。典型的安裝至少有兩個作業系統使用的分割區或磁碟區:一個檔案系統(有時更多)和一個交換體積。
有些計算機有一個分割區,其中包含BIOS或其他診斷軟體。計算機具有UEFI有一個專用的引導程式分區。
最後,請注意,大多數電腦程式使用基於 1024 = 2 10的冪的單位(因為程式設計師喜歡二進位和 2 的冪)。所以 1 kB = 1024 B,1 MB = 1048576 B,1 GB = 1073741824,1 TB = 1099511627776 B,......正式地,這些單位被稱為千位元組基布,兆比位元組MiB等,但大多數軟體僅報告k或kB、M或MB等。因此,1 TB 硬碟僅為 931 GiB 或 0.904 TiB。
答案2
計算檔案大小和磁碟空間的複雜性的簡短摘要:
檔案在磁碟上所佔用的空間是它所佔用的區塊數乘以每個區塊的大小+它所佔用的索引節點數。一個 1 個位元組長的檔案至少需要 1 個區塊、1 個 inode 和 1 個目錄項目。
但如果該文件是到另一個文件的硬鏈接,則可能只需要 1 個額外的目錄條目。這只是對同一組區塊的另一個引用。
- 文件內容的大小。這就是
ls
顯示的內容。 - 可用磁碟空間不是您可以容納的最大檔案的大小,也不是磁碟上適合的所有檔案內容大小的總和。它介於兩者之間。它取決於檔案數量(佔用索引節點)、區塊大小以及每個檔案的內容完全填充區塊的程度。
這只是檔案系統的皮毛,而且過於簡化了。還要記住,不同的檔案系統的操作方式不同。
stat
對於發現其中一些資訊非常有幫助。以下是如何使用 stat 及其用途的一些範例:http://landoflinux.com/linux_stat_command_examples.html
答案3
df
通常用於查看檔案系統是什麼、每個檔案系統有多滿以及它們安裝在哪裡。當您的檔案系統空間不足,並且可能想要在檔案系統之間轉移內容或購買更大的磁碟等時,這非常有用。
du
顯示每個目錄消耗的累積儲存量的詳細資訊(有點像windirstat
Windows 中)。非常適合在嘗試進行文件清理時尋找佔用空間的位置。
除了其他人解釋的微小數字差異外,我認為du
和df
實用程式的目的非常不同。
答案4
du
我將在這裡說明導致與 不同的不同情況df
。
df
計算檔案系統分配的區塊數,du
使用每個檔案的大小資訊。差異可能有多種原因:
應用程式仍開啟的未連結(已刪除)的檔案。文件資訊遺失,區塊仍然分配。
lsof +aL1 <filesystem>
將幫助您識別流程。大多數時候,您必須終止進程以釋放空間(這取決於進程,有時重新載入配置就足夠了)。掛載點下的檔案隱藏到
du
但不隱藏到df
。debugfs
可以幫助你讀取檔案系統。$ sudo debugfs debugfs 1.42.12 (29-Aug-2014) debugfs: open /dev/xxx (the desired file system device) debugfs: cd /boot debugfs: ls -l 1966081 40755 (2) 0 0 4096 26-May-2016 16:28 . 2 40555 (2) 0 0 4096 11-May-2016 10:43 .. 1974291 100644 (1) 0 0 0 26-May-2016 16:28 bob <---<<< /boot/bob is hidden by /boot fs
稀疏文件看起來比實際更大。未分配的區塊不計入,
df
但表觀檔案大小計入du
。
請注意,硬連結不會欺騙du
。