1. 程式人生 > >@轉EXT2->EXT3->EXT4

@轉EXT2->EXT3->EXT4

性能 常用 attr 6.2 bar alt time dex xfs

Linux文件系統第一篇—從Ext2到Ext3再到Ext4

1 概述

Linux繼承了UNIX一切皆文件的設計哲學,用文件和樹形目錄的抽象邏輯概念代替了硬盤和光盤等物理設備使用數據塊的概念,用戶使用文件系統來保存數據時不必關心數據實際保存在硬盤(或者光盤)的地址為多少的數據塊上,只需要記住這個文件的所屬目錄和文件名。但對於程序員來說,了解文件系統的底層組織方式,是進行Linux系統編程所必備的。接下來的討論主要聚焦於磁盤文件系統。

2 索引式文件系統與日誌式文件系統

2.1 索引式文件系統

  • 核心數據結構說明
Linux中文件和目錄保存在稱為塊設備的磁盤或磁帶上,通常每個磁盤上可以定義一個或多個文件系統,Linux文件系統的運行離不開三個重要的數據結構:superblock,inode,block,當然還包含引導塊,存放引導程序,用來讀入和啟動操作系統。
superblock:記錄文件系統的整體信息,包含inode/block的大小、總量、使用量、剩余量,以及文件系統的格式,文件系統掛載時間,最近一次數據寫入時間,最近一次校驗磁盤的時間等。
inode:記錄文件的屬性,一個文件占用一個inode,inode大小(ext2中)大約為128B,並記錄文件數據所在的block號碼,具體來說包含的信息如下:
  • 文件的字節數
  • 文件擁有者的User ID
  • 文件的Group ID
  • 文件的讀、寫、執行權限
  • 文件的時間戳,共有三個:ctime表示inode上一次變動的時間,mtime表示文件內容上一次變動的時間,atime表示文件上一次打開的時間
  • 鏈接數:指有多少文件名指向這個inode
  • 文件數據的block號碼
    在文件的block數量很大時,通常會采用多級block來記錄block號碼,這裏采用Bitmap標記未使用的inode號碼。
block:實際記錄文件的內容,若文件太大,則會占用多個block,通常的block大小有1K,2K,4K三種,這裏內核記錄block信息的數據結構是Bitmap。
使用dumpe2fs命令可以查詢某塊設備上superblock和blockgroup的詳細信息,這裏不再詳細給出。
此外,這裏再澄清兩個概念:
Hard Link:硬鏈接,硬鏈接文件和原始文件對應同一個inode號碼,增加硬鏈接文件一般不改變磁盤的空間與inode數目,通常硬鏈接文件不能跨越文件系統建立,並且不能生成目錄的鏈接文件。
Symbolic Link:符號鏈接,創建一個新的文件,讀取該文件時會讓數據讀取指向它link的文件的文件名,和原始文件的inode號碼不同。
如下圖,passwd-hd和passwd-so分別是passwd的硬鏈接和軟鏈接,可見前者和passwd的inode號碼一致,而後者不一致。
技術分享
  • 文件讀取流程介紹
文件系統需要鏈接到目錄樹才能被我們使用,也就是所謂的掛載,掛載點一定是目錄,該目錄是文件系統的入口。假設我們想要讀取文件/etc/paswd的內容,那麽一般需要從根目錄的inode內容開始往下讀,直到找到正確的文件名,具體流程在我的ubuntu 16.04上如下:
技術分享
  1. 尋找/的inode:通過掛載點信息找到inode號碼為2的inode,且其權限可以讓我們讀取block的內容;
  2. /的block:根據block的內容找到含有etc/目錄的inode號碼261633;
  3. etc/的inode:根據261633號inode內容中的權限值,知道可以讀取etc/的block內容;
  4. etc/的block:根據block號碼找到含有passwd文件的inode號碼261846;
  5. passwd的inode:根據261846號inode內容中的權限值,知道可以讀取passwd的block內容;
  6. passwd的block:讀取block中的內容至內存緩沖區。
