摘要:Linux 磁碟與硬體管理
转自:linux.vbird.org 鸟哥的linux私房菜
認識硬碟:
既然這個章節主要在探討 Linux 的磁碟檔案系統,所以我們當然就需要先來瞭解一下硬碟是個什麼東西啦!首先,我們就來看一看硬碟的物理組成,瞭解了物理組成之後,再來說明一下怎麼樣進行硬碟的分割 (partition) 吧!
物理組成:就硬碟的物理元件來說,硬碟其實是由許許多多的圓形硬碟盤所組成的,依據硬碟盤能夠容納的資料量,而有所謂的單碟(一塊硬碟裡面只有一個硬碟盤)或者是多碟(一塊硬碟裡面含有多個硬碟盤)的硬碟。在這裡我們以單一個硬碟盤來說明,硬碟盤可由底下的圖形來示意:
圖一、硬碟盤示意圖
圖二、磁柱示意圖
首先,硬碟裡面一定會有所謂的磁頭 ( Head )在進行該硬碟盤上面的讀寫動作;而當磁頭固定不動,硬碟盤轉一圈所畫出來的圓就是所謂的磁軌( Track );而如同我們前面剛剛提到的,一塊硬碟裡面可能具有多個硬碟盤,所有硬碟盤上面相同半徑的那一個磁軌就組成了所謂的磁柱( Cylinder )。例如上圖二所示意,在兩個硬碟盤上面的同一個磁軌就是一個磁柱啦!這個磁柱也是磁碟分割( partition )時的最小單位了;另外,由圓心向外劃直線,則可將磁軌再細分為一個一個的磁區( Sector ),這個磁區就是硬碟盤上面的最小儲存物理量了!通常一個 sector 的大小約為 512 Bytes 。以上就是整個硬碟的基本元件。
磁碟分割 ( Partition ):在瞭解了硬碟的物理元件之後,再接著下來介紹的就是硬碟的分割( Partition )囉!為什麼要進行硬碟分割啊?!因為我們必須要告訴作業系統:『我這塊硬碟可以存取的區域是由 A 磁柱到 B 磁柱』,如此一來,作業系統才能夠控制硬碟磁頭去 A-B 範圍內的磁柱存取資料;如果沒有告訴作業系統這個資訊,那麼作業系統就無法利用我們的硬碟來進行資料的存取了,因為作業系統將無法知道他要去哪裡讀取資料啊!這 就是磁碟分割( Partition )的重點了:也就是記錄每一個分割區( Partition )的起始與結束磁柱!好了,那麼這個分割區的起始與結束磁柱的資料放在哪裡呢?!那就是我們在 Linux 安裝與多重開機技巧 那個章節提到的 主要開機磁區( Master Boot Recorder, MBR )囉!事實上, MBR 就是在一塊硬碟的第零軌上面,這也是電腦開機之後要去利用該硬碟時,必須要讀取的第一個區域!在這個區域內記錄的就是硬碟裡面的所有分割資訊,以及開機的時候可以進行該機管理程式的寫入的處所啊!所以,當一個硬碟的 MBR 壞掉時,由於分割的資料不見了,呵呵,那麼這個硬碟也就幾乎可以說是壽終正寢了,因為作業系統不知道該去哪個磁柱上讀取資料啊~~
那麼 MBR 有什麼限制呢?他最大的限制來自於他的大小不夠大到儲存所有分割與開機管理程式的資訊,因此,他僅提供最多四個 partition 的記憶,這就是所謂的 Primary (P)與 Extended (E) 的 partition 最多只能有四個的原因了。所以說,如果你預計分割超過 4 個 partition 的話,那麼勢必需要使用 3P + 1E ,並且將所有的剩餘空間都撥給 Extended 才行( 記得呦! Extended 最多只能有一個 ),否則只要 3P + E 之後還有剩下的空間,那麼那些容量將成為廢物而浪費了,所以結論就是『如果您要分割硬碟時,並且已經預計規劃使用掉 MBR 所提供的 4 個 partition ( 3P + E 或 4P )那麼磁碟的全部容量需要使用光,否則剩下的容量也不能再被使用』。不過,如果您僅是分割出 1P + 1E 的話,那麼剩下的空間就還能再分割兩個 partition !
檔案系統( Filesystem ):在告知系統我的 partition 所在的起始與結束磁柱之後,再來則是需要將 partition 格式化為『我的作業系統認識的檔案系統( Filesystem )』囉!因為每個作業系統認識的 filesystem 並不相同!例如 Windows 作業系統在預設狀態下就無法認識 Linux 的檔案系統 ( 這裡指 Linux 的標準檔案系統 ext2 )。所以當然要針對我們的作業系統來格式化 partition 囉!
我們可以說,每一個 partition 就是一個 Filesystem ,那麼一個 partition 是否可以具有兩個 Filesystem 呢?!理論上應該是不行的!因為每個檔案系統都有其獨特的支援方式,例如 Linux 的 ext3 就無法被 Windows 系統所讀取!而你將一個 partition 格式化的時候,總不能格式化為 ext3 也同時格式化為 fat32 吧?!那是不可能的啊!
不論是哪一種 filesystem ,資料總是需要儲存的吧!既然硬碟是用來儲存資料的,想當然爾,資料就必須寫入硬碟啦!剛剛我們提到硬碟的最小儲存單位是 sector ,不過資料所儲存的最小單位並不是 sector 喔,因為用 sector 來儲存太沒有效率了。怎麼說呢?因為一個 sector 只有 512 Bytes ,而磁頭是一個一個 sector 的讀取,也就是說,如果我的檔案有 10 MBytes ,那麼為了讀這個檔案,我的磁頭必須要進行讀取 (I/O) 20480 次!
為了克服這個效率上的困擾,所以就有邏輯區塊( Block )的產生了!邏輯區塊是在 partition 進行 filesystem 的格式化時,所指定的『最小儲存單位』,這個最小儲存單位當然是架構在 sector 的大小上面( 因為 sector 為硬碟的最小物理儲存單位啊! ),所以啦, Block 的大小為 sector 的 2 的次方倍數。此時,磁頭一次可以讀取一個 block ,如果假設我們在格式化的時候,指定 Block 為 4 KBytes ( 亦即由連續的八個 sector 所構成一個 block ),那麼同樣一個 10 MBytes 的檔案,磁頭要讀取的次數則大幅降為 2560 次,這個時候可就大大的增加檔案的讀取效能啦!
不過,Block 單位的規劃並不是越大越好喔!怎麼說呢?因為一個 Block 最多僅能容寄兀颗e例來說好了,假如您的 Block 規劃為 4 KBytes ,而您有一個檔案大小為 0.1 KBytes ,這個小檔案將佔用掉一個 Block 的空間,也就是說,該 Block 雖然可以容納 4 Kbytes 的容量,然而由於檔案只佔用了 0.1 Kbytes ,所以,實際上剩下的 3.9 KBytes 是不能再被使用了,所以,在考慮 Block 的規劃時,需要同時考慮到:
檔案讀取的效能
檔案大小可能造成的硬碟空間浪費
因此,在規劃您的磁碟時,需要留意到您主機的用途來進行規劃較佳!例如 BBS 主機由於文章較短,也就是說檔案較小,那麼 Block 小一點的好;而如果您的主機主要用在儲存大容量的檔案,那麼考慮到效能,當然 Block 理論上,規劃的大一點會比較妥當啦!
Superblock:如同前面說的,當我們在進行磁碟分割( partition )時,每個磁碟分割槽( partition )就是一個檔案系統( filesystem ),而每個檔案系統開始的位置的那個 block 就稱為 superblock ,superblock的作用是儲存像是檔案系統的大小、空的和填滿的區塊,以及他各自的總數和其他諸如此類的資訊等等,這也就是說,當您要使用這一個磁碟分割槽( 或者說是檔案系統 )來進行資料存取的時候,第一個要經過的就是 superblock 這個區塊了,所以囉, superblock 壞了,您的這個磁碟槽大概也就回天乏術了!
Linux 的檔案系統( inode ):看完了上面的說明,您應該對於硬碟有一定程度的認識了!好了,那麼接下來就是要談一談 Linux 的檔案系統( Filesystem )囉!我們這裡以 Linux 最標準的 ext2 這個檔案系統來作為說明。還記得我們在 Linux 檔案屬性與目錄配置 那個章節提到的,在 Linux 系統當中,每個檔案不止有檔案的內容資料,還包括檔案的種種屬性,例如:所屬群組、所屬使用者、能否執行、檔案建立時間、檔案特殊屬性等等。由於 Linux 作業系統是一個多人多工的環境,為了要保護每個使用者所擁有資料的隱密性,所以檔案屬性的增加是在所難免的!在標準的 ext2 檔案系統當中,我們將每個檔案的內容分為兩個部分來儲存,一個是檔案的屬性,另一個則是檔案的內容。
為了應付這兩個不同的咚咚,所以 ext2 規劃出 inode 與 Block 來分別儲存檔案的屬性( 放在 inode 當中 )與檔案的內容( 放置在 Block area 當中 )。當我們要將一個 partition 格式化( format )為 ext2 時,就必須要指定 inode 與 Block 的大小才行,也就是說,當 partition 被格式化為 ext2 的檔案系統時,他一定會有 inode table 與 block area 這兩個區域。
Block 已經在前面說過了,他是資料儲存的最小單位。那麼 inode 是什麼?!簡單的說, Block 是記錄『檔案內容資料』的區域,至於 inode 則是記錄『該檔案的相關屬性,以及檔案內容放置在哪一個 Block 之內』的資訊。簡單的說, inode 除了記錄檔案的屬性外,同時還必須要具有指向( pointer )的功能,亦即指向檔案內容放置的區塊之中,好讓作業系統可以正確的去取得檔案的內容啊!底下幾個是 inode 記錄的資訊(當然不止這些):
該檔案的擁有者與群組(owner/group);
該檔案的存取模式;
該檔案的類型;
該檔案的建立日期(ctime)、最近一次的讀取時間(atime)、最近修改的時間 (mtime);
該檔案的容量;
定義檔案特性的旗標(flag),如 SetUID...;
該檔案真正內容的指向 (pointer);
至於一個 inode 的大小為 128 bytes 這麼大!好了,那麼我的 Linux 系統到底是如何讀取一個檔案的內容呢?底下我們分別針對目錄與檔案來說明:
目錄:
當我們在 Linux 下的 ext2 檔案系統建立一個目錄時, ext2 會分配一個 inode 與至少一塊 Block 給該目錄。其中,inode 記錄該目錄的相關屬性,並指向分配到的那塊 Block ;而 Block 則是記錄在這個目錄下的相關連的檔案(或目錄)的關連性!
檔案:
當我們在 Linux 下的 ext2 建立一個一般檔案時, ext2 會分配至少一個 inode 與相對於該檔案大小的 Block 數量給該檔案。例如:假設我的一個 Block 為 4 Kbytes ,而我要建立一個 100 KBytes 的檔案,那麼 linux 將分配一個 inode 與 25 個 Block 來儲存該檔案!
由上面的說明當中,我們可以知道要讀取一個樹狀目錄下的檔案時,作業系統會先讀取該檔案所在目錄的 inode ,並取得該目錄的關連區域(在 Block 區域裡面),然後根據該關連資料讀取該檔案所在的 inode ,並再進一步經由檔案的 inode 來取得檔案的最後內容!舉個例子來說,假設我們要讀取 /etc/crontab 這個檔案,整個讀取的流程是如何呢?可由底下的圖三來作為說明:
圖三、讀取 /etc/crontab 的簡易流程示意。
一塊 partition 在 ext2 底下會被格式化為 inode table 與 block area 兩個區域,所以在圖三裡面,我們將 partition 以長條的方式來示意,會比較容易理解的啦!而讀取 /etc/crontab 的流程為:
作業系統根據根目錄( / )的相關資料可取得 /etc 這個目錄所在的 inode ,並前往讀取 /etc 這個目錄的所有相關屬性;
根據 /etc 的 inode 的資料,可以取得 /etc 這個目錄底下所有檔案的關連資料是放置在哪一個 Block 當中,並前往該 block 讀取檔案的關連性內容;
由上個步驟的 Block 當中,可以知道 crontab 這個檔案的 inode 所在地,並前往該 inode ;
由上個步驟的 inode 當中,可以取得 crontab 這個檔案的所有屬性,並且可前往由 inode 所指向的 Block 區域,順利的取得 crontab 的檔案內容。
整個讀取的流程大致上就是這樣,不過這裡有幾點小事情要提醒一下:
在目錄底下的檔案數如果太多而導致一個 Block 無法容納的下所有的關連性資料時,Linux 會給予該目錄多一個 Block 來繼續記錄關連資料;
一個檔案所佔用的 Block 都會記錄在該檔案所在的 inode 內,所以硬碟的磁頭可以直接去讀取各個 Block ,除非該檔案所儲存的各個 Block 真的很離散(事實上不太可能發生),否則在 Linux 的 ext2 當中,是不需要進行磁碟重組的!
inode 數量與 Block 的大小在格式化的時候就已經被設定好了,通常一個 Block 的大小為 4 Kbytes,至於 inode 的數量則依據不同的設定而異,基本的設定為 ( 硬碟大小 / 一個 inode 所控制的容量 ) 。舉例來說,我有一個 1 GBytes 的硬碟,我希望該硬碟中 inode 的數量只要 block 的一半就好了,那麼就可以設定一個 inode 控制的容量為 8 Kbytes ,則 inode 數量共有: ( G * 1024M/G * 1024K/M )/( 8 K ) = 131072 個 inode 囉!而 inode table 則佔去了 131072 * 128 byte = 16777216 bytes = 16384 Kbytes。也就是說,這一個 1GB 的硬碟還有沒任何資料時,就少了 16 MBytes 的容量啦!(用在 inode table 上面)。
因為一個 inode 只能記錄一個檔案的屬性,所以 inode 數量比 block 多是沒有意義的!舉上面的例子來說,我的 Block 規劃為 4 Kbytes ,所以 1GB 大概就有 262144 個 4Kbytes 的 block ,如果一個 block 對應一個 inode 的話,那麼當我的 inode 數量大於 262144 時,多的 inode 將沒有任何用處,徒然浪費硬碟的空間而已!另外一層想法,如果我的檔案容量都很大,那麼一個檔案佔用一個 inode 以及數個 block ,當然 inode 數量就可以規劃的少很多啦!
格式化 Linux 的 ext2 檔案系統,可以使用 mke2fs 這個程式來執行!
當 block 大小越小,而 inode 數量越多,則可利用的空間越多,但是大檔案寫入的效率較差;這種情況適合檔案數量多,但是檔案容量小的系統,例如 BBS 或者是新聞群組( News )這方面服務的系統;
當 Block 大小越大,而 inode 數量越少時,大檔案寫入的效率較佳,但是可能浪費的硬碟空間較多;這種狀況則比較適合檔案容量較大的系統!
Linux 檔案系統的運作:好了,知道了 Linux 標準的 ext2 檔案系統的狀況後,再來瞭解一下那麼 Linux 系統在運作時,他是如何進行資料的存取呢?!我們知道,整個電腦主機當中,輸出輸入 (I/O) 最快速的應該是 CPU 的快取了,然後則是主記憶體,至於硬碟的存取則比前兩個慢上許多。為了讓 Linux 加快整個系統的存取效率,因此在 Linux 上面通常採取非同步處理( asynchronously )的方式。什麼是非同步呢?舉例來說:『當系統讀取了某一個檔案,則該檔案所在的 區塊資料會被載入到記憶體當中,所以該磁碟區塊就會被放置在主記憶體的緩衝快取區中,若這些區塊的資料被改變時,剛開始資料僅有主記憶體的區塊資料會被改變,而且在緩衝區當中的區塊資料會被標記為” Dirty “,這個時候磁碟實體區塊尚未被修正!所以亦即表示,這些” Dirty “區塊的資料必需回寫到磁碟當中,以維持磁碟實體區塊上的資料與主記憶體中的區塊資料的一致性。』
為什麼要這麼做呢?這是因為主記憶體的運作速度比起硬碟來實在是快太多了,萬一系統當中有一個檔案相當的大,而又持續性的存取,那麼由於較慢的硬碟存取速度,將使得整個 Linux 速度被拖垮,所以才會使用非同步方式的資料處理啊!不過,也由於硬碟與主記憶體的資料可能沒有同步化,因此,如果 Linux 不正常關機( 例如跳電或者是當機 )時,則由於資料尚未回寫入磁碟當中,會導致系統在再次開機時,會花相當多的時間進行磁碟檢驗,同時也有可能造成磁碟的損毀啊!
附錄一:第二延伸檔案系統 ext2
這裡轉貼一篇關於 ext2 這個 Linux 檔案格式的主要特點:
第二延伸檔案系統(ext2)介紹 (本文摘自小紅帽技術論壇)
自從我們開始使用電腦後,大多數的使用者都曾經使用過檔案,而我們總是對關於硬碟如何正確地儲存檔案感到好奇,它看起來似乎非常抽象,所以今天讓我們看一看 Linux 作業系統中較新的檔案系統版本『第二延伸系統( ext2 )』,並了解它各方面之用途。
這個檔案系統是主要來自於Andrew Tanenbaum 所寫的Minix檔案系統,它也是唯一可用在免費作業系統的檔案系統,稱之為Minix。它後來修正為 Linux 所慣用的檔案系統並稱為延伸檔案系統,到現在 Linux 的檔案系統稱為 ext2 (第二延伸檔案系統),它是延伸檔案系統中較新的版本並支援存取控制列(ACL)。
但是在著手研究 ext2 檔案系統之前,讓我們先了解檔案系統中之專有名詞的關聯。
Block (區塊): 檔案在磁碟中被儲存在整數固定大小的區塊中,那區塊的大小通常是2的次方。在預設中,ext2檔案系統的區塊大小是4K。研究顥示,4K位元組對於一磁碟區塊而言是最理想的大小,假如一個檔案的大小無法達成4K位元組的倍數時,那最後的磁碟區塊部分就會被浪費。在最不好的例子中幾乎在完整的區塊中就有一位元組被浪費掉。
對於這情況有一點技巧,假如我們選擇了一個較大的區塊,則對於小的檔案而言會有一些磁碟空間被浪費掉。另外一方面,假如我們使用一個非常小的區塊,則磁碟區塊數量會成指數的增加,因此對於檔案而言需有更多的搜尋時間。所以,選擇區塊大小必須三思而後行。
當一個檔案被載入到記憶體時,那磁碟區塊會被放在主記憶體中之緩衝快取區,假如它們已經變更了,區塊在緩衝區中會被標記為’Dirty’,其意指的是這些區塊必須先寫到磁碟中來維持磁碟上的區塊及在主記憶體中的區塊之一致性.
Superblock:superblock 是在每個檔案系統開始的位置,其儲存資訊像是檔案系統的大小,空的和填滿的區塊,它們各自的總數和其他諸如此類的資料。要從一個檔案系統中存取任何檔案皆須經過檔案系統中之superblock。如果superblock損壞了,它可能無法從磁碟中去取得資料。
Inode: 對於檔案系統而言一個inode是在inode表格中的一個項目。Inode包含了所有檔案有關的資訊例如名稱、大小、連接的數量、資料建立之日期,修改及存取的時間。它也包含了磁碟區塊的檔案指向(pointer)。pointer是用來記錄檔案被儲存在何處。
Ext2fs公用程式
現在讓我們來看看一些標準Linux版本之ext2fsprogs公用程式
e2fsck
這個程式允許我們在ext2檔案系統上去執行檔案系統檢查,它像是Windows中之 Scandisk一樣,但卻是一種更有效的系統檢查方式。在此,我們可以加上一個檔案名稱來檢查上面之損壞區塊。
警告:絕對不要在任何已掛載的檔案系統上執行 e2fsck/fsck。假如我們想要去執行 fsck,我們應該卸下檔案系統後再去執行 fsck(亦即需要 umount 該磁區囉)。如果不這樣做,可能會讓檔案系統毀損。
tune2fs
這允許我們去調整檔案系統的參數設定。在此,我們可以設定在兩個檔案系統檢查間之最大掛載總數、容量標記、錯誤行為、變更保留的資訊和許多其他參數。
dumpe2fs
這個程式將ext2檔案系統狀態輸出到標準的設備上。它對於分析問題以及存取一般關於檔案系統用法的資訊是有幫助的。
mke2fs
這個程式允許我們在先前尚未格式化的磁碟中,去建立一個ext2的檔案系統。它提供了許多的選項包含區塊的大小、段落的大小、每一個inode的位元組到多種磁碟陣列的選項。mke2fs通常在第一次安裝的期間執行,並建立完成新的 root 及其他的檔案系統。(就相當於 DOS 底下的 format 程式啦!)
badblocks
這個程式去搜尋磁碟並檢查區塊是否已經損壞,它通常會在新的檔案系統安裝程式前執行,但請不要在掛載好的檔案系統上執行。 在Linux檔案系統中最新的版本被稱為ext3,並已有 Journaling 之支援。Journaling 檔案系統對於所有已完成的步驟,持有記錄以及檢查點,所以假使系統當機時,它可以從最後的檢查點來還原檔案系統。
附錄二:為何選擇 ext3 呢
在最新的 Red Hat 7.2 當中,已經捨棄了 ext2 而改用支援 Journaling 的 ext3 這一個檔案格式了,那麼這兩個咚咚有什麼不一樣的呢?!底下有一篇翻譯過的文章,看看吧!
Red Hat Linux 7.2 為何決定採用ext3檔案系統?
Red Hat決定在7.2版中使用ext3的格式來作為預設的檔案系統在,引起相當多熟悉Linux使用者的關注,但ext3並不是唯一的,也不是眾多日誌式 (journaling)檔案系統中最佳的。
傳統的Linux檔案系統ext2,對於在相當小容量的硬碟上之小檔案而言是相當的理想。隨著硬碟的容量及檔案大小大幅增加,整體性能會下滑。有些原因是來自讀取未有效利用的磁碟空間,有些原因是來自不正常關機或是電源中斷檔案系統的恢復時間。檔案系統經由e2fsck在一個1GB的硬碟做檢查是毫不費力的,但相同的測試在40GB的硬碟上可能會相當的秏費時間。所以就有日誌式檔案系統的誕生。
這些記錄硬碟狀態的檔案稱為日誌。所以在不正確關機之後重新啟動需要參考到日誌檔案來重新回復檔案系統的狀態,而非將整個硬碟做掃描。同時,日誌式檔案系統可以有更高的硬碟空間使用效率及使資料在各種不同之檔案大小中能夠快速的讀取及寫入。
Linux並不是只有一個日誌式的檔案系統,它有四個,或是說成三又二分之一個:
Reiser檔案系統: 依照Hans Reiser的名字而取。Reiser是眾所皆知的一種新式快速記錄硬碟內容的檔案系統,它曾經被廣泛的使用超過一年,且這個檔案系統被推薦安裝在 SuSE7.1版及7.2版上。
JFS檔案系統:經 由IBM所開發的,其設計的理念在於提供一高速的處理能力。IBM從2000年2月間開始經過一系列的測試版本,它的1.0版本已在六月底公開發表。
XFS檔案系統:XFS 是SGI公司在Linux上所開發的日誌式檔案系統,它也提供了所有以完整發展為特色的日誌式檔案系統。
ext3檔案系統:ext3 是之前所提及的二分之一日誌式檔案系統。為何只有一半呢?原因是ext3是一種疊在傳統ext2檔案系統上面並保有磁碟活動紀錄的日誌式檔案系統。所以當不正確關機時,檔案的恢復速度會比ext2檔案系統來的快。但是,因為它是被結合在ext2中,它會遭受到一些老舊系統的限制並因此不能利用所有日誌式檔案系統的完整功能。這樣並非是完全不好,因為ext3分割區並沒有不同於ext2檔案系統,因此如ext3損毀要回到ext2檔案系統卻是非常的簡單。 Red Hat是第一個採用ext3的公司,它嘗試性的將Linux檔案系統推向日誌式檔案系統。當公司計畫在7.2版的第二個測試版本採用ext3時,公司中首席核心開發者Michael K. Johnson便迅速的提供一個原理的闡述:
“為什麼你想要從ext2轉換到ext3呢?有四個主要的理由:可利用性、資料完整性、速度及易於轉換”。可利用性,他指出,這意味著從系統中止到快速重新復原而不是持續的讓e2fsck執行長時間的修復。ext3的日誌式條件可以避免資料毀損的可能。他也指出”除了寫入若干資料超過一次時,ext3往往會較快於ext2,因為ext3的日誌使硬碟讀取頭的移動能更有效的進行“。然而或許決定的因素還是在Johnson先生的第四個理由中。
“它是可以輕易的從ext2變更到ext3來獲得一個強而有力的日誌式檔案系統而不需要重新做格式化”他說道。”那是正確的,為了體驗一下ext3的好處是不需要去做一種長時間的,冗長乏味的且易於產生錯誤的備份工作及重新格式化的動作”。