學習筆記:CentOS7學習之十四:linux文件系統



本文用於記錄學習體會、心得,兼做筆記使用,方便以后復習總結。內容基本完全參考學神教育教材,圖片大多取材自學神教育資料,在此非常感謝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尋址方式。

CHS結構體系

如上圖所示的磁盤,每個磁道的扇區都一樣,這樣外磁道整個弧長要大於內部的扇區弧長,因而其磁記錄密度就要比內部磁道的密度要小。最終,導致了外部磁道的空間浪費。

Zoned-bit recording(ZBR 區位記錄)是一種物理優化硬盤存儲空間的方法,此方法通過將更多的扇區放到磁盤的外部磁道而獲取更多存儲空間。即磁盤內部磁道的扇區少,外部刺刀的扇區多,充分利用的磁道空間。

ZBR磁盤扇區結構示意圖

ZBR磁盤扇區結構示意圖

由於單位時間內,光盤內圈和外圈旋轉的角度一樣,所以外圈旋轉的磁道更長,訪問的扇區更多,因此數據存放的位置越靠外面,訪問速度越快。一般機械磁盤的0扇區都是從最外面開始,越往磁盤內部扇區號越大,訪問速度越慢。

使用ZBR 區位記錄法做的磁盤有以下特點:讀外圈的數據快,讀內圈的數據慢,所以測試硬盤經常看到讀取速度越來越慢的曲線圖就很正常了。

ZBR磁盤外圈磁道和內圈磁道扇區比較

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系統特有的現象。

  1. 有時,文件名包含特殊字符,無法正常刪除。這時,直接刪除inode節點,就能起到刪除文件的作用。

  2. 移動文件或重命名文件,只是改變文件名,不影響inode號碼。

  3. 打開一個文件以后,系統就以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 實戰:修復服務器文件系統

實戰場景:公司服務器突然斷電后,再次啟動后,報如下錯誤。

linux文件系統修復

根據提示輸入CTRL+D或者輸入ROOT密碼
解決方法:
輸入root 密碼
fsck -f -y /dev/sda1 #把引導分區文件系統修復一下,舉例引導分區在/dev/sda1下,需要確認自己的引導分區
fsck -f -y /dev/sda3 #把根分區文件系統修復一下 ,需要提前確認自己的根分區掛在在那個盤
reboot 重啟
fsck參數:
-y 對所有問題都回答 "yes"
-f 即使文件系統標記為 clean 也強制進行檢查


---END---
2019-5-10 1:19:28


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM