《鳥哥 Linux 私房菜:基礎篇》Chapter 06 - Linux 的檔案與目錄管


  • 第一篇:Linux 的規劃與安裝
  • 第二篇:Linux 檔案、目錄與磁碟格式
    • Chapter 05 Linux 的檔案權限與目錄配置
    • Chapter 06 Linux 的檔案與目錄管理
    • Chapter 07 Linux 磁碟與檔案系統管理
    • Chapter 08 Linux 檔案與檔案系統的壓縮、打包與備份
  • 第三篇:學習 Shell 與 Shell Scripts
  • 第四篇:Linux 使用者管理
  • 第五篇:Linux 系統管理員

7.1 認識 Linux 檔案系統

7.1.1 磁碟組成與分割的複習

整顆磁碟的組成:

  • 圓形的磁碟盤(主要紀錄資料)
  • 機械手臂,與在機械手臂上的磁碟讀取頭(可讀寫磁碟盤上的資料)
  • 主軸馬達,可以轉動磁碟盤,讓機械手臂的讀取頭在磁碟盤上讀寫資料

從上面我們知道,磁碟儲存與讀取主要在磁碟盤,而磁碟盤的物理組成則為

  • 磁區(Sector)為最小的物理儲存單位,且依據磁碟設計不同,目前主要有 512 bytes 與 4K 兩種格式
  • 將磁區組成一個圓,那就是磁柱(Cylinder)
  • 早期的分割主要以磁柱為最小分割單位,現在的分割通常使用磁區為最小分割單位
  • 磁區分割主要有兩種格式
    • 限制較多的 MBR 分割表
    • 較新且限制較少的 GPT 分割表
  • MBR 分割表中,第一個磁區最重要,裡面有
    • (1) 主要開機區(Master boot record, MBR),446 bytes
    • (2) 分割表(Partition table),64 bytes
  • GPT 分割表除了分割數量擴充較多以外,支援的磁碟容量也可以超過 2TB

磁碟檔名:

  • 實體磁碟:/dev/sd[a-p][1-128]
  • 虛擬磁碟:/dev/vd[a-d][1-128]

7.1.2 檔案系統特性

  • 磁碟分割完畢,需要「格式化(format)」,因為每種作業系統所設定的檔案屬性/權限不相同,才能成為作業系統能利用的「檔案系統格式(filesystem)」。
  • Linux 的正統檔案系統為 Ext2(Linux second extended file system, ext2fs)
  • 通常我們稱呼一個可被掛載的資料為一個檔案系統,而不是一個分割槽
  • 較新的作業系統,檔案的資料除了檔案實際內容外,通常還有更多屬性,如 Linux 的檔案權限(rwx)與檔案屬性(擁有者、群組、時間參數等)。檔案系統通常會將這兩部分的資料分別存放在不同的區塊,權限與屬性放置到 inode 中,至於實際資料則放置到 data block 區塊中。每個 inode 與 block 都有編號。
  • 此外,還有一個超級區塊(superblock),紀錄整個檔案系統的整體資訊,包括 inode 與 block 的數量、使用量、剩餘量等。
  • superblock、inode、block 簡易說明:
    • superblock:紀錄此 filesystem 的整體資訊,包括 inode/block 的總量、使用量」剩餘量,以及檔案系統格式與相關資訊。
    • inode:紀錄檔案的屬性,一個檔案佔用一個 inode,同時紀錄此檔案的資料所在的 block 號碼。
    • block:實際紀錄檔案的內容,若檔案太大時,會佔用多個 block。
  • 資料存取方式分成:
    • 索引式檔案系統(indexed allocation):inode 一次讀取全部 block 內容,不太需要磁碟重組。
    • FAT 格式:沒有 inode 存在,無法一口氣讀完全部 block,而是讀完一個 block,再由該 block 讀到下一個 block,如隨身碟(快閃記憶體),缺點是如果 block 分散得太厲害,無法在磁碟轉一圈就讀到所有資料,而會需要「磁碟重組」以提升效能。

