論Linux檔案系統

roc_guo發表於2023-11-28

每臺通用計算機都需要將各種資料儲存在硬碟驅動器(HDD)或其他類似裝置上,比如 USB 儲存器。這樣做有兩個原因。首先,當計算機關閉以後,記憶體(RAM)會失去存於它裡面的內容。儘管存在非易失型別的 RAM,在計算機斷電以後還能把資料儲存下來(比如採用 USB 快閃記憶體和固態硬碟的快閃記憶體),但是,快閃記憶體和標準的、易失性的 RAM,比如 DDR3 以及其他相似型別的 RAM 相比,要貴很多。

資料需要儲存在硬碟驅動上的另一個原因是,即使是標準的 RAM 也要比普通硬碟貴得多。儘管 RAM 和硬碟的價格都在迅速下降,但是 RAM 的價格依舊在以位元組為單位來計算。讓我們進行一個以位元組為單位的快速計算:基於 16 GB 大的 RAM 的價格和 2 TB 大的硬碟驅動的價格。計算顯示 RAM 的價格大約比硬碟驅動貴 71 倍。今天,一個典型的 RAM 的價格大約是 0.000000004373750 美元/每位元組。

直觀的展示一下在很久以前 RAM 的價格,在計算機發展的非常早的時期,其中一種型別的 RAM 是基於在 CRT 螢幕上的點。這種 RAM 非常昂貴,大約 1 美元/每位元組。

定義

你可能聽過其他人以各種不同和令人迷惑的方式談論過檔案系統。檔案系統這個單詞本身有多重含義,你需要從一個討論或檔案的上下文中理解它的正確含義。

我將根據我所觀察到的在不同情況下使用“檔案系統”這個詞來定義它的不同含義。注意,儘管我試圖遵循標準的“官方”含義,但是我打算基於它的不同用法來定義這個術語(如下)。這就是說我將在本文的後續章節中進行更詳細的探討。

始於頂層 root(/)目錄的整個 Linux 目錄結構。
特定型別的資料儲存格式,比如 EXT3、EXT4、BTRFS 以及 XFS 等等。Linux 支援近百種型別的檔案系統,包括一些非常老的以及一些最新的。每一種檔案系統型別都使用它自己獨特的後設資料結構來定義資料是如何儲存和訪問的。
用特定型別的檔案系統格式化後的分割槽或邏輯卷,可以掛載到 Linux 檔案系統的指定掛載點上。

檔案系統的基本功能

磁碟儲存是檔案系統必須的功能,它與之伴生的有一些有趣而且不可或缺的細節。很明顯,檔案系統是用來為非易失資料的儲存提供空間,這是它的基本功能。然而,它還有許多從需求出發的重要功能。

所有檔案系統都需要提供一個名字空間,這是一種命名和組織方法。它定義了檔案應該如何命名、檔名的最大長度,以及所有可用字符集中可用於檔名中字符集子集。它也定義了一個磁碟上資料的邏輯結構,比如使用目錄來組織檔案而不是把所有檔案聚整合一個單一的、巨大的檔案混合體。

定義名字空間以後,後設資料結構是為該名字空間提供邏輯基礎所必須的。這包括所需資料結構要能夠支援分層目錄結構,同時能夠透過結構來確定硬碟空間中的塊是已用的或可用的,支援修改檔案或目錄的名字,提供關於檔案大小、建立時間、最後訪問或修改時間等資訊,以及位置或資料所屬的檔案在磁碟空間中的位置。其他的後設資料用來儲存關於磁碟細分的資訊,比如邏輯卷和分割槽。這種更高層次的後設資料以及它所代表的結構包含描述檔案系統儲存在驅動器或分割槽中的資訊,但與檔案系統後設資料無關,與之獨立。

檔案系統也需要一個應用程式介面(API),從而提供了對檔案系統物件,比如檔案和目錄進行操作的系統功能呼叫的訪問。API 也提供了諸如建立、移動和刪除檔案的功能。它也提供了演算法來確定某些資訊,比如檔案存於檔案系統中的位置。這樣的演算法可以用來解釋諸如磁碟速度和最小化磁碟碎片等術語。

現代檔案系統還提供一個安全模型,這是一個定義檔案和目錄的訪問許可權的方案。Linux 檔案系統安全模型確保使用者只能訪問自己的檔案,而不能訪問其他使用者的檔案或作業系統本身。

