1.文件系統特性
磁盤分區后還需要進行格式化后操作系統才能使用這個文件系統,為什么要格式化?
因為每個操作系統所設定的文件屬性、權限不一樣,因此需要將分區槽格式化,以成為操作系統能夠利用的"文件系統格式"。
傳統技術中,一個分區槽只能被格式化成為一個文件系統,所以我們可以說一個filesystem是一個partition。但由于新技術的發展,例如LVM與軟件磁盤陣列(software raid),可以將一個分區槽格式化為多個文件系統,也能將多個分區槽格式化為一個文件系統。所以說,通常我們稱"一個可被掛載的數據為一個文件系統而不是一個分區槽"。
文件系統通常將操作系統的文件權限(rwx)和文件屬性(擁有者、群組、時間參數等)分別存放在不同的區塊,權限與屬性放到inode中,至于實際數據放到data block中。另外,還有一個超級區塊:
superblock:記錄整個文件系統的整體信息,包括inode與block的總量、使用量、剩余量等。
inode:記錄文件的權限與相關屬性,一個文件占用一個inode,同時記錄此文件的數據所在的block號碼。
block:實際記錄文件的內容,若文件太大時,會占用多個block。
由于每個inode與block都有編號,而每個文件都會占用一個inode,inode內會放置有block號碼,也就能夠讀文件的實際數據。如下圖所示:
假設一個文件的屬性與權限數據放到了inode4號,而這個inode記錄了文件數據的實際放置點是2、7、13、15,操作系統就能夠據此來排列磁盤的閱讀順序。這種數據存取方法我們稱為"索引式文件系統"。
還有慣用的是"隨身碟",文件系統一般為FAT格式:
這個文件系統沒有辦法一口氣知道4個block的號碼,它得將每個block讀出,才知道下一個block在哪。如果同一個文件數據寫入的block分散的厲害,磁盤頭就需要轉好幾圈才能完整讀取到文件的內容。
Linux的EXT2文件系統(inode)
文件系統一開始就將inode與block規劃好了,除非重新格式化,否則inode與block固定后就不再變動。
但如果文件系統有幾百GB時,所有的inode與block放置在一起時很不明智的。
所以,EXT2文件系統在格式化的時候基本上時區分為多個區塊群組,每個群組都有自己獨立的inode/block/superblock系統。如下圖所示:
- data block
用來放置文件內容數據,在EXT2文件系統中所支持的block大小有1K、2K、4K三種。
除了大小限制還有什么限制?基本限制如下:
block的大小與數量在格式化完就不能在改變了
每個block內最多只能存放一個文件的數據
如果文件大于block的大小,則一個文件會占用多個block數量
如果文件小于block的大小,則該block的剩余容量就不能在被使用
- inode table
inode記錄文件的屬性以及該文件實際數據放置在哪個block內。inode記錄的文件數據至少有以下這些:
該文件的存取模式(read/write/excute)
該文件的擁有者與群組(owner/group)
該文件的容量
該文件建立或狀態改變的事件(ctime)
最近一次的讀取時間(atime)
最近修改的時間(mtime)
定義文件特性的旗標(flag),如SetUID...
該文件真正內容的指向(pointer)
inode的特點:
數量與大小也是在格式化時就已經固定了
每個inode大小均固定為128bytes(新的ext4)
每個文件都只占用一個inode
文件系統能建立都文件數量與inode的數量有關
系統讀取文件時需要先找到inode,并分析inode記錄的權限與用戶是否符合,符合才能開始實際讀取block的內容
我們來分析以下EXT2的inode/block與文件大小的關系。inode要記錄的數據非常多,但大小只有128bytes,而inode記錄一個block號碼要花掉4byte,假設我有一個文件有400MB且每個block為4K時,那么至少要10w個block號碼記錄。inode哪有這么多可記錄的信息?為此我們系統將inode記錄與block號碼的區域定義為12個直接,1個間接,1個雙間接,1個三間接記錄區,結構如下所示:
假設我們以1K block大小來說明:
12個直接指向:12*1K=12K
直接指向就是直接存放的block的數據,總共可記錄12筆
間接:256*1K=256K
拿到額外一個block專門存取block號碼,每個block號碼記錄花去4bytes,1K的大小能記錄256個block。
雙間接:2562561K=256^2K
第一層block會指定256個第二層,每個第二層可以指定256個block號碼
三間接:256256256*1K=256^3K
第一層block會指定256個第二層,每個第二層指定256個第三層,每個第三層指定256個block號碼
- superblock
記錄整個文件系統相關信息的地方,主要記錄的信息有:
block與inode的總量
未使用與已使用的inode/block數量
block與inode的大小(block為1,2,4K;inode為128或256bytes)
filesystem的掛載時間、最近一次寫入數據的時間、最近一次檢驗磁盤的時間等文件系統的相關信息
一個valid bit數值,若此文件系統已被掛載,則valid bit為0,沒被掛載就為1。
一般來說,supderblock大小為1024bytes
我們說一個文件系統應該只有一個superblock,但是后續的block group可能還會有superblock,這是為了防止superblock死掉,進行的備份。
- filesystem Description(文件系統描述說明)
這個區段描述每個block group的開始與結束的block號碼,以及說明每個區段(superblock、bitmap、inodemap、data block)分別介于哪一個block號碼之間。
block bitmap(區塊對照表)
在新增文件的時候總會用到block,那怎么知道哪個block是空的呢,這就需要block bitmap的輔助了,能夠快速找到可使用的空間。inode bitmap(inode對照表)
這個和block bitmap相似的功能。記錄inode使用與未使用的號碼。
2.文件系統與目錄樹
2.1 目錄
在Linux下的文件系統建立一個目錄時,文件系統會給該目錄分配一個inode與至少一個block。其中,inode記錄該目錄的相關權限與屬性,并可以記錄分配到了哪塊block號碼;block記錄了這個目錄下的文件名與文件名占用的inode號碼數據。
可以使用命令"ls -il"選項查看某個目錄下的文件所占用的inode號碼
[jumpserver@xxx tomcat-analysis]$ ls -il
total 108
239384 drwxr-xr-x. 2 jumpserver root 4096 Apr 2 14:12 bin
268848599 drwxr-xr-x. 3 jumpserver root 4096 Apr 3 10:41 conf
538441458 drwxr-xr-x. 2 jumpserver root 4096 Apr 2 14:12 lib
268848635 -rw-r--r--. 1 jumpserver root 56846 Sep 14 2016 LICENSE
537335010 drwxr-xr-x. 3 jumpserver root 4096 Apr 10 15:08 logs
268848636 -rw-r--r--. 1 jumpserver root 1239 Sep 14 2016 NOTICE
268848637 -rw-r--r--. 1 jumpserver root 8965 Sep 14 2016 RELEASE-NOTES
268848638 -rw-r--r--. 1 jumpserver root 16195 Sep 14 2016 RUNNING.txt
807646942 drwxr-xr-x. 2 jumpserver root 29 Apr 2 14:12 temp
239395 drwxr-xr-x. 9 jumpserver root 4096 Apr 4 10:26 webapps
268848634 drwxr-xr-x. 3 jumpserver root 21 Apr 3 10:31 work
2.2 文件
在Linux下的EXT2下建立一個一般文件時,EXT2會分配一個inode和相對于該文件大小的block數量給該文件。
例如:假設block為4KB,我們要建立一個100KB的文件,那么Linux將分配一個inode和25個block來存儲該文件。注意:inode只有12個直接指向,因此還要多一個block來作為區塊號碼的記錄。
2.3 目錄樹讀取
inode本身并不記錄文件名,文件名的記錄在目錄的block中。所以我們在第五章文件與目錄的權限說明中,才會提到"新增、刪除、更名文件名與目錄的w權限有關"。
目錄樹是由根目錄開始讀起的,系統通過掛載的信息可以找到掛載點的inode號碼,此時就能夠得到根目錄的inode內容,根據該inode讀取根目錄的block內的文件名數據,再一層一層向下讀到正確的檔名。例如:我們想讀取"/etc/passwd"這個文件,系統由以下步驟:
[jumpserver@xxx tomcat-analysis]$ ll -di / /etc/ /etc/passwd
128 dr-xr-xr-x. 18 root root 4096 Aug 10 2018 /
16777345 drwxr-xr-x. 91 root root 8192 Mar 30 03:45 /etc/
18615857 -rw-r--r--. 1 root root 1613 Mar 15 15:53 /etc/passwd
[jumpserver@host-172-16-13-249 tomcat-analysis]$
- / 的inode:通過掛載點的信息找到inode號碼為128的根目錄inode,且inode規范的權限讓我們可以讀取該block的內容(由r、x)
- / 的block:經過上面步驟取得block號碼,并找到該內容有/etc目錄的inode號碼(16777345)
- etc/ 的inode:讀取16777345號inode得知root具有r、x的權限,因此可以讀取etc/的block
4.etc/ 的block:經過上個步驟取得block號碼,并找到該內容有passwd文件的inode號碼(18615857)
5.passwd的inode:讀取18615857號inode得知root有r的權限,因此可以讀取passwd的block內容
6.passwd的block:最后將該block內容的數據讀出來
2.4 磁盤讀取功能
當你的文件系統很大時,例如100GB,由于磁盤上面的數據總是來來去去,所以正規文件系統的文件通常無法連續卸載一起(block號碼不會連續),而是填入式的將數據填入未被使用的block中。這樣就會有所謂的"文件數據離散"問題。
它導致的結果就是讀取效率很低,因為磁盤讀取頭要在正規文件系統中反反復復的頻繁讀取。不過,你可以將整個文件系統的數據全部復制出來,將該系統重新格式化,再將數據復制回去可以解決這個問題。
EXT2/EXT3/EXT4 文件的存取與日志式文件系統的功能
假設我們想要新增一個文件,它的行為是怎樣的呢?
1.先確定用戶對想要新增文件的目錄是否有w與x的權限;
2.根據inode bitmap找到沒有使用的inode號碼,并將新文件的權限/屬性寫入;
3.根據block bitmap找到沒有使用的block號碼,并將實際數據寫入block中,且更新的inode的block指向;
4.將剛剛寫入的inode與block數據同步更新inode bitmap與block bitmap,并更新superblock的內容。
數據不一致的狀態:正常情況下,新增可以順利完成。如果在數據寫入inode table及data block后突然停電等突發狀況,最后一個superblock的同步更新步驟沒有做完,此時就會發生metadata的內容與實際數據存放區產生不一致。
早期的EXT2中,如果發生這個問題,系統在重啟的時候,就會把superblock記錄的valid bit(是否有掛載)與filesystem state(是否clean)等狀態來判斷是否需要進行數據一致性檢查。這樣的檢查真的很費時,metadata區域與實際數據存放區進行比對,要搜索整個filesystem!
日志式文件系統
為了避免上面的問題發生,后來想到一種方式:如果在我們的filesystem中規劃出一個區塊,該區塊專門記錄寫入活修訂文件的步驟:
1.預備:當系統要寫入一個文件時,會先在日志記錄區塊中記錄某個文件準備要寫入的信息。
2.實際寫入:開始寫入文件的權限與數據;開始更新metadata的數據。
3.結束:完成數據與metadata的更新后,在日志記錄區塊中完成該文件的記錄。
EXT3/EXT4是EXT2的升級版本,并可向下兼容。我們可以用"dumpe2fs"查看輸出的訊息,可以發現superblock里面含有journal處理日志區塊的記錄。
3.Linux文件系統的運作
3.1 大文件的運作
所有的數據要加載到內存后CPU才能對該數據進行處理。如果你編輯一個大文件,編輯過程中又頻繁的要系統來寫入到磁盤中,由于磁盤寫入的速度比內存慢很多,因此會常常等待磁盤的寫入/讀取效率!
為了解決整個問題,Linux使用的方式是異步處理(asynchronously):
當系統加載一個文件到內存后,如果該文件沒有被動過,則在內存區段的文件數據會被設定為干凈(clean)的。但如果內存中但文件數據被改過,此時該內存的數據會被設定為臟的(Dirty),此時所有的動作都還在內存中執行,并沒有寫入磁盤中。系統會不定時的將內存中設定為"Dirty"的數據寫回磁盤。其實也就是緩沖的功能。
3.2 掛載點的意義
每個filesystem都有獨立的inode/block/superblock等信息,這個文件系統要能夠鏈接到目錄樹才能被我們使用。將文件系統與目錄樹結合的動作我們成為"掛載"。
注意:掛載點一定是目錄,該目錄為進入該文件系統的入口。
舉例來說,CentOS7.x應該有3個掛載點,分別是"/","/boot","/home"。如果我們觀察這3個目錄的inode號碼,可以發現:
由于XFS文件系統最頂層的目錄inode一般為128,因此可以發現"/","/boot","/home"為3個不同的fielsystem。(因為每行的文件屬性不相同,并且3個目錄掛載點也不同)。
4.XFS文件系統
CentOS7開始,預設的文件系統由EXT4變成了XFS文件系統。這是由于哪些原因?
4.1 EXT家族目前的問題:支持度最廣,但格式化很慢!
EXT文件系統對于文件格式化處理,采用但是預先規劃出所有的inode/block/metadata等數據。早期磁盤容量不大這個還沒什么問題,但現在磁盤容量越來越大。光是系統要預先分配inode與block就要消耗很長很長時間了。
4.2 XFS文件系統配置
XFS在文件系統資料分布上,主要有3個部分:數據區(data section)、文件系統活動登錄區(log section)、實時運作區(realtime section)。
- 1.數據區(data section)
像EXT家族一樣,包括inode/datablock/superblock等,都放在這個區塊。這個數據去與EXT的block group類似,分為多個儲存區群組(allocation groups)來分別放置文件系統所需要的數據。
每個存儲區又包含:整個文件系統的superblock;剩余空間的管理機制;inode的分配與追蹤。此外,inode與block都是系統需要用到時,才動態配置產生,所以格式化很快!。
- 2.文件系統活動登錄區(log section)
主要來記錄文件系統的變化。如果文件系統因為某些故障損毀時,系統會拿這個登錄區來進行檢驗,查看系統掛掉前,文件系統正在做哪些動作。
- 3.實時運作區(realtime section)
有文件要被建立時,XFS會在這個區段里找一個或多個extent區塊,將文件放置在這個區塊內,等分配完成后,再寫入data section的inode與block。extent區塊的大小要在格式化的時候就先指定,最小4K最大1GB。
4.3 XFS文件系統的描述數據觀察
有么有像EXT家族的dumpe2fs一樣可以觀察superblock內容的相關指令?我們可以用xfs_info。
第1行里面的isize指inode的容量,每個有256bytes大小。agcount是儲存區群組的個數,一共是4個。agsize是指每個儲存區具有65536個block。配合第4行的block設定為4K,因此整個文件系統的容量是4655364K這么大。
第2行sectsz指邏輯扇區(sector)的容量設定為512bytes。
第4行bsize指block的容量,每個block為4K,共有262144個block在這個文件系統內。
第5行第sunit與swidth與磁盤陣列第stripe相關性較高。下面說明。
第7行internal指這個登錄區的位置在文件系統內,而不是外部設備的意思。占用4K*2560個block,總共月10MB的容量。
第9行的realtime區域,里面的extent容量為4K。目前沒有使用。