2.2 日誌式文件系統
上述提到的文件系統稱為索引式文件系統,Linux內核早期支持中的ext2文件系統正是這種類型。這是針對新增一個文件時,需要的步驟如下:
  1. 確定使用者對於要增加新文件的目錄是否具有w與x的權限,如有,方可新增;
  2. 根據inode bitmap尋找到沒有使用的inode號碼,將新文件的權限/屬性寫入;
  3. 根據block bitmap找到沒有使用的block號碼,將數據寫入block中,更新inode的block指向數據;
  4. 將剛剛寫入的inode與block數據同步更新至inode bitmap和block bitmap,並更新superblock的內容。
上述的inode bitmap,block bitmap,superblock稱為系統的元數據(metadata)。在系統故障時,會出現元數據內容與實際數據存放內容不一致的情況,當然在文件系統重新啟動時,會調用文件掃描工具fsck來恢復損壞的元數據信息,但在文件系統很大時,要花費很長時間來恢復。針對上述不一致的情況,出現了日誌式文件系統,日誌式文件系統會專門劃出一個區塊記錄系統寫入和修改文件的步驟,此時寫文件的步驟如下:
  1. 準備:當系統寫入一個文件時,會在日誌記錄區塊記錄文件要寫入的信息;
  2. 寫入:寫入文件的權限和數據,更新元數據的內容;
  3. 完成:在數據與元數據更新完成後,在日誌記錄區塊中完成文件的記錄。
在出現故障需要恢復時,可根據日誌追蹤之前提交到主文件系統的更改,大大減少了磁盤的掃描時間,實現丟失數據的快速重建,比傳統的索引式文件系統更安全。Linux下的集中日誌式文件系統有XFS(目前是CentOS7的默認文件系統),ReiserFS,Ext3,Ext4。

3 Ext2/Ext3/Ext4的區別和比較

3.1 Ext2與Ext3的比較

ext3和ext2的主要區別在於,ext3引入Journal(日誌)機制,Linux內核從2.4.15開始支持ext3,它是從文件系統過渡到日誌式文件系統最為簡單的一種選擇,ext3提供了數據完整性和可用性保證

  • ext2和ext3的格式完全相同,只是在ext3硬盤最後面有一部分空間用來存放Journal的記錄;
  • 在ext2中,寫文件到硬盤中時,先將文件寫入緩存中,當緩存寫滿時才會寫入硬盤中;
  • 在ext3中,寫文件到硬盤中時,先將文件寫入緩存中,待緩存寫滿時系統先通知Journal,再將文件寫入硬盤,完成後再通知Journal,資料已完成寫入工作;
  • 在ext3中,也就是有Journal機制裏,系統開機時檢查Journal的內容,來查看是否有錯誤產生,這樣就加快了開機速度;
3.2 Ext3與Ext4的比較