最後一塊組成部分是實現這些所有功能所需要的軟體。Linux 使用兩層軟體實現的方式來提高系統和程式設計師的效率。

論Linux檔案系統論Linux檔案系統
這兩層中的第一層是 Linux 虛擬檔案系統。虛擬檔案系統提供了核心和開發者訪問所有型別檔案系統的的單一 集。虛擬檔案系統軟體透過呼叫特殊裝置驅動來和不同型別的檔案系統進行互動。特定檔案系統的裝置驅動是第二層實現。裝置驅動程式將檔案系統命令的標準集解釋為在分割槽或邏輯捲上的特定型別檔案系統命令。

目錄結構

作為一個通常來說非常有條理的處女座,我喜歡將東西儲存在更小的、有組織的小容器中,而不是存於同一個大容器中。目錄的使用使我能夠儲存檔案並在我想要檢視這些檔案的時候也能夠找到它們。目錄也被稱為資料夾,之所以被稱為資料夾,是因為其中的檔案被類比存放於物理桌面上。

在 Linux 和其他許多作業系統中,目錄可以被組織成樹狀的分層結構。在 Linux 檔案系統層次標準中定義了 Linux 的目錄結構(LCTT 譯註:可參閱這篇)。當透過目錄引用來訪問目錄時,更深層目錄名字是透過正斜槓(/)來連線,從而形成一個序列,比如 /var/log 和 /var/spool/mail 。這些被稱為路徑。

下表提供了標準的、眾所周知的、預定義的頂層 Linux 目錄及其用途的簡要清單。

目錄 描述
/ (root 檔案系統) root 檔案系統是檔案系統的目錄。它必須包含在掛載其它檔案系統前需要用來啟動 Linux 系統的全部檔案。它必須包含需要用來啟動剩餘檔案系統的全部可執行檔案和庫。檔案系統啟動以後,所有其他檔案系統作為 root 檔案系統的子目錄掛載到標準的、預定義好的掛載點上。
/bin
/bin

目錄包含使用者的可執行檔案。

/boot 包含啟動 Linux 系統所需要的靜態載入程式和核心可執行檔案以及配置檔案。
/dev 該目錄包含每一個連線到系統的硬體裝置的裝置檔案。這些檔案不是裝置驅動,而是代表計算機上的每一個計算機能夠訪問的裝置。
/etc 包含主機計算機的本地系統配置檔案。
/home 主目錄儲存使用者檔案,每一個使用者都有一個位於

/home

目錄中的子目錄(作為其主目錄)。

/lib 包含啟動系統所需要的共享庫檔案。
/media 一個掛載外部可移動裝置的地方,比如主機可能連線了一個 USB 驅動器。
/mnt 一個普通檔案系統的臨時掛載點(如不可移動的介質),當管理員對一個檔案系統進行修復或在其上工作時可以使用。
/opt 可選檔案,比如供應商提供的應用程式應該安裝在這兒。
/root 這不是 root(

/

)檔案系統。它是 root 使用者的主目錄。

/sbin 系統二進位制檔案。這些是用於系統管理的可執行檔案。
/tmp 臨時目錄。被作業系統和許多程式用來儲存臨時檔案。使用者也可能臨時在這兒儲存檔案。注意,儲存在這兒的檔案可能在任何時候在沒有通知的情況下被刪除。
/usr 該目錄裡面包含可共享的、只讀的檔案,包括可執行二進位制檔案和庫、man 檔案以及其他型別的文件。
/var 可變資料檔案儲存在這兒。這些檔案包括日誌檔案、MySQL 和其他資料庫的檔案、Web 伺服器的資料檔案、郵件以及更多。

表 1:Linux 檔案系統層次結構的頂層

這些目錄以及它們的子目錄如表 1 所示,在所有子目錄中,粗體的目錄組成了 root 檔案系統的必需部分。也就是說,它們不能建立為一個分離的檔案系統並且在開機時進行掛載。這是因為它們(特別是它們包含的內容)必須在系統啟動的時候出現,從而系統才能正確啟動。

/media 目錄和 /mnt 目錄是 root 檔案系統的一部分,但是它們從來不包含任何資料,因為它們只是一個臨時掛載點。

表 1 中剩下的非粗體的目錄不需要在系統啟動過程中出現,但會在之後掛載到 root 檔案系統上,在開機階段,它們為主機進行準備,從而執行有用的工作。

