記錄檔系統可以在系統發生斷電或者其它系統故障時保證整體資料的完整性,Linux是目前支援記錄檔系統最多的作業系統之一,本文重點研究了Linux常用的記錄檔系統:EXT3、ReiserFS、XFS和JFS日誌技術,並採用標準的測試載入器PostMark和 Bonnie++對它們進行了測試,給出了詳細的效能分析,對Linux伺服器應用具有重要的參考價值。
一、概述
所謂日誌文
件系統是在傳統檔案系統的基礎上,加入檔案系統更改的日誌記錄,它的設計思想是:追蹤記錄檔案系統的變化,並將變化內容記錄入日誌。記錄檔系統在磁碟分割中儲存有日誌記錄,寫操作首先是對記錄檔案進行操作,若整個寫操作由於某種原因(如系統掉電)而中斷,系統重啟時,會根據日誌記錄來恢複中斷前的寫操作。在記錄檔系統中,所有的檔案系統的變化都被記錄到日誌,每隔一定時間,檔案系統會將更新後的中繼資料及檔案內容寫入磁碟。在對中繼資料做任何改變以前,檔案系統驅動程式會向日誌中寫入一個條目,這個條目描述了它將要做些什麼,然後它修改中繼資料。目前Linux的記錄檔系統主要有:在Ext2基礎上開發的Ext3,根據物件導向思想設計的ReiserFS,由SGI IRIX系統移植過來的XFS,由IBM AIX系統移植過來的JFS,其中EXT3完全相容EXT2,其磁碟結構和EXT2完全一樣,只是加入日誌技術;而後三種檔案系統廣泛使用了B樹以提高檔案系統的效率。
二、Ext3
Ext3 檔案系統是直接從Ext2檔案系統發展而來,目前Ext3檔案系統已經非常穩定可靠,它完全相容Ext2檔案系統,使用者可以平滑地過渡到一個日誌功能健全的檔案系統。Ext3記錄檔系統的思想就是對檔案系統進行的任何進階修改都分兩步進行。首先,把待寫塊的一個副本存放在日誌中;其次,當發往日誌的 I/O 資料傳送完成時(即資料提交到日誌),塊就寫入檔案系統。當發往檔案系統的I/O 資料傳送終止時(即資料提交給檔案系統),日誌中的塊副本就被丟棄。
2.1 Ext3記錄模式
Ext3既可以只對中繼資料做日誌,也可以同時對檔案資料區塊做日誌。具體來說,Ext3提供以下三種記錄模式:
日誌(Journal )
檔案系統所有資料和中繼資料的改變都記入日誌。這種模式減少了丟失每個檔案所作修改的機會,但是它需要很多額外的磁碟訪問。例如,當一個新檔案被建立時,它的所有資料區塊都必須複製一份作為日誌記錄。這是最安全和最慢的Ext3記錄模式。
預定(Ordered )
只有對檔案系統中繼資料的改變才記入日誌。然而,Ext3檔案系統把中繼資料和相關的資料區塊進行分組,以便把中繼資料寫入磁碟之前寫入資料區塊。這樣,就可以減少檔案內資料損毀的機會;例如,確保增大檔案的任何寫訪問都完全受日誌的保護。這是預設的Ext3 記錄模式。
寫回(Writeback )
只有對檔案系統中繼資料的改變才記入日誌;這是在其他記錄檔系統發現的方法,也是最快的模式。
2.2 日誌塊裝置(JBD)
Ext3 檔案系統本身不處理日誌,而是利用日誌塊裝置(Journaling Block Device)或叫JBD 的通用核心層。Ext3檔案系統調用JDB常式以確保在系統萬一出現故障時它的後續操作不會損壞磁碟資料結構。Ext3 與JDB 之間的互動本質上基於三個基本單元:日誌記錄,原子操作和事務。
日誌記錄本質上是檔案系統將要發出的低級操作的描述。在某些記錄檔系統中,日誌記錄只包括操作所修改的位元組範圍及位元組在檔案系統中的起始位置。然而,JDB 層使用的日誌記錄由低級操作所修改的整個緩衝區組成。這種方式可能浪費很多日誌空間(例如,當低級操作僅僅改變位元影像的一個位時),但是,它還是相當快的,因為JBD 層直接對緩衝區和緩衝區首部進行操作。
修改檔案系統的任一系統調用都通常劃分為操縱磁碟資料結構的一系列低級操作。如果這些低級操作還沒有全部完成系統就意外宕機,就會損壞磁碟資料。為了防止資料損毀,Ext3檔案系統必須確保每個系統調用以原子的方式進行處理。原子操作是對磁碟資料結構的一組低級操作,這組低級操作對應一個單獨的進階操作。
出於效率的原因,JBD 層對日誌的處理採用分組的方法,即把屬於幾個原子操作處理的日誌記錄分組放在一個單獨的事務中。此外,與一個處理相關的所有日誌記錄都必須包含在同一個事務中。一個事務的所有日誌記錄都存放在日誌的連續塊中。JBD層把每個事務作為整體來處理。例如,只有當包含在一個事務的日誌記錄中的所有資料提交給檔案系統時才回收該事務所使用的塊。
三、ReiserFS
ReiserFS 是一個非常優秀的檔案系統,其開發人員非常有魄力,整個檔案系統完全是從頭設計的。目前,ReiserFS可輕鬆管理上百G的檔案系統,這在企業級應用中非常重要。ReiserFS 是根據物件導向的思想設計的,由語義層(semantic layer)和儲存層(storage layer)組成。語義層主要是對對象命名空間的管理及對象介面的定義,以確定對象的功能。儲存層主要是對磁碟空間的管理。語義層與儲存層是通過鍵(key)聯絡的。語義層通過對對象名進行解析產生鍵,儲存層通過鍵找到對象在磁碟上儲存空間,索引值是全域唯一的。
3.1 語義層主要介面
1) 檔案介面 每個檔案擁有一個介面ID,此ID標識一個方法集,此方法集包含訪問ReiserFS 檔案的所有介面。
2) 屬性介面 ReiserFS實現了一種新介面,把檔案的每一種屬性當做一個檔案,屬性的值就是此檔案的內容,以實現對檔案屬性的目錄式訪問。
3) hash介面 目錄是檔案名稱到檔案的映射表,ReiserFS是通過B+樹來實現這張映射表。由於檔案名稱是變長的,而且有時檔案名稱會很長,所以檔案名稱不適合作為索引值,故引入了Hash函數來產生索引值。
4) 安全介面 安全介面處理所有的安全性檢查,通常是由檔案介面觸發的。下面以讀檔案為例:檔案介面的read 方法在讀入檔案資料之前會調用安全介面的read chech 方法來來進行安全性檢查,而後者又會調用屬性檔案的read方法把檔案屬性讀入以便檢查。
5) 項(Item)介面 項介面主要是一些對項進行平衡處理的方法,包括:項的拆分,項的評估,項的覆寫,項的追加,項的刪除,插入及尋找。
6) 鍵分配(key Assignment)介面 當把一個鍵分配給一個項時,鍵分配介面就會被觸發。每一種項都有一個與其對應的鍵分配方法。
3.2 儲存層
ReiserFS是以B+樹來儲存資料的,其結構
圖1:ReiserFS B+ 型樹狀結構
在B+樹中的各個結點中有一個稱為項(Item)的資料結構。項是一個資料容器,一個項只屬於一個結點,是結點管理空間的基本單位。,一個項包括以下內容:
1) Item_body:項的資料域
2) Item_key: 項的索引值
3) Item_offset:資料域的起點在結點中的位移量
4) Item_length: 資料域的長度
5) Item_Plugin_id:項介面ID。
圖2: ReiserFS 項結構
ReiserFS設計了多種不同的項以儲存不同的資料,主要有以下幾種:
1) static_stat_data: 靜態統計資料,包括檔案的所有者,存取權限,建立時間,最近修改時間,連結數等
2) cmpnd_dir_item: 包含各個目錄項
3) extend_pointers: 指向一個盤區(extend)
4) node_pointers: 指向一個結點
5) bodies: 包含的是檔案的小部分資料
3.3 ReiserFS日誌
與ext3 一樣,ReiserFS也有三種記錄模式,即journal,ordered,writeback。同時,ReiserFS引入了兩種日誌最佳化方法: copy-on-capture和steal-on-capture。copy-on-capture:當一個事務要修改的塊在另一個未提交的事務中時,就把這個塊複製一份,這樣這兩個事務就可以並發進行了。steal-on-capture:當一個塊被多個事務修改時,只有最晚提交的那個事務才把這個塊實際寫入檔案系統,其他事務都不寫這個塊。
四、XFS
XFS 是一種高效能的64 位元檔案系統,由SGI 公司為了替代原有的EFS 檔案系統而開發的。XFS 通過保持cache 的一致性、定位元據和分布處理磁碟請求來提供對檔案系統資料的低延遲、高頻寬的訪問。目前SGI已經將XFS檔案系統從IRIX移植到Linux。
4.1 分配組(allocation groups)
當建立 XFS 檔案系統時,底層塊裝置被分割成八個或更多個大小相等的線性地區(region),使用者可以將它們想象成"塊"(chunk)或者"線性範圍(range)",在 XFS 中,每個地區稱為一個"分配組"。分配組是唯一的,因為每個分配組管理自己的索引節點(inode)和空閑空間,實際上是將這些分配組轉化為一種檔案子系統,這些子系統透明地存在於 XFS 檔案系統內。有了分配組,XFS 代碼將允許多個線程和進程持續以並行方式運行,即使它們中的許多線程和進程正在同一檔案系統上執行大規模 IO 操作。因此,將 XFS 與某些高端硬體相結合,將獲得高效能而不會使檔案系統成為瓶頸。分配組在內部使用高效的 B+樹來跟蹤主要資料,具有優越效能和極大的可擴充性。
4.2 日誌記錄
XFS 也是一種日誌記錄檔案系統,它允許意外重新引導後的快速恢複。象 ReiserFS 一樣,XFS 使用邏輯日誌;它不象 ext3 那樣將文字檔案系統塊記錄到日誌,而是使用一種高效的磁碟格式來記錄中繼資料的變動。就 XFS 而言,邏輯日誌記錄是很適合的;在高端硬體上,日誌經常是整個檔案系統中爭用