7.1.3 Linux 的 Ext2 檔案系統(inode)

  • Linux 檔案系統 Ext2 是以 inode 為基礎的索引式檔案系統。
  • 檔案系統一開始就將 inode 與 block 規劃好了,除非重新格式化(或者利用 resize2fs 等指令變更檔案系統大小),否則 inode 與 block 就不再變動。
  • Ext2 格式化時,區分為多個區塊群組(Block group),每個區塊群組又有獨立的 inode/block/superblock 系統。
    • 檔案系統最前面有個開機磁區(Boot Sector),安裝開機管理程式。
    • 每個區塊群組(Block Group)分成六個主要內容:
      • Data Block(資料區塊)
      • Inode Table(inode 表格)
        • 該檔案的存取模式(rwx)
        • 該檔案的擁有者與群組(owner/group)
        • 該檔案的容量
        • 該檔案建立或狀態改變的時間(ctime)
        • 最近一次的讀取時間(atime)
        • 最近修改的時間(mtime)
        • 定義檔案特性的旗標(flag)
        • 該檔案真正內容的指向(pointer)
      • Superblock(超級區塊)
        • block 與 inode 的總量
        • 未使用與已使用的 inode/block 數量
        • block 與 inode 的大小(block 為 1, 2, 4K,inode 為 128, 256 bytes)
        • filesystem 的掛載時間、最近一次寫入資料的時間、最近一次檢驗磁碟的時間等
        • 一個 valid bit 的數值,若此檔案系統已被掛載,則 valid bit 為 0,若未被掛載,則 valid bit 為 1

7.1.4 與目錄樹的關係

  • 目錄:檔案系統會分配一個 inode 與至少一塊 block 給目錄
  • 檔案:ext2 分配一個 inode 與相對於該檔案大小的 block 數量給該檔案
  • 目錄樹讀取:舉例來說,如果想要讀取 /etc/passwd 檔案,輸入 ll -di / /etc /etc/passwd
    1. / 的 inode:透過掛載點的資訊找到 inode 號碼為 2 的根目錄 inode,且 inode 規範得閒盎讓我們可以讀取該 block 的內容(有 r & x)。
    2. / 的 block:經過上個步驟取得 block 的號碼,並找到該內容有 etc/ 目錄的 inode(128004)。
    3. etc/ 的 inode:讀取 128004 號 inode 得知 sunny(非 root 使用者)有 r & x 權限,因此可以讀取 etc/ 的 block 內容。
    4. etc/ 的 block:經過上個步驟取得 block 的號碼,並找到該內容有 passwd 檔案的 inode 號碼(144144)。
    5. passwd 的 inode:讀取 144144 號 inode 得知 sunny(非 root 使用者)有 r 的權限,因此可以讀取 passwd 的 block 內容。
    6. passwd 的 block:最後將該 block 的資料讀出來。
  • filesystem 大小與磁碟讀取效能:如果檔案寫入的 block 真的分得很散,會有檔案資料離散的問題發生,可以將該 filesystem 重新格式化解決問題。

7.1.5 Ext2/Ext3/Ext4 檔案的存取與日誌式檔案系統的功能

假設我們想要新增一個檔案,此時檔案系統的行為:

  1. 先確定使用者對於欲新增的目錄是否具有 w 與 x 的權限
  2. 根據 inode bitmap 找到沒有使用的 inode 號碼,並將新檔案的權限/屬性寫入
  3. 根據 block bitmap 找到沒有使用的 block 號碼,並將實際的資料寫入 block 中,並更新新 inode 的 block 指向資料
  4. 將該該寫入的 inode 與 block 資料同步更新 inode bitmap 與 block bitmap,並更新 superblock 的內容

一般來說,inode table 與 data block 稱為資料存放區域,superblock、block bitmap 與 inode bitmap 等區段被稱為 metadata(中介資料),因為 superblock、block bitmap 與 inode bitmap 是經常變動的,每次新增、移除、編輯時都有可能會影響到這三部分的資料。

  • 資料不一致狀態(inconsistent):系統突然中斷,導致寫入的資料只有 inode table 及 block table 時,最後一部同步更新資料沒有完成,此時就會發生 metadata 與實際資料不一致的問題。早期 Ext2 會在系統重開機時,藉由 superblock 的 valid bit(是否有掛載)與 filesystem state(clean 與否),來判斷是否進行一致性的檢查,不過這個檢查非常費時,因此衍生出了「日誌式檔案系統」。
  • 日誌式檔案系統(Journaling filesystem):在 filesystem 規劃出一個區塊,該區塊專門紀錄寫入或修訂檔案時的步驟:
    1. 預備:當系統要寫入一個檔案時,會先在日誌紀錄區塊中紀錄某個檔案準備要寫入的資訊。
    2. 實際寫入:開始寫入檔案的權限與資料;開始更新 metadata 的資料。
    3. 結束:完成資料與 metadata 的更新後,在日誌紀錄區塊當中完成該檔案的紀錄。

7.1.6 Linux 檔案系統的運作

