天天看點

Linux ext2, ext3, ext4 檔案系統解讀[4]



ext2 ext3 ext4 檔案系統的差別:

ext2為非日志檔案系統,即在檔案系統的運作期間不會記錄寫操作的日志,這就有一個很大的弊端,即檔案系統隻能單純依靠Inode和Data Block的Bitmap來确定資料寫入的狀态。

我們先來了解一下寫入資料的一些具體的步驟:

  1. 當使用者嘗試寫入一個檔案時,首先系統判斷目前使用者對于這個檔案嘗試寫入的目錄是否有寫權限,如果有權限的話才允許寫入。
  2. 檔案系統根據Inode Bitmap找到第一個未使用的Inode,得到Inode的編号,将檔案權限和屬性寫入Inode結構中。
  3. 檔案系統根據Data Block Bitmap找到未使用的Data Block,将檔案内容寫入其中,并将Inode中的Data Block指針指向Data Block,如果一塊Data Block不足以存放檔案内容,就再找下一塊Data Block,如果直接塊不足以存放内容,就在間接塊中進一步配置設定空間。
  4. Data Block資料寫完并且Inode中的指針更新完成後,會更新Inode Bitmap和Data Block Bitmap,将占用的Inode和Data Block對應的比特标記為0(使用中)。
  5. 最後會更新Super Block的内容(更新空閑和使用的數量)。

資料不一緻:

通常我們将Inode和Data Block中的資料稱為資料部分,将Super Block/Inode Bitmap/Data Block Bitmap稱為中繼資料(Metadata)。從上面資料寫入的過程可以很容易看到問題,如果在意外情況下(例如掉電,Kernel Crash,讀寫異常等等),資料寫入成功,但是中繼資料沒有完成寫入,這時就會出現中繼資料與實際資料不一緻的情況。當出現這種不一緻的情況時,可以通過檔案系統自檢來針對資料一緻性進行檢查(fsck),一緻性檢查要周遊整個檔案系統,根據中繼資料中的标志位來與實際資料存放進行對比,如果檔案數量和大小很多,那麼整個過程的耗時就會非常長。

為了克服上述的問題,在ext3中引入了日志功能,ext3檔案系統由ext2發展而來(二者的Magic Number都是一樣的,可見其相容性),ext3檔案系統本身的資料結構(例如Super Block,Inode,Group Descriptor,Dir Entry等)基本與ext2一緻,可以完全相容ext2檔案系統,使得使用者可以平滑地過度到一個帶有日志功能的檔案系統中。

引入日志功能後,檔案系統會劃分出部分Block用于日志的寫入,當進行檔案寫入時,系統首先會把待寫的Block資料寫入日志中,當資料成功送出到日志中後,會進一步向檔案系統的Data Block中送出,資料成功送出到檔案系統後,日志中的臨時資料就會被丢棄。

當出現系統故障,通過fsck進行一緻性檢查和恢複的時候,會存在以下兩種情況:

  1. 資料在送出到日志之前發生系統故障,此時資料還沒有向檔案系統中寫入,fsck會直接忽略這次送出的内容,保證中繼資料和資料的一緻性,但是此次寫入的資料就丢失了。
  2. 資料送出到日志之後,尚未完全寫入檔案系統之前,發生系統故障,此時在進行fsck的時候,會重新将日志中的臨時寫入資料送出到檔案系統中,保證資料一緻性,同時此次寫入操作能夠正常完成。

從上面的兩種情況可以看到,引入日志系統後,能夠保證資料一緻性,但是并不能保證資料不丢失。

ext3支援三種日志模式,差別是寫入日志的Block是中繼資料的Block還是Data Block,以及何日送出日志:

  1. Journal:檔案系統所有資料和中繼資料的改變都要送出到日志,這種模式下會減少所有Block丢失資料以及資料不一緻的可能性,但是會有相當大的磁盤空間被日志Block占用,當一個檔案被建立時,所有的Data Block在送出前都會送出到日志,相當于所有資料寫入都執行了兩次(一次對日志,一次對檔案系統本身),是以這是最安全但是最慢的日志模式。
  2. Ordered:隻有對中繼資料的改變才會送出到日志,這種模式下能夠確定資料一緻性,但是對于檔案内容的可靠性不做保證。盡管這種情況下并不保證檔案内容,但是在中繼資料修改之前,會先送出檔案内容,然後再送出中繼資料對應的Block到日志,最後再送出到檔案系統。這個模式會對檔案系統的性能有少量影響。Ordered模式是ext3檔案系統的預設日志模式。
  3. Writeback:隻有對中繼資料的改變才會送出到日志,但是和Ordered模式不同的是,這個模式下檔案資料送出後和中繼資料的更新可以異步進行,由于中繼資料的更新不會等檔案資料送出後進行,是以很有可能出現中繼資料更新已經完成,但是檔案資料還沒有完成送出,造成資料不一緻的情況。

