天天看點

Linux核心之IO3:檔案系統一緻性

1 掉電與檔案系統一緻性

由上一節檔案系統的布局分析可知,當操作一個檔案時,比如往/a目錄下添加一個b,即添加/a/b檔案,需要修改inode bitmap, inode table, block bitmap, data block。

Linux核心之IO3:檔案系統一緻性

這一系列的操作是非原子的,假如任何一個環節掉電,造成某些步驟丢失,就會造成資料的不完整,檔案将無法正常通路。

2 append一個檔案的全流程

Linux核心之IO3:檔案系統一緻性

而硬體是不可能原子執行的,是以會造成不一緻性。

Linux核心之IO3:檔案系統一緻性

3 模拟檔案系統不一緻性案例

(1) 做一個image,用來模拟磁盤

dd if=/dev/zero of=image bs=1024 count=4096      

(2).格式化為ext4檔案系統

mkfs.ext4 -b 4096 image      

(3).mount到test目錄,寫入一個ok.txt檔案

sudo mount -o loop image test/
cd test/
sudo touch ok.txt
cd ..
sudo umount test      

(4).檢視磁盤詳細資訊

(base) leon\@pc:\~/io\$ dumpe2fs image
dumpe2fs 1.42.13 (17-May-2015)
Filesystem volume name:  <none>
Last mounted on:     /home/leon/io/test
Filesystem UUID:     759835e3-9508-4c57-b511-9c4f7e13f0ad
Filesystem magic number: 0xEF53
Filesystem revision #:  1 (dynamic)

…

Inode count:       1024
Block count:       1024
Reserved block count:   51
Free blocks:       982
Free inodes:       1012
First block:       0
Block size:        4096
Fragment size:      4096
Blocks per group:     32768
Fragments per group:   32768
Inodes per group:     1024

…

First inode:       11
Inode size:        128
Default directory hash:  half_md4
Directory Hash Seed:   9cf91d57-8528-4d39-b6ba-5f8e2e86fcb7
Group 0: (Blocks 0-1023) [ITABLE_ZEROED]
Checksum 0x240a, unused inodes 1012
主 superblock at 0, Group descriptors at 1-1
Block bitmap at 2 (+2), Inode bitmap at 18 (+18)
Inode表位于 34-65 (+34)
982 free blocks, 1012 free inodes, 2 directories, 1012個未使用的inodes
可用塊數: 8-17, 19-33, 67-1023
可用inode數: 13-1024

(base)      

可以看到inode bitmap在18個塊。

(5).檢視inodebitmap塊

dd if=image bs=4096 skip=18 |      
Linux核心之IO3:檔案系統一緻性

由于ext4預設用掉11個inode,新建立的ok.txt檔案後,inode bitmap用掉12位。

(6).現在模拟掉電,修改inode bitmap

vim -b image

:%!xxd –g 1

:%!xxd –r      

找到inode bitmap塊對應位址4096*18=0x12000

Linux核心之IO3:檔案系統一緻性

将bitmap改為ff 07

Linux核心之IO3:檔案系統一緻性
Linux核心之IO3:檔案系統一緻性

(7).重新mount通路,檢視出錯資訊

(base) leon@pc:~/io/test$ sudo touch bad.txt

touch: 無法建立'bad.txt': 輸入/輸出錯誤

(base) leon@pc:~/io/test$ dmesg      
Linux核心之IO3:檔案系統一緻性

掉電導緻的不一緻性,會出現各種奇怪的問題,甚至都無法修複;

任何軟體的手段隻能保持一緻性,無法保證不丢失資料。

Linux核心之IO3:檔案系統一緻性

4 fsck

人為破壞data block,用fsck修複

Linux核心之IO3:檔案系統一緻性

修複原理,掃描bitmap和inode table的一緻性。

早期Linux/Windows系統異常掉電後啟動,都用fsck修複磁盤,速度很慢。

為提高速度,新系統都采用日志系統方式。

5 檔案系統的日志

将要修改的行為,記錄為一個日志,若操作磁盤過程掉電,開機根據日志回放,将磁盤操作全部重做一遍。磁盤操作完成,删除日志。

優點:保持檔案系統的一緻性,也提高速度。

EXT2/3/4都采用日志系統。

日志的幾個階段:

1.開始寫日志

2.日志區寫完日志,commited;

3.執行完一條日志,磁盤操作完成,checkpoint。

4.操作完成,free日志。

Linux核心之IO3:檔案系統一緻性

完整的日志方式,相當于每個資料都寫了兩遍,讓系統變很慢,實際工程上會根據資料情況,做部分日志,即日志方式分為三種:速度遞增,安全性遞減

data=journal: 完整日志;

data = ordered: 隻寫中繼資料,且先寫完資料塊,再寫中繼資料

data=writeback 隻寫中繼資料,循序不确定;ubuntu預設方式;

這樣日志就分為5個階段:

Linux核心之IO3:檔案系統一緻性

6 檔案系統的調試工具

建立一個檔案t.txt,df –h

(base) leon@pc:~/io$ **sudo debugfs -R 'stat /home/leon/io/t.txt' /dev/sda7**

sudo: 無法解析主機:pc: 連接配接逾時
debugfs 1.42.13 (17-May-2015)
Inode: 13896517  Type: regular  Mode: 0664  Flags: 0x80000
Generation: 507799365  Version: 0x00000000:00000001
User: 1000  Group: 1000  Size: 17
File ACL: 0  Directory ACL: 0
Links: 1  Blockcount: 8
Fragment: Address: 0  Number: 0  Size: 0
ctime: 0x5f40e439:2182bba0 -- Sat Aug 22 17:24:09 2020
atime: 0x5f40e43b:c9589800 -- Sat Aug 22 17:24:11 2020
mtime: 0x5f40e439:2182bba0 -- Sat Aug 22 17:24:09 2020
crtime: 0x5f40e439:208e98b8 -- Sat Aug 22 17:24:09 2020
Size of extra inode fields: 32
EXTENTS:
(0):55636171
(END)      

得到檔案的資料塊55636171

檢視資料塊内容

sudo      
Linux核心之IO3:檔案系統一緻性
sudo dd if=/dev/sda of=1 skip=$((55636171*8+824123392)) bs=512c count=1      
Linux核心之IO3:檔案系統一緻性

debugfs 根據塊号查inode号

sudo debugfs -R 'icheck 55636171'      

根據inode号,查檔案路徑

sudo debugfs -R 'ncheck 13896517'      
Linux核心之IO3:檔案系統一緻性

7 Copy On Write檔案系統: btrfs

不用日志,實作檔案系統一緻性。每次寫磁盤時,先将更新資料寫入一個新的block,當新資料寫入成功之後,再更新相關的資料結構指向新block。

Linux核心之IO3:檔案系統一緻性