本文用於記錄學習體會、心得,兼做筆記使用,方便以后復習總結。內容基本完全參考學神教育教材,圖片大多取材自學神教育資料,在此非常感謝MK老師和學神教育的優質教學。希望各位因學習需求而要進行轉載時,能申明出處為學神教育,謝謝各位!
1、 機械硬盤結構
1.1 機械硬盤結構
機械硬盤截圖如下圖所示:
- 空氣過濾片
- 主軸(馬達電機與軸承在其下方)
- 音圈馬達
- 永磁鐵
- 磁盤:Magnetic arm
- 磁頭:Magnetic head
- 磁頭臂
磁盤內部不是真空,只不過里面的空氣很干凈。如果是真空,還不利於散熱。
硬盤的內部是金屬盤片,將圓形的盤片划分成若干個扇形區域,這就是扇區sector。若干個扇區就組成整個盤片。為什么要分扇區?是邏輯化數據的需要,能更好的管理硬盤空間。 以盤片中心為圓心,把盤片分成若干個同心圓,那每一個划分圓的“線條”,就稱為磁道track。
硬盤內的盤片有兩個面,都可以儲存數據,而硬盤內的盤片往往不止一張,常見的有兩張,那么,兩張盤片中相同位置的磁道,就組成一個“柱面”,盤片中有多少個磁道,就有多少個柱面。盤片兩面都能存數據,要讀取它,必須有磁頭,所以,每一個面,都有一個磁頭,一張盤片就有兩個磁頭。
硬盤的存儲容量=磁頭數×磁道(柱面)數×每道扇區數×每道扇區字節數。
磁道從外向內自0開始順序進行編號,各個磁道上的扇區數是在硬盤格式化時確定的。
文件儲存在硬盤上,硬盤的最小存儲單位叫做"扇區"(Sector)。每個扇區儲存512字節(相當於0.5KB)。
比較古老的CHS (Cylinder/Head/Sector :磁頭(Heads)、柱面(Cylinder)、扇區(Sector))結構體系. 因為很久以前,在硬盤的容量還非常小的時候,人們采用與軟盤類似的結構生產硬盤。也就是硬盤盤片的每一條磁道都具有相同的扇區數,由此產生了所謂的3D參數,即是磁頭數(Heads)、柱面數(Cylinders)、扇區數(Sectors)以及相應的3D尋址方式。
如上圖所示的磁盤,每個磁道的扇區都一樣,這樣外磁道整個弧長要大於內部的扇區弧長,因而其磁記錄密度就要比內部磁道的密度要小。最終,導致了外部磁道的空間浪費。
Zoned-bit recording(ZBR 區位記錄)是一種物理優化硬盤存儲空間的方法,此方法通過將更多的扇區放到磁盤的外部磁道而獲取更多存儲空間。即磁盤內部磁道的扇區少,外部刺刀的扇區多,充分利用的磁道空間。
ZBR磁盤扇區結構示意圖
由於單位時間內,光盤內圈和外圈旋轉的角度一樣,所以外圈旋轉的磁道更長,訪問的扇區更多,因此數據存放的位置越靠外面,訪問速度越快。一般機械磁盤的0扇區都是從最外面開始,越往磁盤內部扇區號越大,訪問速度越慢。
使用ZBR 區位記錄法做的磁盤有以下特點:讀外圈的數據快,讀內圈的數據慢,所以測試硬盤經常看到讀取速度越來越慢的曲線圖就很正常了。
磁盤寫數據時,先從外面往里。所以windows系統盤和linux系統分區boot的都是在最外面的磁道
windows : C盤安裝最外,速度也是最快
Linux : boot分區和 swap分區,裝最外面
1.2 簇和block
windows中的簇類似於Linux系統中的block
例:在win10系統,新一個文本文件“新建文本文檔.txt”,只輸入aa兩個字符。
右擊屬性查看大小: 說明我的NTFS文件系統中默認的簇大小為4KB
[root@linuxprobe ~]# stat /etc/passwd ##查看linux中block的大小
文件:"/etc/passwd"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:37107837硬鏈接:1
權限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
環境:system_u:object_r:passwd_file_t:s0
最近訪問:2019-05-09 22:37:00.968000146 +0800
最近更改:2019-04-30 10:58:57.840068859 +0800
最近改動:2019-04-30 10:58:57.842068859 +0800
創建時間:-
IO 塊:4096 說明系統的block是4096大小。
2、文件系統結構
linux文件系統由三部分組成:文件名、inode,block
linux文件系統格式: ext3、ext4、xfs
windows文件系統格式: FAT32、NTFS
2.1 文件名
[root@linuxprobe ~]# cp /etc/passwd ./a.txt
[root@linuxprobe ~]# ll a.txt
-rw-r--r--. 1 root root 3379 5月 9 23:46 a.txt
此處的a.txt即為文件名
2.2 inode的內容
inode包含文件的元信息,具體來說有以下內容:
- 文件的字節數
- 文件擁有者的User ID
- 文件的Group ID
- 文件的讀、寫、執行權限
- 文件的時間戳,共有三個:ctime指inode上一次變動的時間,mtime指文件內容上一次變動的時間,atime指文件上一次打開的時間。
- 鏈接數,即有多少文件名指向這個inode
- 文件數據block的位置
可以用stat命令,查看某個文件的inode信息:
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:67146853硬鏈接:1
權限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2019-05-09 23:46:22.991072117 +0800 ##access time
最近更改:2019-05-09 23:46:22.991072117 +0800 ##modify time
最近改動:2019-05-09 23:46:22.991072117 +0800 ##change time
創建時間:-
atime : access time 訪問文件內容的時間。對文件進行一次讀操作,它的訪問時間就會改變。例如像:cat、more等操作,但是像之前的stat還有ls命令對atime是不會有影響的。比如:cat a.txt
mtime : modify time 修改文件內容的時間。文件的內容被最后一次修改的時間,我們經常用的ls -l命令顯示出來的文件時間就是這個時間,當用vim對文件進行編輯之后保存,它的mtime就會相應的改變;比如:如:echo aa >> a.sh 或vim a.txt 修改內容
ctime : change time 指inode上一次文件屬性變動的時間。當文件的狀態被改變的時候,狀態時間就會隨之改變,例如當使用chmod、chown等改變文件屬性的操作是會改變文件的ctime的。chmod +x a.txt
[root@linuxprobe ~]# ll a.txt
-rw-r--r--. 1 root root 3379 5月 9 23:46 a.txt
舉例
1)使用cat命令查看文件后,文件atime變更
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:67146853硬鏈接:1
權限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2019-05-09 23:46:22.991072117 +0800
最近更改:2019-05-09 23:46:22.991072117 +0800
最近改動:2019-05-09 23:46:22.991072117 +0800
創建時間:-
[root@linuxprobe ~]# cat a.txt
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:67146853硬鏈接:1
權限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2019-05-10 00:00:28.391086736 +0800 #使用cat查看文件后指揮變更atime
最近更改:2019-05-09 23:46:22.991072117 +0800
最近改動:2019-05-09 23:46:22.991072117 +0800
創建時間:-
2)使用vim命令寫文件w后,文件atime、mtime、ctime都會變更。如果只是查看沒有寫的話,只會變更atime。
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:67146862硬鏈接:1
權限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2019-05-10 00:03:57.313090348 +0800
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改動:2019-05-10 00:03:57.349090349 +0800
創建時間:-
[root@linuxprobe ~]# vim a.txt
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:67146862硬鏈接:1
權限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2019-05-10 00:04:42.803091135 +0800 ##不進行寫操作,只會變更atime
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改動:2019-05-10 00:03:57.349090349 +0800
創建時間:-
3)使用chmod命令后,文件ctime會變更
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:67146862硬鏈接:1
權限:(0644/-rw-r--r--) Uid:(0/root) Gid:(0/root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2019-05-10 00:04:42.803091135 +0800
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改動:2019-05-10 00:03:57.349090349 +0800
創建時間:-
[root@linuxprobe ~]# chmod +x a.txt
[root@linuxprobe ~]# stat a.txt
文件:"a.txt"
大小:3379 塊:8 IO 塊:4096 普通文件
設備:fd00h/64768d Inode:67146862硬鏈接:1
權限:(0755/-rwxr-xr-x) Uid:(0/root) Gid:(0/root)
環境:unconfined_u:object_r:admin_home_t:s0
最近訪問:2019-05-10 00:04:42.803091135 +0800
最近更改:2019-05-10 00:03:57.313090348 +0800
最近改動:2019-05-10 00:07:55.227094462 +0800 ##ctime變更
創建時間:-
2.3 inode的大小
inode也會消耗硬盤空間,所以硬盤格式化的時候,操作系統自動將硬盤分成兩個區域。一個是數據區,存放文件數據;另一個是inode區(inode table),存放inode所包含的信息。
每個inode節點的大小,一般是128字節或256字節。inode節點的總數,在格式化時就給定,假定在一塊1GB的硬盤中,每個inode節點的大小為128字節,每1KB就設置一個inode,那么inode table的大小就會達到128MB,占整塊硬盤的12.8%。
inode號:每個inode都有一個號碼,操作系統用inode號碼來識別不同的文件,Unix/Linux系統內部不使用文件名,而使用inode號碼來識別文件。對於系統來說,文件名只是inode號碼便於識別的別稱或者綽號。表面上,用戶通過文件名,打開文件。實際上,系統內部這個過程分成三步:首先,系統找到這個文件名對應的inode號碼;其次,通過inode號碼,獲取inode信息;最后,根據inode信息,找到文件數據所在的block,讀出數據。
例1: 使用ls -i命令,可以看到文件名對應的inode號碼
[root@linuxprobe ~]# ls -i a.txt
67146862 a.txt
例2:查看每個硬盤分區的inode總數和已經使用的數量,可以使用df -i命令。
[root@linuxprobe ~]# df -i
文件系統 Inode 已用(I) 可用(I) 已用(I)% 掛載點
/dev/mapper/centos-root 31453184 375866 31077318 2% /
devtmpfs 478669 417 478252 1% /dev
tmpfs 482939 1 482938 1% /dev/shm
tmpfs 4829391520 481419 1% /run
tmpfs 482939 16 482923 1% /sys/fs/cgroup
/dev/sda1 524288 378 523910 1% /boot
tmpfs 482939 7 482932 1% /run/user/42
tmpfs 482939 21 482918 1% /run/user/1001
/dev/sr0 0 00- /run/media/oracle/CentOS 7 x86_64
注:由於每個文件都必須有一個inode,因此有可能發生inode已經用光,但是硬盤還未存滿的情況。這時,就無法在硬盤上創建新文件
2.4 目錄文件
Unix/Linux系統中,目錄(directory)也是一種文件。打開目錄,實際上就是打開目錄文件。
目錄文件的結構非常簡單,就是一系列目錄項的列表。每個目錄項,由兩部分組成:所包含文件的文件名,以及該文件名對應的inode號碼。
[root@linuxprobe ~]# ls -id /etc
33554497 /etc
2.5 block塊大小
block 是真正存儲數據的地方。
block是 文件系統 中最小的存儲單位
扇區 是 磁盤 中最小的存儲單位
在linux下中叫:block,在windows中叫:簇
操作系統讀取硬盤的時候,不會一個個扇區(512字節)地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取一個"塊"(block)。這種由多個扇區組成的"塊",是文件存取的最小單位。"塊"的大小,最常見的是1KB,即連2個 sector扇區組成一個 block。或4K即8個扇區組成一個“塊”。
例1:格式化修改磁盤,修改簇大小
簇和block調大:
優點: 速度快,節約尋址時間。
缺點:空間浪費
3 文件的硬鏈接和軟鏈接
3.1 linux鏈接概念
Linux鏈接分兩種,一種被稱為硬鏈接(Hard Link),另一種被稱為軟鏈接,即符號鏈接(Symbolic Link)。默認情況下,ln命令產生硬鏈接。
【硬連接】:硬連接指通過索引節點號來進行連接。inode是可以對應多個文件名的
在Linux的文件系統中,保存在磁盤分區中的文件不管是什么類型都給它分配一個編號,稱為索引節點號(Inode Index)。
在Linux中,多個文件名可以指向同一索引節點。一般這種連接就是硬連接。
硬連接的作用是允許一個文件擁有多個有效路徑名,這樣用戶就可以建立硬連接到重要文件,以防止“誤刪”的功能。
只刪除一個連接並不影響索引節點本身和其它的連接,只有當最后一個連接被刪除后,文件的數據塊及目錄的連接才會被釋放。也就是說,文件真正刪除的條件是與之相關的所有硬連接文件均被刪除。
【軟連接】:另外一種連接稱之為符號連接(Symbolic Link),也叫軟連接。軟鏈接文件有類似於Windows的快捷方式。它實際上是一個特殊的文件。在符號連接中,文件實際上是一個文本文件,其中包含的有另一文件的位置信息。
3.2 實戰-1:ln命令創建硬鏈接
語法格式:ln 源文件 目標文件
[root@linuxprobe ~]# touch a.txt
[root@linuxprobe ~]# ln a.txt b.txt ##創建b.txt作為a.txt的硬鏈接
[root@linuxprobe ~]# ll a.txt
-rw-r--r--. 2 root root 0 5月 10 00:41 a.txt
[root@linuxprobe ~]# ll b.txt
-rw-r--r--. 2 root root 0 5月 10 00:41 b.txt ##查看發現a.txt和b.txt文件屬性相同,mtime都一致
[root@linuxprobe ~]# echo 222>>a.txt
[root@linuxprobe ~]# echo 222 > a.txt
[root@linuxprobe ~]# cat a.txt
222
[root@linuxprobe ~]# cat b.txt
222 ##修改a.txt文件后,b.txt文件也同樣被修改
[root@linuxprobe ~]# ls -i a.txt
67146853 a.txt
[root@linuxprobe ~]# ls -i b.txt ##兩個文件的inode一致
67146853 b.txt
[root@linuxprobe ~]# chmod 777 a.txt
[root@linuxprobe ~]# ll a.txt
-rwxrwxrwx. 2 root root 4 5月 10 00:42 a.txt
[root@linuxprobe ~]# ll b.txt
-rwxrwxrwx. 2 root root 4 5月 10 00:42 b.txt ##修改一個文件的權限后,另外一個文件的權限也會修改
硬鏈接的原理就是多個文件名指向同一個inode,因此多個文件名共用一個inode號,達到共享與備份的目的
注意:源文件被刪除,不影響鏈接文件的正常使用
[root@linuxprobe ~]# rm -rf a.txt
[root@linuxprobe ~]# cat b.txt
222
[root@linuxprobe ~]# echo 0000 >> b.txt
[root@linuxprobe ~]# cat b.txt
222
0000
硬鏈接不能針對目錄創建
[root@linuxprobe ~]# ln /etc/ test
ln: "/etc/": 不允許將硬鏈接指向目錄
硬鏈接不能跨分區進行創建
[root@linuxprobe ~]# ln b.txt /boot/bb.txt
ln: 無法創建硬鏈接"/boot/bb.txt" => "b.txt": 無效的跨設備連接
因為每個分區的inode號是獨立的,跨分區的硬鏈接有可能會導致inode沖突,所以不容許跨分區的硬鏈接。
3.3 ln -s 創建軟連接
軟鏈接:相當於windows中的快捷方式
語法:ln -s 源文件 軟鏈接的名字
例1:創建軟連接,然后刪除源文件,鏈接文件能否正常使用。
注:源文件被刪除,鏈接文件失效
例2:能針對目錄和跨分區創建軟鏈接
創建目錄的軟連接
[root@linuxprobe ~]# ll test
總用量 0
lrwxrwxrwx. 1 root root 5 5月 10 01:01 etc -> /etc/ ##創建/etc的軟連接
創建跨分區的軟連接,源文件必須寫絕對路徑
[root@linuxprobe ~]# ln -s /boot/grub/splash.xpm.gz c.txt
[root@linuxprobe ~]# ll c.txt
lrwxrwxrwx. 1 root root 24 5月 10 01:03 c.txt -> /boot/grub/splash.xpm.gz
3.4 inode的特殊作用
由於inode號碼與文件名分離,這種機制導致了一些Unix/Linux系統特有的現象。
-
有時,文件名包含特殊字符,無法正常刪除。這時,直接刪除inode節點,就能起到刪除文件的作用。
-
移動文件或重命名文件,只是改變文件名,不影響inode號碼。
-
打開一個文件以后,系統就以inode號碼來識別這個文件,不再考慮文件名。因此,通常來說,系統無法從inode號碼得知文件名。
互動:為什么每次修改完服務器配置文件后,都需要重新加載一下配置文件?[root@linuxprobe ~]# ls -i a.txt
67146858 a.txt
[root@linuxprobe ~]# vim a.txt
[root@linuxprobe ~]# ls -i a.txt
67146871 a.txt
因為vim每次修改完后,Inode號都會變,系統還是讀取的原來inode號的配置文件,每次修改完服務器的配置文件,都要重啟服務,重新讀一下配置文件。
4、實戰:解決磁盤有空間但創建不了文件-修復服務器文件系統
4.1 解決磁盤有空間但創建不了文件
實戰場景:在一台配置較低的Linux服務器(內存、硬盤比較小)的/data分區內創建文件時,系統提示磁盤空間不足,用df -h命令查看了一下磁盤使用情況,發現/data分區只使用了80%,還有1.9G的剩余空間,但是無法創建新的文件。當時使用的是root用戶。服務器沒有被黑。
[root@xuegod63 ~]# df -h
文件系統 容量已用 可用 已用% 掛載點
/dev/sda310G 8.0G 1.9G 80%/
常識: 只要權限夠,磁盤上有空間一定可以創建文件。 這個是錯的。
排查:
[root@xuegod63 ~]# df -i
文件系統 Inode 已用(I) 可用(I) 已用(I)% 掛載點
/dev/sda3 5242880 52428800 100%/
后來用df -i查看了一下/data所在的分區的索引節點(inode),發現已經用滿(IUsed=100%),導致系統無法創建新目錄和文件。
查找原因:
/data/cache目錄中存在數量非常多的小字節緩存文件,占用的Block不多,但是占用了大量的inode。
解決方案1:刪除/data/cache目錄中的部分文件,釋放出/data分區的一部分inode。
解決方案2 : 在/data備份好一些文件,然后刪除這些文件,釋放一些inode,然后創建一個文件夾/data/cache2。在cache2下掛載一個新分區: sda4 ,下次寫數據需要寫到新分區cache2目錄下。
inode分區完后,不可以增加inode數量,改變inode大小,但是inode總數和inode大小是在格式化時進行修改的。
mkfs.xfs
no device name given in argument list
Usage: mkfs.xfs
/* blocksize */ [-b log=n|size=num]
/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx]
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,
(sunit=value,swidth=value|su=num,sw=num|noalign),
sectlog=n|sectsize=num
/* force overwrite */ [-f]
/* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,
projid32bit=0|1]
/* no discard */ [-K]
/* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n
sunit=value|su=num,sectlog=n|sectsize=num,
lazy-count=0|1]
/* label */ [-L label (maximum 12 characters)]
/* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]
/* no-op info only */ [-N]
/* prototype file */ [-p fname]
/* quiet */ [-q]
/* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]
/* sectorsize */ [-s log=n|size=num]
/* version */ [-V]
devicename
<devicename> is required unless -d name=xxx is given.
<num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),
xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).
<value> is xxx (512 byte blocks).
參數:
[-i bytes-per-inode] 修改inode大小
[-I inode-size] 修改inode數量
4.2 實戰:修復服務器文件系統
實戰場景:公司服務器突然斷電后,再次啟動后,報如下錯誤。
根據提示輸入CTRL+D或者輸入ROOT密碼
解決方法:
輸入root 密碼
fsck -f -y /dev/sda1 #把引導分區文件系統修復一下,舉例引導分區在/dev/sda1下,需要確認自己的引導分區
fsck -f -y /dev/sda3 #把根分區文件系統修復一下 ,需要提前確認自己的根分區掛在在那個盤
reboot 重啟
fsck參數:
-y 對所有問題都回答 "yes"
-f 即使文件系統標記為 clean 也強制進行檢查
2019-5-10 1:19:28