?導(dǎo)讀本文旨在高屋建瓴地來討論?Linux?文件系統(tǒng)概念,而不是對某種特定的文件系統(tǒng),比如 EXT4 是如何工作的進(jìn)行具體的描述。另外,本文也不是一個(gè)文件系統(tǒng)命令的教程。
每臺(tái)通用計(jì)算機(jī)都需要將各種數(shù)據(jù)存儲(chǔ)在硬盤驅(qū)動(dòng)器(HDD)或其他類似設(shè)備上,比如 USB 存儲(chǔ)器。這樣做有兩個(gè)原因。首先,當(dāng)計(jì)算機(jī)關(guān)閉以后,內(nèi)存(RAM)會(huì)失去存于它里面的內(nèi)容。盡管存在非易失類型的 RAM,在計(jì)算機(jī)斷電以后還能把數(shù)據(jù)存儲(chǔ)下來(比如采用 USB 閃存和固態(tài)硬盤的閃存),但是,閃存和標(biāo)準(zhǔn)的、易失性的 RAM,比如 DDR3 以及其他相似類型的 RAM 相比,要貴很多。
數(shù)據(jù)需要存儲(chǔ)在硬盤驅(qū)動(dòng)上的另一個(gè)原因是,即使是標(biāo)準(zhǔn)的 RAM 也要比普通硬盤貴得多。盡管 RAM 和硬盤的價(jià)格都在迅速下降,但是 RAM 的價(jià)格依舊在以字節(jié)為單位來計(jì)算。讓我們進(jìn)行一個(gè)以字節(jié)為單位的快速計(jì)算:基于 16 GB 大的 RAM 的價(jià)格和 2 TB 大的硬盤驅(qū)動(dòng)的價(jià)格。計(jì)算顯示 RAM 的價(jià)格大約比硬盤驅(qū)動(dòng)貴 71 倍。今天,一個(gè)典型的 RAM 的價(jià)格大約是 0.000000004373750 美元/每字節(jié)。
直觀的展示一下在很久以前 RAM 的價(jià)格,在計(jì)算機(jī)發(fā)展的非常早的時(shí)期,其中一種類型的 RAM 是基于在 CRT 屏幕上的點(diǎn)。這種 RAM 非常昂貴,大約 1 美元/每字節(jié)。
定義
你可能聽過其他人以各種不同和令人迷惑的方式談?wù)撨^文件系統(tǒng)。文件系統(tǒng)這個(gè)單詞本身有多重含義,你需要從一個(gè)討論或文件的上下文中理解它的正確含義。
我將根據(jù)我所觀察到的在不同情況下使用“文件系統(tǒng)”這個(gè)詞來定義它的不同含義。注意,盡管我試圖遵循標(biāo)準(zhǔn)的“官方”含義,但是我打算基于它的不同用法來定義這個(gè)術(shù)語(如下)。這就是說我將在本文的后續(xù)章節(jié)中進(jìn)行更詳細(xì)的探討。
始于頂層 root(/)目錄的整個(gè) Linux 目錄結(jié)構(gòu)。
特定類型的數(shù)據(jù)存儲(chǔ)格式,比如 EXT3、EXT4、BTRFS 以及 XFS 等等。Linux 支持近百種類型的文件系統(tǒng),包括一些非常老的以及一些最新的。每一種文件系統(tǒng)類型都使用它自己獨(dú)特的元數(shù)據(jù)結(jié)構(gòu)來定義數(shù)據(jù)是如何存儲(chǔ)和訪問的。
用特定類型的文件系統(tǒng)格式化后的分區(qū)或邏輯卷,可以掛載到 Linux 文件系統(tǒng)的指定掛載點(diǎn)上。
文件系統(tǒng)的基本功能
磁盤存儲(chǔ)是文件系統(tǒng)必須的功能,它與之伴生的有一些有趣而且不可或缺的細(xì)節(jié)。很明顯,文件系統(tǒng)是用來為非易失數(shù)據(jù)的存儲(chǔ)提供空間,這是它的基本功能。然而,它還有許多從需求出發(fā)的重要功能。
所有文件系統(tǒng)都需要提供一個(gè)名字空間,這是一種命名和組織方法。它定義了文件應(yīng)該如何命名、文件名的最大長度,以及所有可用字符集中可用于文件名中字符集子集。它也定義了一個(gè)磁盤上數(shù)據(jù)的邏輯結(jié)構(gòu),比如使用目錄來組織文件而不是把所有文件聚集成一個(gè)單一的、巨大的文件混合體。
定義名字空間以后,元數(shù)據(jù)結(jié)構(gòu)是為該名字空間提供邏輯基礎(chǔ)所必須的。這包括所需數(shù)據(jù)結(jié)構(gòu)要能夠支持分層目錄結(jié)構(gòu),同時(shí)能夠通過結(jié)構(gòu)來確定硬盤空間中的塊是已用的或可用的,支持修改文件或目錄的名字,提供關(guān)于文件大小、創(chuàng)建時(shí)間、最后訪問或修改時(shí)間等信息,以及位置或數(shù)據(jù)所屬的文件在磁盤空間中的位置。其他的元數(shù)據(jù)用來存儲(chǔ)關(guān)于磁盤細(xì)分的高級信息,比如邏輯卷和分區(qū)。這種更高層次的元數(shù)據(jù)以及它所代表的結(jié)構(gòu)包含描述文件系統(tǒng)存儲(chǔ)在驅(qū)動(dòng)器或分區(qū)中的信息,但與文件系統(tǒng)元數(shù)據(jù)無關(guān),與之獨(dú)立。
文件系統(tǒng)也需要一個(gè)應(yīng)用程序接口(API),從而提供了對文件系統(tǒng)對象,比如文件和目錄進(jìn)行操作的系統(tǒng)功能調(diào)用的訪問。API 也提供了諸如創(chuàng)建、移動(dòng)和刪除文件的功能。它也提供了算法來確定某些信息,比如文件存于文件系統(tǒng)中的位置。這樣的算法可以用來解釋諸如磁盤速度和最小化磁盤碎片等術(shù)語。
現(xiàn)代文件系統(tǒng)還提供一個(gè)安全模型,這是一個(gè)定義文件和目錄的訪問權(quán)限的方案。Linux 文件系統(tǒng)安全模型確保用戶只能訪問自己的文件,而不能訪問其他用戶的文件或操作系統(tǒng)本身。
最后一塊組成部分是實(shí)現(xiàn)這些所有功能所需要的軟件。Linux 使用兩層軟件實(shí)現(xiàn)的方式來提高系統(tǒng)和程序員的效率。
這兩層中的第一層是 Linux 虛擬文件系統(tǒng)。虛擬文件系統(tǒng)提供了內(nèi)核和開發(fā)者訪問所有類型文件系統(tǒng)的的單一命令集。虛擬文件系統(tǒng)軟件通過調(diào)用特殊設(shè)備驅(qū)動(dòng)來和不同類型的文件系統(tǒng)進(jìn)行交互。特定文件系統(tǒng)的設(shè)備驅(qū)動(dòng)是第二層實(shí)現(xiàn)。設(shè)備驅(qū)動(dòng)程序?qū)⑽募到y(tǒng)命令的標(biāo)準(zhǔn)集解釋為在分區(qū)或邏輯卷上的特定類型文件系統(tǒng)命令。
目錄結(jié)構(gòu)
作為一個(gè)通常來說非常有條理的處女座,我喜歡將東西存儲(chǔ)在更小的、有組織的小容器中,而不是存于同一個(gè)大容器中。目錄的使用使我能夠存儲(chǔ)文件并在我想要查看這些文件的時(shí)候也能夠找到它們。目錄也被稱為文件夾,之所以被稱為文件夾,是因?yàn)槠渲械奈募活惐却娣庞谖锢碜烂嫔稀?/p>
在 Linux 和其他許多操作系統(tǒng)中,目錄可以被組織成樹狀的分層結(jié)構(gòu)。在 Linux 文件系統(tǒng)層次標(biāo)準(zhǔn)中定義了 Linux 的目錄結(jié)構(gòu)(LCTT 譯注:可參閱這篇)。當(dāng)通過目錄引用來訪問目錄時(shí),更深層目錄名字是通過正斜杠(/)來連接,從而形成一個(gè)序列,比如 /var/log 和 /var/spool/mail 。這些被稱為路徑。
下表提供了標(biāo)準(zhǔn)的、眾所周知的、預(yù)定義的頂層 Linux 目錄及其用途的簡要清單。
目錄描述/ (root 文件系統(tǒng))root 文件系統(tǒng)是文件系統(tǒng)的頂級目錄。它必須包含在掛載其它文件系統(tǒng)前需要用來啟動(dòng) Linux 系統(tǒng)的全部文件。它必須包含需要用來啟動(dòng)剩余文件系統(tǒng)的全部可執(zhí)行文件和庫。文件系統(tǒng)啟動(dòng)以后,所有其他文件系統(tǒng)作為 root 文件系統(tǒng)的子目錄掛載到標(biāo)準(zhǔn)的、預(yù)定義好的掛載點(diǎn)上。/bin
/bin
目錄包含用戶的可執(zhí)行文件。
/boot包含啟動(dòng) Linux 系統(tǒng)所需要的靜態(tài)引導(dǎo)程序和內(nèi)核可執(zhí)行文件以及配置文件。/dev該目錄包含每一個(gè)連接到系統(tǒng)的硬件設(shè)備的設(shè)備文件。這些文件不是設(shè)備驅(qū)動(dòng),而是代表計(jì)算機(jī)上的每一個(gè)計(jì)算機(jī)能夠訪問的設(shè)備。/etc包含主機(jī)計(jì)算機(jī)的本地系統(tǒng)配置文件。/home主目錄存儲(chǔ)用戶文件,每一個(gè)用戶都有一個(gè)位于
/home
目錄中的子目錄(作為其主目錄)。
/lib包含啟動(dòng)系統(tǒng)所需要的共享庫文件。/media一個(gè)掛載外部可移動(dòng)設(shè)備的地方,比如主機(jī)可能連接了一個(gè) USB 驅(qū)動(dòng)器。/mnt一個(gè)普通文件系統(tǒng)的臨時(shí)掛載點(diǎn)(如不可移動(dòng)的介質(zhì)),當(dāng)管理員對一個(gè)文件系統(tǒng)進(jìn)行修復(fù)或在其上工作時(shí)可以使用。/opt可選文件,比如供應(yīng)商提供的應(yīng)用程序應(yīng)該安裝在這兒。/root這不是 root(
/
)文件系統(tǒng)。它是 root 用戶的主目錄。
/sbin系統(tǒng)二進(jìn)制文件。這些是用于系統(tǒng)管理的可執(zhí)行文件。/tmp臨時(shí)目錄。被操作系統(tǒng)和許多程序用來存儲(chǔ)臨時(shí)文件。用戶也可能臨時(shí)在這兒存儲(chǔ)文件。注意,存儲(chǔ)在這兒的文件可能在任何時(shí)候在沒有通知的情況下被刪除。/usr該目錄里面包含可共享的、只讀的文件,包括可執(zhí)行二進(jìn)制文件和庫、man 文件以及其他類型的文檔。/var可變數(shù)據(jù)文件存儲(chǔ)在這兒。這些文件包括日志文件、MySQL 和其他數(shù)據(jù)庫的文件、Web 服務(wù)器的數(shù)據(jù)文件、郵件以及更多。
表 1:Linux 文件系統(tǒng)層次結(jié)構(gòu)的頂層
這些目錄以及它們的子目錄如表 1 所示,在所有子目錄中,粗體的目錄組成了 root 文件系統(tǒng)的必需部分。也就是說,它們不能創(chuàng)建為一個(gè)分離的文件系統(tǒng)并且在開機(jī)時(shí)進(jìn)行掛載。這是因?yàn)樗鼈儯ㄌ貏e是它們包含的內(nèi)容)必須在系統(tǒng)啟動(dòng)的時(shí)候出現(xiàn),從而系統(tǒng)才能正確啟動(dòng)。
/media 目錄和 /mnt 目錄是 root 文件系統(tǒng)的一部分,但是它們從來不包含任何數(shù)據(jù),因?yàn)樗鼈冎皇且粋€(gè)臨時(shí)掛載點(diǎn)。
表 1 中剩下的非粗體的目錄不需要在系統(tǒng)啟動(dòng)過程中出現(xiàn),但會(huì)在之后掛載到 root 文件系統(tǒng)上,在開機(jī)階段,它們?yōu)橹鳈C(jī)進(jìn)行準(zhǔn)備,從而執(zhí)行有用的工作。
請參考官方 Linux 文件系統(tǒng)層次標(biāo)準(zhǔn)(FHS)網(wǎng)頁來了解這些每一個(gè)目錄以及它們的子目錄的更多細(xì)節(jié)。維基百科上也有關(guān)于 FHS 的一個(gè)很好的介紹。應(yīng)該盡可能的遵循這些標(biāo)準(zhǔn),從而確保操作和功能的一致性。無論在主機(jī)上使用什么類型的文件系統(tǒng),該層次目錄結(jié)構(gòu)都是相同的。
Linux 統(tǒng)一目錄結(jié)構(gòu)
在一些非 Linux 操作系統(tǒng)的個(gè)人電腦上,如果有多個(gè)物理硬盤驅(qū)動(dòng)器或多個(gè)分區(qū),每一個(gè)硬盤或分區(qū)都會(huì)分配一個(gè)驅(qū)動(dòng)器號(hào)。知道文件或程序位于哪一個(gè)硬盤驅(qū)動(dòng)器上是很有必要的,比如 C: 或 D: 。然后,你可以在命令中使用驅(qū)動(dòng)器號(hào),以 D: 為例,為了進(jìn)入 D: 驅(qū)動(dòng)器,你可以使用 cd 命令來更改工作目錄為正確的目錄,從而定位需要的文件。每一個(gè)硬盤驅(qū)動(dòng)器都有自己單獨(dú)的、完整的目錄樹。
Linux 文件系統(tǒng)將所有物理硬盤驅(qū)動(dòng)器和分區(qū)統(tǒng)一為一個(gè)目錄結(jié)構(gòu)。它們均從頂層 root 目錄(/)開始。所有其它目錄以及它們的子目錄均位于單一的 Linux 根目錄下。這意味著只有一棵目錄樹來搜索文件和程序。
因?yàn)橹挥幸粋€(gè)文件系統(tǒng),所以 /home、/tmp、/var、/opt 或 /usr 能夠創(chuàng)建在和 root(/)文件系統(tǒng)不同的物理硬盤驅(qū)動(dòng)器、分區(qū)或邏輯分區(qū)上,然后掛載到一個(gè)掛載點(diǎn)(目錄)上,從而作為 root 文件系統(tǒng)樹的一部分。甚至可移動(dòng)驅(qū)動(dòng)器,比如 USB 驅(qū)動(dòng)器或一個(gè)外接的 USB 或 ESATA 硬盤驅(qū)動(dòng)器均可以掛載到 root 文件系統(tǒng)上,成為目錄樹不可或缺的部分。
當(dāng)從 Linux 發(fā)行版的一個(gè)版本升級到另一個(gè)版本或從一個(gè)發(fā)行版更改到另一個(gè)發(fā)行版的時(shí)候,就會(huì)很清楚地看到這樣創(chuàng)建到不同分區(qū)的好處。通常情況下,除了任何像 Fedora 中的 dnf-upgrade 之類的升級工具,會(huì)明智地在升級過程中偶爾重新格式化包含操作系統(tǒng)的硬盤驅(qū)動(dòng)來刪除那些長期積累的垃圾。如果 /home 目錄是 root 文件系統(tǒng)的一部分(位于同一個(gè)硬盤驅(qū)動(dòng)器),那么它也會(huì)被格式化,然后需要通過之前的備份恢復(fù)。如果 /home 目錄作為一個(gè)分離的文件系統(tǒng),那么安裝程序?qū)?huì)識(shí)別到,并跳過它的格式化。對于存儲(chǔ)數(shù)據(jù)庫、郵箱、網(wǎng)頁和其它可變的用戶以及系統(tǒng)數(shù)據(jù)的 /var 目錄也是這樣的。
將 Linux 系統(tǒng)目錄樹的某些部分作為一個(gè)分離的文件系統(tǒng)還有一些其他原因。比如,在很久以前,我還不知道將所有需要的 Linux 目錄均作為 root(/)文件系統(tǒng)的一部分可能存在的問題,于是,一些非常大的文件填滿了 /home 目錄。因?yàn)?/home 目錄和 /tmp 目錄均不是分離的文件系統(tǒng),而是 root 文件系統(tǒng)的簡單子目錄,整個(gè) root 文件系統(tǒng)就被填滿了。于是就不再有剩余空間可以讓操作系統(tǒng)用來存儲(chǔ)臨時(shí)文件或擴(kuò)展已存在數(shù)據(jù)文件。首先,應(yīng)用程序開始抱怨沒有空間來保存文件,然后,操作系統(tǒng)也開始異常行動(dòng)。啟動(dòng)到單用戶模式,并清除了 /home 目錄中的多余文件之后,終于又能夠重新工作了。然后,我使用非常標(biāo)準(zhǔn)的多重文件系統(tǒng)設(shè)置來重新安裝 Linux 系統(tǒng),從而避免了系統(tǒng)崩潰的再次發(fā)生。
我曾經(jīng)遇到一個(gè)情況,Linux 主機(jī)還在運(yùn)行,但是卻不允許用戶通過 GUI 桌面登錄。我可以通過使用虛擬控制臺(tái)之一,通過命令行界面(CLI)本地登錄,然后遠(yuǎn)程使用 SSH 。問題的原因是因?yàn)?/tmp 文件系統(tǒng)滿了,因此 GUI 桌面登錄時(shí)所需要的一些臨時(shí)文件不能被創(chuàng)建。因?yàn)槊钚薪缑娴卿洸恍枰?/tmp 目錄中創(chuàng)建文件,所以無可用空間并不會(huì)阻止我使用命令行界面來登錄。在這種情況下,/tmp 目錄是一個(gè)分離的文件系統(tǒng),在 /tmp 所位于的邏輯卷上還有大量的可用空間。我簡單地?cái)U(kuò)展了 /tmp 邏輯卷的容量到能夠容納主機(jī)所需要的臨時(shí)文件,于是問題便解決了。注意,這個(gè)解決方法不需要重啟,當(dāng) /tmp 文件系統(tǒng)擴(kuò)大以后,用戶就可以登錄到桌面了。
當(dāng)我在一家很大的科技公司當(dāng)實(shí)驗(yàn)室管理員的時(shí)候,遇到過另外一個(gè)故障。開發(fā)者將一個(gè)應(yīng)用程序安裝到了一個(gè)錯(cuò)誤的位置(/var)。結(jié)果該應(yīng)用程序崩潰了,因?yàn)?/var 文件系統(tǒng)滿了,由于缺乏空間,存儲(chǔ)于 /var/log 中的日志文件無法附加新的日志消息。然而,系統(tǒng)仍然在運(yùn)行,因?yàn)?root 文件系統(tǒng)和 /tmp 文件系統(tǒng)還沒有被填滿。刪除了該應(yīng)用程序并重新安裝在 /opt 文件系統(tǒng)后,問題便解決了。
文件系統(tǒng)類型
Linux 系統(tǒng)支持大約 100 種分區(qū)類型的讀取,但是只能對很少的一些進(jìn)行創(chuàng)建和寫操作。但是,可以掛載不同類型的文件系統(tǒng)在同一個(gè) root 文件系統(tǒng)上,并且是很常見的。在這樣的背景下,我們所說的文件系統(tǒng)一詞是指在硬盤驅(qū)動(dòng)器或邏輯卷上的一個(gè)分區(qū)中存儲(chǔ)和管理用戶數(shù)據(jù)所需要的結(jié)構(gòu)和元數(shù)據(jù)。能夠被 Linux 系統(tǒng)的 fdisk 命令識(shí)別的文件系統(tǒng)類型的完整列表在此,你可以感受一下 Linux 系統(tǒng)對許多類型的系統(tǒng)的高度兼容性。
Linux 支持讀取這么多類型的分區(qū)系統(tǒng)的主要目的是為了提高兼容性,從而至少能夠與一些其他計(jì)算機(jī)系統(tǒng)的文件系統(tǒng)進(jìn)行交互。下面列出了在 Fedora 中創(chuàng)建一個(gè)新的文件系統(tǒng)時(shí)的所有可選類型:
btrfscramfsext2ext3ext4fatgfs2hfsplusminixmsdosntfsreiserfsvfatxfs
其他發(fā)行版支持創(chuàng)建的文件系統(tǒng)類型不同。比如,CentOS?6 只支持創(chuàng)建上表中標(biāo)為黑體的文件系統(tǒng)類型。
掛載
在 Linux 系統(tǒng)上“掛載mount”文件系統(tǒng)的術(shù)語是指在計(jì)算機(jī)發(fā)展的早期,磁帶或可移動(dòng)的磁盤組需要需要物理地掛載到一個(gè)合適的驅(qū)動(dòng)器設(shè)備上。當(dāng)通過物理的方式放置到驅(qū)動(dòng)器上以后,操作系統(tǒng)會(huì)邏輯地掛載位于磁盤上的文件系統(tǒng),從而操作系統(tǒng)、應(yīng)用程序和用戶才能夠訪問文件系統(tǒng)中的內(nèi)容。
一個(gè)掛載點(diǎn)簡單的來說就是一個(gè)目錄,就像任何其它目錄一樣,是作為 root 文件系統(tǒng)的一部分創(chuàng)建的。所以,比如,home 文件系統(tǒng)是掛載在目錄 /home 下。文件系統(tǒng)可以被掛載到其他非 root 文件系統(tǒng)的掛載點(diǎn)上,但是這并不常見。
在 Linux 系統(tǒng)啟動(dòng)階段的最初階段,root 文件系統(tǒng)就會(huì)被掛載到 root 目錄下(/)。其它文件系統(tǒng)在之后通過 SystemV 下的 rc 或更新一些的 Linux 發(fā)行版中的 systemd 等 Linux 啟動(dòng)程序掛載。在啟動(dòng)進(jìn)程中文件系統(tǒng)的掛載是由 /etc/fstab 配置文件管理的。一個(gè)簡單的記憶方法是,fstab 代表“文件系統(tǒng)表file system table”,它包含了需要掛載的文件系統(tǒng)的列表,這些文件系統(tǒng)均指定了掛載點(diǎn),以及針對特定文件系統(tǒng)可能需要的選項(xiàng)。
使用 mount 命令可以把文件系統(tǒng)掛載到一個(gè)已有的目錄/掛載點(diǎn)上。通常情況下,任何作為掛載點(diǎn)的目錄都應(yīng)該是空的且不包含任何其他文件。Linux 系統(tǒng)不會(huì)阻止用戶掛載一個(gè)已被掛載了文件系統(tǒng)的目錄或?qū)⑽募到y(tǒng)掛載到一個(gè)包含文件的目錄上。如果你將文件系統(tǒng)掛載到一個(gè)已有的目錄或文件系統(tǒng)上,那么其原始內(nèi)容將會(huì)被隱藏,只有新掛載的文件系統(tǒng)的內(nèi)容是可見的。
結(jié)論
我希望通過這篇文章,闡明了圍繞文件系統(tǒng)這個(gè)術(shù)語的一些可能的模糊之處。我花費(fèi)了很長的時(shí)間,以及在一個(gè)良師的幫助下才真正理解和欣賞到 Linux 文件系統(tǒng)的復(fù)雜性、優(yōu)雅性和功能以及它的全部含義。
如果你有任何問題,請寫到下面的評論中,我會(huì)盡力來回答它們。
?
評論