上面三種日志模式,可以在手動mount的時候通過-o參數指定,也可以在/etc/fstab中指定,例如:

[[email protected] daniel]# mount -o data=writeback /dev/sde1 /mnt/sde

[[email protected] daniel]# mount -v

/dev/sda1 on / type ext4 (rw)

proc on /proc type proc (rw)

sysfs on /sys type sysfs (rw)

devpts on /dev/pts type devpts (rw,gid=5,mode=620)

tmpfs on /dev/shm type tmpfs (rw)

none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)

/dev/sdb1 on /mnt/resource type ext4 (rw)

/dev/sdd1 on /mnt/sdd type ext4 (rw)

/dev/sdc1 on /mnt/sdc type ext2 (rw)

/dev/sde1 on /mnt/sde type ext3 (rw,data=writeback)

# /etc/fstab

# Created by anaconda on Tue Mar 29 17:12:12 2016

#

# Accessible filesystems, by reference, are maintained under '/dev/disk'

# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

#

UUID=8fc4d768-29cd-462c-a7ab-5bf4bcfa9fa2 /     ext4    defaults        1 1

tmpfs                   /dev/shm                tmpfs   defaults        0 0

devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

sysfs                   /sys                    sysfs   defaults        0 0

proc                    /proc                   proc    defaults        0 0

/dev/sde1               /mnt/sde                ext3    data=writeback  0 0

ext3日志可以存儲到一個檔案中,也可以存放在單獨的裝置中,可以在建立檔案系統的時候,指定将日志記錄到其他裝置上,例如:

[[email protected] daniel]# mkfs.ext3 -J device=/dev/sdf1 /dev/sdc1

檔案系統本身并不處理日志,而是通過日志塊裝置(Journaling Block Device,JBD)的通用核心層進行處理。

ext3檔案系統與JBD的互動過程主要基于三個單元:

  1. 日志記錄:用于描述檔案系統的一次低級操作,在某些日志系統中,日志記錄隻包括操作所修改的資料範圍以及起始位置。JBD使用的日志記錄由一次低級操作所包含的資料緩沖區組成,JBD直接對緩沖區和其首部操作。
  2. 原子操作(Atomic handle):一個原子操作是指發生在一次檔案系統的進階更新内的所有低級操作,一個原子操作保證在對應的日志送出後才會将資料向檔案系統中送出。當系統故障時,檔案系統確定原子操作要麼送出成功,要麼所有該原子操作對應的低級操作都復原。
  3. 事務(Transaction):處于管理的友善以及性能考慮,JBD将一組原子操作合并為一個事務,每隔一段時間會将日志中的内容同步到檔案系統中,或者當日志空間中沒有多餘的可寫空間時,事務的日志會同步到檔案系統中。事務會在多個狀态之間切換:

運作(Running):表示事務可以接收和處理更多的原子操作

鎖定(Locked):不接收新的原子操作,所有已接受的原子操作尚未完成

同步(Flush):事務已完成,正在向送出日志

送出(Commit):日志送出完成,正在向檔案系統送出資料

完成(Finished):資料已經全部送出到檔案系統中,可以删除此事務

ext3日志檔案系統的幾個特點:

  1. 高可用性:即使是系統故障之後,也不需要進行檔案系統自檢,通常恢複的過程非常短。
  2. 資料完整性:能夠極大提高資料一緻性,保證檔案系統的完整性,減少系統故障對檔案系統的破壞。
  3. 通路速度:盡管ext3檔案系統啟用了日志功能後,會增加寫入磁盤的次數,但是從整體上來看,ext3仍然比ext2性能要好一些,這是因為ext3的日志功能對磁盤驅動器的讀寫頭進行了一些優化,是以從讀寫性能上看,ext3較ext2并沒有降低。
  4. 資料轉換:ext2檔案系統不需要重新格式化,可以通過tune2fs直接将ext2檔案系統轉換為ext3,例如:

[[email protected] daniel]# mount -v

/dev/sdc1 on /mnt/sdc type ext2 (rw)

[[email protected] daniel]# umount /dev/sdc1

[[email protected] daniel]# tune2fs -j /dev/sdc1

tune2fs 1.41.12 (17-May-2010)

Creating journal inode: done

This filesystem will be automatically checked every 31 mounts or

180 days, whichever comes first.  Use tune2fs -c or -i to override.

[[email protected] daniel]# mount /dev/sdc1 /mnt/sdc

[[email protected] daniel]# mount -v