由於磁碟寫入的速度要比記憶體慢很多,如果你常常編輯一個很大的檔案,你會耗在等待磁碟寫入/讀取上,因此 Linux 透過非同步處理(asynchronously)。如果記憶體被更改過(例如用 nano 去編輯這個檔案),記憶體中的資料會被設定為髒的(dirty),此時所有的動作都會在記憶體中執行,並沒有寫入到磁碟中,系統會不定時將 Dirty 的資料寫回磁碟以確保一致性。

7.1.7 掛載點的意義(mount point)

  • 將檔案與目錄樹結合的動作稱為「掛載」。
  • 掛載點一定是「目錄」,該目錄為進入該檔案系統的入口。

7.1.8 其他 Linux 支援的檔案系統與 VFS

常見的支援檔案系統

  • 傳統檔案系統
  • 日誌式檔案系統
  • 網路檔案系統

Linux VFS(Virtual Filesystem Switch):Linux 的核心利用 VFS 管理 filesystem

7.1.9 XFS 檔案系統簡介

CentOS 為什麼要捨棄對 Linux 支援度最完整的 Ext,而改用 XFS 呢?

  • Ext 家族:支援度較廣,但格式化超慢!
  • XFS 檔案系統的配置:
    • 基本上就是日誌檔案系統
    • 資料分布:
      • 資料區(data section):跟之前的 ext 家族一樣,包括 inode/block/superblock 等資料。不同的是,xfs 的 block 與 inode 有多種不同的容量可供設定。
      • 檔案系統活動登錄區(log section):有點像是日誌區。
      • 即時運作區(reAltime section):當有檔案要被建立時,xfs 會在這個區段裡面找到一個倒數個 extent 區塊,等檔案分配完畢,再寫入到 data section 的 inode 與 block。

7.2 檔案系統的簡單操作

7.2.1 磁碟與目錄的容量

現在我們知道磁碟的整體資料在 superblock 區塊中,個別檔案的容量則在 inode 記載,那在文字介面底下如何叫出這幾個資料呢?

  • df:列出檔案系統的整體磁碟使用量
    • df [-ahikHTm] [目錄或檔名]
  • du:評估出檔案系統的磁碟使用量(常用於推估目錄所佔容量)
    • du [-ahskm] [目錄或檔名]

7.2.2 實體連結與符號連結:ln

  • ln [-sf] 來源檔 目錄檔
  • Hard Link(實體連結、硬式連結或實際連結):
    • 在某個目錄下,新增一筆檔名連結到某 inode 號碼的關聯記號。
    • 如果將任何一個「檔名」刪除,inode 與 block 都還是存在的!
    • 限制
      • 不能跨 Filesystem
      • 不能 link 目錄
  • Symbolic Link(符號連結,亦即捷徑)
    • 建立一個獨立檔案,而這個檔案會讓資料的讀取指向它 link 的那個檔案的檔名

7.3 磁碟的分割、格式化、檢驗與掛載

在系統裡面新增一顆磁碟:

  1. 對磁碟進行分割,建立可用的 partition。
  2. 對該 partition 進行格式化(format),建立系統可用的 filesystem。
  3. 若想仔細一點,可對剛建立好的 filesystem 進行檢驗。
  4. 在 Linux 系統上,需要建立掛載點(亦即是目錄),並將它掛載上來。

7.3.1 觀察磁碟分割狀態

  • lsblk [-dfimpt] [device]:列出系統上所有磁碟列表
  • blkid:列出裝置的 UUID 等參數
  • parted device_name print:列出磁碟的分割表類型與分割資訊

咦等一下為什麼 partition table 是 loop?查了一下發現是在 VPS 上,所以會有這樣的情況唷!可惜的是接下來的磁碟分割就不能實作了,沒關係,老樣子,看過放在心裏,有一天會發芽。

7.3.2 磁碟分割:gdisk/fdisk

MBR 分割表用 fdisk 分割,GPT 分割表用 gdisk 分割:

  • gdisk
    • gdisk 裝置名稱
  • fdisk
    • fdsdk /dev/sda

7.3.3 磁碟格式化(建置檔案系統)

  • xfs 檔案系統 mkfs.xfs
    • mkfs.xfs [-b bsize] [-d parms] [-i parms] [-l parms] [-L parms] [-f] [-r parms] 裝置名稱
  • ext4 檔案系統 mkfs.ext4
    • mkfs.ext4 [-b size] [-L label] 裝置名稱
  • 其他檔案系統 mkfs
    • mkfs[tab][tab]

7.3.4 檔案系統檢驗

當機問題在所難免,我們主要針對 xfs 及 ext4 兩個主流系統來說明:

  • xfs_repair 處理 XFS 檔案系統
    • xfs_repair [-fnd] 裝置名稱
  • fsck.ext4 處理 ext4 檔案系統
    • fsck.ext [-pf] [-b superblock] 裝置名稱