請參考官方 Linux 檔案系統層次標準(FHS)網頁來了解這些每一個目錄以及它們的子目錄的更多細節。維基百科上也有關於 FHS 的一個很好的介紹。應該儘可能的遵循這些標準,從而確保操作和功能的一致性。無論在主機上使用什麼型別的檔案系統,該層次目錄結構都是相同的。

Linux 統一目錄結構

在一些非 Linux 作業系統的個人電腦上,如果有多個物理硬碟驅動器或多個分割槽,每一個硬碟或分割槽都會分配一個驅動器號。知道檔案或程式位於哪一個硬碟驅動器上是很有必要的,比如 C: 或 D: 。然後,你可以在命令中使用驅動器號,以 D: 為例,為了進入 D: 驅動器,你可以使用 cd 命令來更改工作目錄為正確的目錄,從而定位需要的檔案。每一個硬碟驅動器都有自己單獨的、完整的目錄樹。

Linux 檔案系統將所有物理硬碟驅動器和分割槽統一為一個目錄結構。它們均從頂層 root 目錄(/)開始。所有其它目錄以及它們的子目錄均位於單一的 Linux 根目錄下。這意味著只有一棵目錄樹來搜尋檔案和程式。

因為只有一個檔案系統,所以 /home、/tmp、/var、/opt 或 /usr 能夠建立在和 root(/)檔案系統不同的物理硬碟驅動器、分割槽或邏輯分割槽上,然後掛載到一個掛載點(目錄)上,從而作為 root 檔案系統樹的一部分。甚至可移動驅動器,比如 USB 驅動器或一個外接的 USB 或 ESATA 硬碟驅動器均可以掛載到 root 檔案系統上,成為目錄樹不可或缺的部分。

當從 Linux 發行版的一個版本升級到另一個版本或從一個發行版更改到另一個發行版的時候,就會很清楚地看到這樣建立到不同分割槽的好處。通常情況下,除了任何像 Fedora 中的 dnf-upgrade 之類的升級工具,會明智地在升級過程中偶爾重新格式化包含作業系統的硬碟驅動來刪除那些長期積累的垃圾。如果 /home 目錄是 root 檔案系統的一部分(位於同一個硬碟驅動器),那麼它也會被格式化,然後需要透過之前的備份恢復。如果 /home 目錄作為一個分離的檔案系統,那麼安裝程式將會識別到,並跳過它的格式化。對於儲存資料庫、郵箱、網頁和其它可變的使用者以及系統資料的 /var 目錄也是這樣的。

將 Linux 系統目錄樹的某些部分作為一個分離的檔案系統還有一些其他原因。比如,在很久以前,我還不知道將所有需要的 Linux 目錄均作為 root(/)檔案系統的一部分可能存在的問題,於是,一些非常大的檔案填滿了 /home 目錄。因為 /home 目錄和 /tmp 目錄均不是分離的檔案系統,而是 root 檔案系統的簡單子目錄,整個 root 檔案系統就被填滿了。於是就不再有剩餘空間可以讓作業系統用來儲存臨時檔案或擴充套件已存在資料檔案。首先,應用程式開始抱怨沒有空間來儲存檔案,然後,作業系統也開始異常行動。啟動到單使用者模式,並清除了 /home 目錄中的多餘檔案之後,終於又能夠重新工作了。然後,我使用非常標準的多重檔案系統設定來重新安裝 Linux 系統,從而避免了系統崩潰的再次發生。

我曾經遇到一個情況,Linux 主機還在執行,但是卻不允許使用者透過 GUI 桌面登入。我可以透過使用虛擬控制檯之一,透過命令列介面(CLI)本地登入,然後遠端使用 SSH 。問題的原因是因為 /tmp 檔案系統滿了,因此 GUI 桌面登入時所需要的一些臨時檔案不能被建立。因為命令列介面登入不需要在 /tmp 目錄中建立檔案,所以無可用空間並不會阻止我使用命令列介面來登入。在這種情況下,/tmp 目錄是一個分離的檔案系統,在 /tmp 所位於的邏輯捲上還有大量的可用空間。我簡單地擴充套件了 /tmp 邏輯卷的容量到能夠容納主機所需要的臨時檔案,於是問題便解決了。注意,這個解決方法不需要重啟,當 /tmp 檔案系統擴大以後,使用者就可以登入到桌面了。

當我在一家很大的科技公司當實驗室管理員的時候,遇到過另外一個故障。開發者將一個應用程式安裝到了一個錯誤的位置(/var)。結果該應用程式崩潰了,因為 /var 檔案系統滿了,由於缺乏空間,儲存於 /var/log 中的日誌檔案無法附加新的日誌訊息。然而,系統仍然在執行,因為 root 檔案系統和 /tmp 檔案系統還沒有被填滿。刪除了該應用程式並重新安裝在 /opt 檔案系統後,問題便解決了。

檔案系統型別

Linux 系統支援大約 100 種分割槽型別的讀取,但是隻能對很少的一些進行建立和寫操作。但是,可以掛載不同型別的檔案系統在同一個 root 檔案系統上,並且是很常見的。在這樣的背景下,我們所說的檔案系統一詞是指在硬碟驅動器或邏輯捲上的一個分割槽中儲存和管理使用者資料所需要的結構和後設資料。能夠被 Linux 系統的 fdisk 命令識別的檔案系統型別的完整列表在此,你可以感受一下 Linux 系統對許多型別的系統的高度相容性。

Linux 支援讀取這麼多型別的分割槽系統的主要目的是為了提高相容性,從而至少能夠與一些其他計算機系統的檔案系統進行互動。下面列出了在 Fedora 中建立一個新的檔案系統時的所有可選型別:

btrfs
cramfs
ext2
ext3
ext4
fat
gfs2
hfsplus
minix
msdos
ntfs
reiserfs
vfat
xfs

其他發行版支援建立的檔案系統型別不同。比如,  6 只支援建立上表中標為黑體的檔案系統型別。

掛載

在 Linux 系統上“掛載mount”檔案系統的術語是指在計算機發展的早期,磁帶或可移動的磁碟組需要需要物理地掛載到一個合適的驅動器裝置上。當透過物理的方式放置到驅動器上以後,作業系統會邏輯地掛載位於磁碟上的檔案系統,從而作業系統、應用程式和使用者才能夠訪問檔案系統中的內容。

一個掛載點簡單的來說就是一個目錄,就像任何其它目錄一樣,是作為 root 檔案系統的一部分建立的。所以,比如,home 檔案系統是掛載在目錄 /home 下。檔案系統可以被掛載到其他非 root 檔案系統的掛載點上,但是這並不常見。

在 Linux 系統啟動階段的最初階段,root 檔案系統就會被掛載到 root 目錄下(/)。其它檔案系統在之後透過 SystemV 下的 rc 或更新一些的 Linux 發行版中的 systemd 等 Linux 啟動程式掛載。在啟動程式中檔案系統的掛載是由 /etc/fstab 配置檔案管理的。一個簡單的記憶方法是,fstab 代表“檔案系統表file system table”,它包含了需要掛載的檔案系統的列表,這些檔案系統均指定了掛載點,以及針對特定檔案系統可能需要的選項。

使用 mount 命令可以把檔案系統掛載到一個已有的目錄/掛載點上。通常情況下,任何作為掛載點的目錄都應該是空的且不包含任何其他檔案。Linux 系統不會阻止使用者掛載一個已被掛載了檔案系統的目錄或將檔案系統掛載到一個包含檔案的目錄上。如果你將檔案系統掛載到一個已有的目錄或檔案系統上,那麼其原始內容將會被隱藏,只有新掛載的檔案系統的內容是可見的。

結論

我希望透過這篇文章,闡明瞭圍繞檔案系統這個術語的一些可能的模糊之處。我花費了很長的時間,以及在一個良師的幫助下才真正理解和欣賞到 Linux 檔案系統的複雜性、優雅性和功能以及它的全部含義。

如果你有任何問題,請寫到下面的評論中,我會盡力來回答它們。

作者簡介:

David Both 居住在美國北卡羅納州的首府羅利,是一個 Linux 開源貢獻者。他已經從事 IT 行業 40 餘年,在 IBM 教授 OS/2 20 餘年。1981 年,他在 IBM 開發了第一個關於最初的 IBM 個人電腦的培訓課程。他也曾在 Red Hat 教授   課程,也曾供職於 MCI worldcom,Cico 以及北卡羅納州等。他已經為 Linux 開源社群工作近 20 年。


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

相關文章