/dev/sdc1 on /mnt/sdc type ext3 (rw)

也可以在不修改ext3檔案系統的前提下,直接将其重新挂載為ext2檔案系統。

  1. 日志模式:ext3的三種不同的日志模式可以讓系統管理者根據實際情況在速度和穩定性之間進行靈活配置。

ext4檔案系統:

ext4檔案系統是ext3的改進版,從前面的描述中我們可以看到,ext3僅僅是在ext2檔案系統上增加了一個日志功能而已,而ext4則針對ext2/ext3的重要資料結構進行了調整優化,使其可以提供更好的性能和穩定性,以及更為豐富的功能。

與ext2轉換為ext3一樣,無需重新格式化,就可以将ext3檔案系統更新為ext4,原有ext3的資料結構依然保留,ext4作用與新的資料。例如:

[[email protected] daniel]# umount /dev/sdc1

[[email protected] daniel]# tune2fs -O extents,uninit_bg,dir_index /dev/sdc1

tune2fs 1.41.12 (17-May-2010)

Please run e2fsck on the filesystem.

[[email protected] daniel]# fsck /dev/sdc1

......

Group descriptor 8181 checksum is invalid.  FIXED.

Group descriptor 8182 checksum is invalid.  FIXED.

Group descriptor 8183 checksum is invalid.  FIXED.

/dev/sdc1 contains a file system with errors, check forced.

Pass 1: Checking inodes, blocks, and sizes

Pass 2: Checking directory structure

Pass 3: Checking directory connectivity

Pass 4: Checking reference counts

Pass 5: Checking group summary information

/dev/sdc1: 23/1047552 files (0.0% non-contiguous), 134133/268173037 blocks

[[email protected] daniel]# mount /dev/sdc1 /mnt/sdc

[[email protected] daniel]# mount -v

/dev/sdc1 on /mnt/sdc type ext4 (rw)

與ext3相比,ext4有如下新的特性:

  1. 支援更大的檔案系統總大小和更大的單個檔案大小,ext4支援的最大檔案系統大小為1EB,最大16TB的單個檔案。
  2. 支援無限數量的子目錄,ext3目前最多支援32000個子目錄。
  3. ext3采用間接塊映射,當檔案大小非常大的時候,通過二級和三級間接塊查找檔案内容效率極低,與之相比,ext4中引入了extents的概念,每個extent為一組連續資料塊,一個大檔案會被分解儲存在多個extents中,進而大大提高了大檔案的通路效率,減少碎片檔案。
  4. 當檔案寫入ext3檔案系統時,檔案系統的資料塊配置設定器每次隻能配置設定一個Block,而ext4檔案系統可以一次調配多個Block,減少在寫入檔案時Block的調配次數。
  5. ext3的塊配置設定政策是盡快配置設定,而ext4則盡可能地延遲配置設定,直到檔案在緩存中寫完才開始進行資料塊的配置設定,這樣能夠極大地優化資料塊的分布,進而提高後續檔案讀取的性能。
  6. 對于ext4檔案系統來說,系統會維護一個未使用的Inode的表,當進行磁盤自檢的時候,會跳過這個表中的Inode,隻檢查使用中的Inode,而對ext3檔案系統fsck則會逐個檢查Inode,這個機制使得ext4的自檢速度要比ext3快很多。不過需要注意的是,這個Inode表并不是由ext4檔案系統維護的,而是由fsck來維護的,是以首先需要執行過一次fsck,才能夠在下次fsck的時候得到速度上的優化。
  7. 日志功能對于檔案系統而言至關重要,如果日志本身出現問題,而恰好我們又使用這個異常的日志來進行檔案系統的恢複的話,那麼會導緻檔案系統更嚴重的錯誤。是以,在ext4檔案系統中,加入了日志資料校驗的功能,能夠及時發現日志中潛在的錯誤。同時,ext4中還将ext3中的日志送出和檔案系統資料的送出合并到一起,進而進一步提升約20%左右的性能。
  8. 磁盤碎片的産生在所難免,ext4支援線上碎片整理,在整理時能夠保證檔案的正常通路。
  9. ext4将Inode的預設大小改為256位元組,增加的空間用來存放更多的節點資訊和擴充屬性(例如納秒時間戳,Inode版本等等),以提升檔案的通路速度。節點預留機制:當一個目錄被建立時,若幹個Inode會被預留出來,以加速檔案的建立。
  10. 很多軟體為了保證下載下傳檔案有足夠的空間來存放,通常會提前建立一個與下載下傳檔案大小相同的空檔案,ext4檔案系統中實作了與非陪的機制并提供了相應的API。
  11. 預設啟用barrier,以保證資料完整性。

繼續閱讀