Btrfs 詳解:基礎概念
介紹
文件系統是現代計算機的基礎之一。它是任何操作系統必不可少的一部分,且通常不為人注意。但是,像 Btrfs 這樣的現代文件系統提供了許多很棒的特性,使計算機的使用更加方便。例如,它可以無感地為你壓縮文件,或者為增量備份建立可靠的基礎。
這篇文章將帶你高屋建瓴地了解 Btrfs 文件系統是如何工作的,有什么特性。本文既不會過多涉及技術細節,也不會研究其底層實現,系列后續的文章會詳細介紹一些重要特性。
什么是文件系統
如果你基本了解過文件系統是如何工作的,那么下面的內容對你應該是不陌生的,你可以直接跳到下一節。否則,請先閱讀下面對文件系統的簡短介紹。
簡單來說,文件系統允許你的 PC 去尋找存儲在磁盤上的數據。這聽起來像是微不足道的工作,但實際上時至今日各種類型的非易失性存儲設備(比如機械硬盤、固態硬盤、SD 卡等等)仍然與 1970 年代 PC 被發明時基本相同:一個(巨大的)存儲塊集合。
“塊Block” 是最小的可尋址存儲單元。PC 上的每個文件內容被存儲在多個塊中。一個塊通常是 4096 字節的大小。這取決于你的硬件和在這之上的軟件(即文件系統)。
文件系統允許我們從海量的存儲塊中查找文件的內容,這是通過所謂的 inode
下面是 inode 的示意圖:
A text file “myfile.txt” and a hypothetical example of its representation on disk. All the squares are individual storage blocks.
inode 的結構對文件系統的功能有巨大的影響,因此它是各種文件系統諸多的重要數據結構之一。出于這個原因,每個文件系統有各自的 inode 結構。如果你想了解更多信息,看看下面 鏈接 關于 Btrfs 文件系統 inode 結構的內容。如需更詳細地了解各個字段的含義,你可以 參考 ext4 文件系統的 inode 結構。
寫時復制(CoW)文件系統
相比 ext4,Btrfs 擁有的杰出特性之一是,它是一個 寫時復制Copy-on-Write(CoW)文件系統。當一個文件被改變和回寫磁盤,它不會故意寫回它原來的位置,而是被復制和存儲在磁盤上的新位置。從這個意義上,可以簡單地認為 Cow 是一種 “重定向”,因為文件寫入被重定向到不同的存儲塊上。
這聽起來很浪費,但實際上并不是。這是因為被修改的數據無論如何一定會被寫到磁盤上,不管文件系統是如何工作的。Btrfs 僅僅是確保了數據被寫入在之前沒被占據的塊上,所以舊數據保持完整。唯一真正的缺點就是這種行為會導致文件碎片化比其他文件系統要快。在日常的電腦使用中,你不太可能會注意到這點差異。
CoW 的優勢在哪里?簡單的說:文件被修改和編輯的歷史被保存了下來。Btrfs 保存文件舊版本的引用(inode)可以輕易地被訪問。這個引用就是快照:文件系統在某個時間點的狀態鏡像。這將是這系列文章里的單獨的一篇,所以暫時留到后面介紹。
除了保存文件歷史,CoW 文件系統永遠處于一致的狀態,即使之前的文件系統事務(比如寫入一個文件)由于斷電等原因沒有完成。這是因為文件系統的元數據更新也是寫時復制的:文件系統本身永遠不會被覆寫,所以中斷不會使其處于部分寫入的狀態。
對文件的寫時復制
你可以將文件名視為對 inode 的指針。在寫入文件的時候,Btrfs 創建一個被修改文件內容(數據)的拷貝,和一個新的 inode(元數據),然后讓文件名指向新的 inode,舊的 inode 保持不變。下面是一個假設示例來闡述這點:
Continuation of the example above: 3 more bytes of data were added
這里 myfile.txt
增加了三個字節。傳統的文件系統會更新中間的 Data
塊去包含新的內容。CoW 文件系統不會改變舊的數據塊(圖中灰色),寫入(復制)更改的數據和元數據在新的地方。值得注意的是,只有被改變的數據塊被復制,而不是全部文件。
如果沒有空閑的塊去寫入新內容,Btrfs 將從被舊文件版本占據的數據塊中回收空間(除非它們是快照的一部分,本系列后續文章會看到)。
對目錄的寫時復制
從文件系統的角度看,目錄只是特殊類型的文件。與常規文件不同,文件系統直接解釋數據塊的內容。一個目錄有自身的元數據(inode,就像上面說的文件一樣)去記錄訪問權限或修改時間。最簡單的形式,存在目錄里的數據(被叫作目錄項)是一個 inode 引用的列表,每個 inode 又是另外的文件或目錄。但是,現代文件系統在目錄項中至少會存儲一個文件名和對應的 inode 引用。
之前已經指出,寫入一個文件會創建之前 inode 的副本,并相應修改其內容。從根本上,這產生了一個和之前無關的新的 inode 。為了讓被修改的文件對文件系統可見,所有包含這個文件引用的目錄項都會被更新。
這是一個遞歸的過程!因為一個目錄本身是一個帶有 inode 的文件。修改目錄里的任何一項都會為這個目錄文件創建新的 inode 。這會沿著文件系統樹遞歸直到文件系統的根。
所以,只要保留對任何舊目錄的引用,并且這些目錄沒有被刪除和覆寫,就可以遍歷之前舊狀態的文件系統樹。這就是快照的功能。
后續文章可以期待的內容
Btrfs 不只是一個 Cow 文件系統。它目標是實現高級特性的同時關注容錯、修復和易于管理(參見 文檔)。本系列未來的文章將會專門介紹這些特性。
- 子卷 – 文件系統中的文件系統
- 快照 – 回到過去
- 壓縮 – 透明節省存儲空間
- 配額組 – 限制文件系統大小
- RAID – 替代 mdadm 配置
這遠非 Btrfs 特性的詳盡列表。如果你想全面地了解可用特性,查看 維基 和 文檔。
總結
我希望我已能激起你進一步了解計算機文件系統的興趣。如果目前你有任何疑問,請在評論區留言討論以便在日后文章中探討,同時,你也可以自行學習文中提供的相關資源。如果你發現 Btrfs 中某項特別有趣的功能,也歡迎在評論區提出。如果某個主題收到足夠的關注,我可能會在系列文章中新增相關內容。下一篇文章再見!