點擊上方「民工哥技術之路」,選擇「設為星標」
回復「1024」獲取獨家整理的學習資料!
文件系統要解決的一個關鍵問題是怎樣防止掉電或系統崩潰造成數據損壞,在此類意外事件中,導致文件系統損壞的根本原因在於寫文件不是原子操作,因為寫文件涉及的不僅僅是用戶數據,還涉及元數據(metadata)包括 Superblock、inode bitmap、inode、data block bitmap等,所以寫操作無法一步完成,如果其中任何一個步驟被打斷,就會造成數據的不一致或損壞。
舉一個簡化的例子,我們對一個文件進行寫操作,要涉及以下步驟:
從data block bitmap中分配一個數據塊;
在inode中添加指向數據塊的指針;
把用戶數據寫入數據塊。
如果步驟2完成了,3未完成,結果是數據損壞,因為該文件認為數據塊是自己的,但裡面的數據其實是垃圾;
如果步驟2完成了,1未完成,結果是元數據不一致,因為該文件已經把數據塊據為己有,然而文件系統卻還認為該數據塊未分配、隨後又可能會把該數據塊分配給別的文件、造成數據覆蓋;
如果步驟1完成了、2未完成,結果就是文件系統分配了一個數據塊,但是沒有任何文件用到這個數據塊,造成空間浪費;
如果步驟3完成了,2未完成,結果就是用戶數據寫入了硬碟數據塊中,但白寫了,因為文件不知道這個數據塊是自己的。
日誌文件系統(Journal File System)就是為解決上述問題而誕生的。
它的原理是在進行寫操作之前,把即將進行的各個步驟(稱為transaction)事先記錄下來,保存在文件系統上單獨開闢的一塊空間上,這就是所謂的日誌(journal),也被稱為write-ahead logging,日誌保存成功之後才進行真正的寫操作、把文件系統的元數據和用戶數據寫進硬碟(稱為checkpoint),這樣萬一寫操作的過程中掉電,下次掛載文件系統之前把保存好的日誌重新執行一遍就行了(術語叫做replay),避免了前述的數據損壞場景。
有人問如果保存日誌的過程中掉電怎麼辦?最初始的想法是把一條日誌的數據一次性寫入硬碟,相當於一個原子操作,然而這並不可行,因為硬碟通常以512位元組為單位進行操作,日誌數據一超過512位元組就不可能一次性寫入了。所以實際上是這麼做的:給每一條日誌設置一個結束符,只有在日誌寫入成功之後才寫結束符,如果一條日誌沒有對應的結束符就會被視為無效日誌,直接丟棄,這樣就保證了日誌裡的數據是完整的。
一條日誌在它對應的寫操作完成之後就沒用了,佔用的硬碟空間就可以釋放。保存日誌的硬碟空間大小是有限的,被循環使用,所以日誌也被稱為circular log。
至此可以總結一下日誌文件系統的工作步驟了:
Journal write : 把transaction寫入日誌中;
Journal commit : 在一條日誌保存好之後,寫入結束符;
Checkpoint : 進行真正的寫操作,把元數據(metadata)和用戶數據(user data)寫入文件系統;
Free : 回收日誌佔用的硬碟空間。
以上方式把用戶數據(user data)也記錄在日誌中,稱為Data Journaling,Linux EXT3文件系統就支持這種方式,這種方式存在效率問題:
就是每一個寫操作涉及的元數據(metadata)和用戶數據(user data)實際上都要在硬碟上寫兩次,一次寫在日誌裡,一次寫在文件系統上。元數據倒也罷了,用戶數據通常比較大,拷貝幾個GB的電影文件也要乘以2實在是降低了效率。
一個更高效的方式是Metadata Journaling,不把用戶數據(user data)記錄在日誌中,它防止數據損壞的方法是先寫入用戶數據(user data)、再寫日誌,即在上述」Journal write」之前先寫用戶數據,這樣就保證了只要日誌是有效的,那麼它對應的用戶數據也是有效的,一旦發生掉電故障,最壞的結果也就是最後一條日誌沒記完,那麼對應的用戶數據也會丟,效果與Data Journaling丟棄日誌一樣,重要的是文件系統的一致性和完整性是有保證的。
Metadata Journaling又叫Ordered Journaling,大多數文件系統都採用這種方式。像Linux EXT3文件系統也是可以選擇Data Journaling還是Ordered Journaling的。
參考資料:Crash Consistency: FSCK and Journaling
來源:http://linuxperf.com/?p=153華為第一款臺式機正式上線!
用了 10 年 Windows 後,我最終轉向 Linux
從 lsof 開始,深入理解 Linux 虛擬文件系統
一款超牛逼的 Linux 終端復用神器(附安裝、使用教程)
超詳細 116 頁 Elasticsearch 實戰文檔!高清可下載
抓包工具 tcpdump 用法說明
Linux 系統多網卡環境下的路由配置
Linux 或 Windows上實現埠映射