Linux內核從2.6.28開始支持ext4文件系統,相比於ext3提供了更佳的性能和可靠性。下面先簡單羅列出二者的差異,後續文章再來深入探索。
1. 與 Ext3 兼容。 執行若幹條命令,就能從 Ext3 在線遷移到 Ext4,而無須重新格式化磁盤或重新安裝系統。原有 Ext3 數據結構照樣保留,Ext4 作用於新數據,當然,整個文件系統因此也就獲得了 Ext4 所支持的更大容量。
2. 更大的文件系統和更大的文件。 較之 Ext3 目前所支持的最大 16TB 文件系統和最大 2TB 文件,Ext4 分別支持 1EB的文件系統,以及 最大16TB 的文件。
3. 無限數量的子目錄。 Ext3 目前只支持 32,000 個子目錄,而 Ext4 支持無限數量的子目錄。
4. Extents。 Ext3 采用間接塊映射,當操作大文件時,效率極其低下。比如一個 100MB 大小的文件,在 Ext3 中要建立 25,600 個數據塊(每個數據塊大小為 4KB)的映射表。而 Ext4 引入了現代文件系統中流行的 extents 概念,每個 extent 為一組連續的數據塊,上述文件則表示為“該文件數據保存在接下來的 25,600 個數據塊中”,提高了不少效率。
5. 多塊分配。 當寫入數據到 Ext3 文件系統中時,Ext3 的數據塊分配器每次只能分配一個 4KB 的塊,寫一個 100MB 文件就要調用 25,600 次數據塊分配器,而 Ext4 的多塊分配器“multiblock allocator”(mballoc) 支持一次調用分配多個數據塊。
6. 延遲分配。 Ext3 的數據塊分配策略是盡快分配,而 Ext4 和其它現代文件操作系統的策略是盡可能地延遲分配,直到文件在 cache 中寫完才開始分配數據塊並寫入磁盤,這樣就能優化整個文件的數據塊分配,與前兩種特性搭配起來可以顯著提升性能。
7. 快速 fsck。 以前執行 fsck 第一步就會很慢,因為它要檢查所有的 inode,現在 Ext4 給每個組的 inode 表中都添加了一份未使用 inode 的列表,今後 fsck Ext4 文件系統就可以跳過它們而只去檢查那些在用的 inode 了。
8. 日誌校驗。 日誌是最常用的部分,也極易導致磁盤硬件故障,而從損壞的日誌中恢復數據會導致更多的數據損壞。Ext4 的日誌校驗功能可以很方便地判斷日誌數據是否損壞,而且它將 Ext3 的兩階段日誌機制合並成一個階段,在增加安全性的同時提高了性能。
9. “無日誌”(No Journaling)模式。 日誌總歸有一些開銷,Ext4 允許關閉日誌,以便某些有特殊需求的用戶可以借此提升性能。
10. 在線碎片整理。 盡管延遲分配、多塊分配和 extents 能有效減少文件系統碎片,但碎片還是不可避免會產生。Ext4 支持在線碎片整理,並將提供 e4defrag 工具進行個別文件或整個文件系統的碎片整理。
11. inode 相關特性。 Ext4 支持更大的 inode,較之 Ext3 默認的 inode 大小 128 字節,Ext4 為了在 inode 中容納更多的擴展屬性(如納秒時間戳或 inode 版本),默認 inode 大小為 256 字節。Ext4 還支持快速擴展屬性(fast extended attributes)和 inode 保留(inodes reservation)。
12. 持久預分配(Persistent preallocation)。 P2P 軟件為了保證下載文件有足夠的空間存放,常常會預先創建一個與所下載文件大小相同的空文件,以免未來的數小時或數天之內磁盤空間不足導致下載失敗。 Ext4 在文件系統層面實現了持久預分配並提供相應的 API(libc 中的 posix_fallocate()),比應用軟件自己實現更有效率。
13. 默認啟用 barrier。 磁盤上配有內部緩存,以便重新調整批量數據的寫操作順序,優化寫入性能,因此文件系統必須在日誌數據寫入磁盤之後才能寫 commit 記錄,若 commit 記錄寫入在先,而日誌有可能損壞,那麽就會影響數據完整性。Ext4 默認啟用 barrier,只有當 barrier 之前的數據全部寫入磁盤,才能寫 barrier 之後的數據。

4 小結

目前,大多數Linux發行版,包括我的Ubuntu 16.04的默認支持文件系統是ext4,ext4也是首個專門為Linux設計的文件系統,我們可以輕易的從ext3遷移到ext4,對於程序員來說,了解文件系統的演化脈絡是十分重要的,後續會繼續深入討論Linux下的各個文件系統。

參考資料
【1】鳥哥的Linux私房菜第八章
【2】Ext2、Ext3和Ext4之間的區別
【3】Linux 文件系統剖析

轉自 https://zhuanlan.zhihu.com/p/22976640 @auth 徐誌強

@轉EXT2->EXT3->EXT4