7.3.5 檔案系統掛載與卸載

  • 單一檔案系統不應該被重複掛載在不同的掛載點中
  • 單一目錄不應該重複掛載多個檔案系統
  • 要作為掛載點的目錄,理論上應該都是空目錄
  • mount -a
  • mount [-l]
  • mount [-t 檔案系統] LABEL=''
  • mount [-t 檔案系統] UUID=''
  • mount [-t 檔案系統] 裝置檔名

7.3.6 磁碟/檔案系統參數修訂

  • mknod
    • mknod 裝置檔名 [bcp] [Major] [Minor]

7.4 設定開機掛載

7.4.1 開機掛載 /etc/fstab 及 /etc/mtab

系統掛載限制:

  • 根目錄 / 是必須掛載的,而且一定要先於其他 mount point 被掛載進來
  • 其他 mount point 必須為已建立的目錄,可任意指定,但一定要遵守必須的系統目錄架構原則(FHS)
  • 所有 mount point 在同一時間之內,只能掛載一次
  • 所有 partition 在同一時間之內,只能掛載一次
  • 如若進行卸載,你必須先將工作目錄移到 mount point(及其子目錄)之外

查閱 /etc/fstab 內容:cat /etc/fstab

其實 /etc/fstab(filesystem table)就是將我們利用 mount 指令進行掛載時,將所有選項與參數寫入到這個檔案中。由上圖可知,總共有六個欄位,非常的重要:
[裝置/UUID] [掛載點] [檔案系統] [檔案系統參數] [dump] [fsck]

  • 磁碟裝置檔名/UUID/LABEL name:
    • 檔案系統或磁碟的裝置檔名,如 /dev/vda2 等
    • 檔案系統的 UUID 名稱,如 UUID=xxx
    • 檔案系統的 LABEL 名稱,如 LABEL=xxx
  • 掛載點(mount point):一定是目錄
  • 磁碟分割槽的檔案系統:手動掛載時可以讓系統自動測試掛載,但在這個檔案中,必須要手動寫入檔案系統,包括 xfs, ext4, vfat, reiserfs, nfs 等等。
  • 檔案系統參數:
    • async/sync
    • auto/noauto
    • rw/ro
    • exec/noexec
    • user/nouser
    • suid/nosuid
    • defaults
  • 能否被 dump 備份指令作用
  • 是否以 fsck 檢驗磁區

7.4.2 特殊裝置 loop 掛載(映像檔不燒錄就掛載使用)

如果有光碟映像檔,或者使用檔案作為磁碟的方式時,那就得要使用特別的方法來將它寡仔起來,不需要燒錄。

  • 掛載光碟/DVD 映像檔
    • 掛載:mount -o loop /tmp/CentOS-7.0-1406-x86_64-DVD.iso /data/centos_dvd (/data/centos_dvd: 我們自己創建的目錄)
    • 卸載:unmount /data/centos_dvd
  • 建立大型檔案以製作 loop 裝置檔案:什麼時候可以做這件事情呢?如果當初在分割時,只有分割一個根目錄,又沒有多餘的容量進行額外的分割了,偏偏根目錄容量還很大,就可以製作出一個大檔案,並將這個檔案掛載啦!
    • 建立大型檔案
    • 大型檔案的格式化
    • 掛載

7.5 記憶體置換空間(swap)之建置

以前記憶體容量不足,因此 swap 空間就非常重要,可以暫時將記憶體的程序拿到硬碟中的 swap,目前的記憶體都很大,在 Linux 上應該沒有太大的問題,但在伺服器可就不這麼想了,因為不知道何時會有大量來自網路的要求,因此最好預留一些 swap 來緩衝。


7.6 檔案系統的特殊觀察與操作

  • 磁碟空間的浪費
  • 利用 GNU 的 parted 進行分割行為(Optional)
    • parted [裝置] [指令 [參數]]

資料來源

鳥哥的 Linux 私房菜: http://linux.vbird.org/linux_basic/

#鳥哥的 Linux 私房菜 #linux
鳥哥有句名言:「我沒有錢,所以只能硬著頭皮找其他技巧,不過換個想法,多學點也是好事。」還有什麼比瀟灑的 Linux 更帥呢?話不多說,走起!






Related Posts

Gatsby程序化產生頁面

Gatsby程序化產生頁面

[筆記] Command Line 超新手入門

[筆記] Command Line 超新手入門

兩年過後,我能夠被稱為資深工程師了嗎?

兩年過後,我能夠被稱為資深工程師了嗎?



Comments