基礎學習篇 - CentOS 7.x

第十四章、磁碟配額(Quota)與進階檔案系統管理

可以公平使用磁碟容量的 Quota 以及可增加磁碟容量的 RAID, LVM, iSCSI 設備等介紹

最近更新時間: 2015/07/28

如果您的 Linux 伺服器有多個用戶經常存取資料時,為了維護所有使用者在硬碟容量的公平使用,磁碟配額 (Quota) 就是一項非常有用的工具!另外,如果你的用戶常常抱怨磁碟容量不夠用,那麼更進階的檔案系統就得要學習學習。 本章我們會介紹磁碟陣列 (RAID) 及邏輯捲軸檔案系統 (LVM),這些工具都可以幫助你管理與維護使用者可用的磁碟容量喔!

14.1 磁碟配額 (Quota) 的應用與實作

Quota 這個玩意兒就字面上的意思來看,就是有多少『限額』的意思啦!如果是用在零用錢上面, 就是類似『有多少零用錢一個月』的意思之類的。如果是在電腦主機的磁碟使用量上呢?以 Linux 來說,就是有多少容量限制的意思囉。我們可以使用 quota 來讓磁碟的容量使用較為公平, 底下我們會介紹什麼是 quota ,然後以一個完整的範例來介紹 quota 的實作喔!

14.1.1 什麼是 Quota

在 Linux 系統中,由於是多人多工的環境,所以會有多人共同使用一個硬碟空間的情況發生, 如果其中有少數幾個使用者大量的佔掉了硬碟空間的話,那勢必壓縮其他使用者的使用權力! 因此管理員應該適當的限制硬碟的容量給使用者,以妥善的分配系統資源!避免有人抗議呀!

舉例來說,我們使用者的預設家目錄都是在 /home 底下,如果 /home 是個獨立的 partition , 假設這個分割槽有 10G 好了,而 /home 底下共有 30 個帳號,也就是說,每個使用者平均應該會有 333MB 的空間才對。 偏偏有個使用者在他的家目錄底下塞了好多隻影片,佔掉了 8GB 的空間,想想看,是否造成其他正常使用者的不便呢? 如果想要讓磁碟的容量公平的分配,這個時候就得要靠 quota 的幫忙囉!

  • Quota 的一般用途 (註1)

quota 比較常使用的幾個情況是:

  • 針對 WWW server ,例如:每個人的網頁空間的容量限制!
  • 針對 mail server,例如:每個人的郵件空間限制。
  • 針對 file server,例如:每個人最大的可用網路硬碟空間 (教學環境中最常見!)

上頭講的是針對網路服務的設計,如果是針對 Linux 系統主機上面的設定那麼使用的方向有底下這一些:

  • 限制某一群組所能使用的最大磁碟配額 (使用群組限制)
    你可以將你的主機上的使用者分門別類,有點像是目前很流行的付費與免付費會員制的情況, 你比較喜好的那一群的使用配額就可以給高一些!呵呵! ^_^...

  • 限制某一使用者的最大磁碟配額 (使用使用者限制)
    在限制了群組之後,你也可以再繼續針對個人來進行限制,使得同一群組之下還可以有更公平的分配!

  • 限制某一目錄 (directory, project) 的最大磁碟配額
    在舊版的 CentOS 當中,使用的預設檔案系統為 EXT 家族,這種檔案系統的磁碟配額主要是針對整個檔案系統來處理,所以大多針對『掛載點』進行設計。 新的 xfs 可以使用 project 這種模式,就能夠針對個別的目錄 (非檔案系統喔) 來設計磁碟配額耶!超棒的!

大概有這些實際的用途啦!基本上,quota 就是在回報管理員磁碟使用率以及讓管理員管理磁碟使用情況的一個工具就是了! 比較特別的是,XFS 的 quota 是整合到檔案系統內,並不是其他外掛的程式來管理的,因此,透過 quota 來直接回報磁碟使用率,要比 unix 工具來的快速! 舉例來說, du 這東西會重新計算目錄下的磁碟使用率,但 xfs 可以透過 xfs_quota 來直接回報各目錄使用率,速度上是快非常多!

  • Quota 的使用限制

雖然 quota 很好用,但是使用上還是有些限制要先瞭解的:

  • 在 EXT 檔案系統家族僅能針對整個 filesystem:
    EXT 檔案系統家族在進行 quota 限制的時候,它僅能針對整個檔案系統來進行設計,無法針對某個單一的目錄來設計它的磁碟配額。 因此,如果你想要使用不同的檔案系統進行 quota 時,請先搞清楚該檔案系統支援的情況喔!因為 XFS 已經可以使用 project 模式來設計不同目錄的磁碟配額。

  • 核心必須支援 quota :
    Linux 核心必須有支援 quota 這個功能才行:如果你是使用 CentOS 7.x 的預設核心, 嘿嘿!那恭喜你了,你的系統已經預設有支援 quota 這個功能囉!如果你是自行編譯核心的, 那麼請特別留意你是否已經『真的』開啟了 quota 這個功能?否則底下的功夫將全部都視為『白工』。

  • 只對一般身份使用者有效:
    這就有趣了!並不是所有在 Linux 上面的帳號都可以設定 quota 呢,例如 root 就不能設定 quota , 因為整個系統所有的資料幾乎都是他的啊! ^_^

  • 若啟用 SELinux,非所有目錄均可設定 quota :
    新版的 CentOS 預設都有啟用 SELinux 這個核心功能,該功能會加強某些細部的權限控制!由於擔心管理員不小心設定錯誤,因此預設的情況下, quota 似乎僅能針對 /home 進行設定而已~因此,如果你要針對其他不同的目錄進行設定,請參考到後續章節查閱解開 SELinux 限制的方法喔! 這就不是 quota 的問題了...

新版的 CentOS 使用的 xfs 確實比較有趣!不但無須額外的 quota 紀錄檔,也能夠針對檔案系統內的不同目錄進行配置!相當有趣! 只是不同的檔案系統在 quota 的處理情況上不太相同,因此這裡要特別強調,進行 quota 前,先確認你的檔案系統吧!

  • Quota 的規範設定項目:

quota 這玩意兒針對 XFS filesystem 的限制項目主要分為底下幾個部分:

  • 分別針對使用者、群組或個別目錄 (user, group & project):

XFS 檔案系統的 quota 限制中,主要是針對群組、個人或單獨的目錄進行磁碟使用率的限制!

  • 容量限制或檔案數量限制 (block 或 inode):

我們在第七章談到檔案系統中,說到檔案系統主要規劃為存放屬性的 inode 與實際檔案資料的 block 區塊,Quota 既然是管理檔案系統,所以當然也可以管理 inode 或 block 囉! 這兩個管理的功能為:

  • 限制 inode 用量:可以管理使用者可以建立的『檔案數量』;
  • 限制 block 用量:管理使用者磁碟容量的限制,較常見為這種方式。
  • 柔性勸導與硬性規定 (soft/hard):

既然是規範,當然就有限制值。不管是 inode/block ,限制值都有兩個,分別是 soft 與 hard。 通常 hard 限制值要比 soft 還要高。舉例來說,若限制項目為 block ,可以限制 hard 為 500MBytes 而 soft 為 400MBytes。這兩個限值的意義為:

  • hard:表示使用者的用量絕對不會超過這個限制值,以上面的設定為例, 使用者所能使用的磁碟容量絕對不會超過 500Mbytes ,若超過這個值則系統會鎖住該用戶的磁碟使用權;
  • soft:表示使用者在低於 soft 限值時 (此例中為 400Mbytes),可以正常使用磁碟,但若超過 soft 且低於 hard 的限值 (介於 400~500Mbytes 之間時),每次使用者登入系統時,系統會主動發出磁碟即將爆滿的警告訊息, 且會給予一個寬限時間 (grace time)。不過,若使用者在寬限時間倒數期間就將容量再次降低於 soft 限值之下, 則寬限時間會停止。
  • 會倒數計時的寬限時間 (grace time):

剛剛上面就談到寬限時間了!這個寬限時間只有在使用者的磁碟用量介於 soft 到 hard 之間時,才會出現且會倒數的一個咚咚! 由於達到 hard 限值時,使用者的磁碟使用權可能會被鎖住。為了擔心使用者沒有注意到這個磁碟配額的問題, 因此設計了 soft 。當你的磁碟用量即將到達 hard 且超過 soft 時,系統會給予警告,但也會給一段時間讓使用者自行管理磁碟。 一般預設的寬限時間為七天,如果七天內你都不進行任何磁碟管理,那麼 soft 限制值會即刻取代 hard 限值來作為 quota 的限制

以上面設定的例子來說,假設你的容量高達 450MBytes 了,那七天的寬限時間就會開始倒數, 若七天內你都不進行任何刪除檔案的動作來替你的磁碟用量瘦身, 那麼七天後你的磁碟最大用量將變成 400MBytes (那個 soft 的限制值),此時你的磁碟使用權就會被鎖住而無法新增檔案了。

整個 soft, hard, grace time 的相關性我們可以用底下的圖示來說明:

soft, hard, grace time 的相關性
圖14.1.1、soft, hard, grace time 的相關性

圖中的長條圖為使用者的磁碟容量,soft/hard 分別是限制值。只要小於 400M 就一切 OK , 若高於 soft 就出現 grace time 並倒數且等待使用者自行處理,若到達 hard 的限制值, 那我們就搬張小板凳等著看好戲啦!嘿嘿!^_^!這樣圖示有清楚一點了嗎?

14.1.2 一個 XFS 檔案系統的 Quota 實作範例

坐而言不如起而行啊,所以這裡我們使用一個範例來設計一下如何處理 Quota 的設定流程。

  • 目的與帳號:現在我想要讓我的專題生五個為一組,這五個人的帳號分別是 myquota1, myquota2, myquota3, myquota4, myquota5,這五個用戶的密碼都是 password ,且這五個用戶所屬的初始群組都是 myquotagrp 。 其他的帳號屬性則使用預設值。

  • 帳號的磁碟容量限制值:我想讓這五個用戶都能夠取得 300MBytes 的磁碟使用量(hard),檔案數量則不予限制。 此外,只要容量使用率超過 250MBytes ,就予以警告 (soft)。

  • 群組的限額 (option 1):由於我的系統裡面還有其他用戶存在,因此我僅承認 myquotagrp 這個群組最多僅能使用 1GBytes 的容量。 這也就是說,如果 myquota1, myquota2, myquota3 都用了 280MBytes 的容量了,那麼其他兩人最多只能使用 (1000MB - 280x3 = 160MB) 的磁碟容量囉!這就是使用者與群組同時設定時會產生的後果。

  • 共享目錄限額 (option 2):另一種設定方式,每個用戶還是具有自己獨立的容量限止,但是這五個人的專題共用目錄在 /home/myquota 這裡,該目錄請設定為其他人沒有任何權限的共享目錄空間,僅有 myquotagrp 群組擁有全部的權限。 且無論如何,該目錄最多僅能夠接受 500MBytes 的容量。請注意,群組 (group) 的限制與目錄 (directory/project) 無法同時並存喔! 所以底下的流程中,我們會先以群組來設計,然後再以目錄限制來進一步說明!

  • 寬限時間的限制:最後,我希望每個使用者在超過 soft 限制值之後,都還能夠有 14 天的寬限時間。

好了,那你怎麼規範帳號以及相關的 Quota 設定呢?首先,在這個小節我們先來將帳號相關的屬性、參數及其他環境搞定再說吧!

# 製作帳號環境時,由於有五個帳號,因此鳥哥使用 script 來建立環境!
[root@study ~]# vim addaccount.sh
#!/bin/bash
# 使用 script 來建立實驗 quota 所需的環境
groupadd myquotagrp
for username in myquota1 myquota2 myquota3 myquota4 myquota5
do
	useradd -g myquotagrp $username
	echo "password" | passwd --stdin $username
done
mkdir /home/myquota
chgrp myquotagrp /home/myquota
chmod 2770 /home/myquota

[root@study ~]# sh addaccount.sh

接下來,就讓我們來實作 Quota 的練習吧!

14.1.3 實作 Quota 流程-1:檔案系統的支援與觀察

前面我們就談到,要使用 Quota 必須要核心與檔案系統支援才行!假設你已經使用了預設支援 Quota 的核心, 那麼接下來就是要啟動檔案系統的支援啦!但是要注意,我們這邊是以 XFS 檔案系統為例的,如果你使用的是 EXT 家族,請找前一版的書籍說明喔! 此外,不要在根目錄底下進行 quota 設計喔!因為檔案系統會變得太複雜!因此,底下我們是以 /home 這個 xfs 檔案系統為例的! 當然啦,首先就是要來檢查看看!

[root@study ~]# df -hT /home
Filesystem              Type  Size  Used Avail Use% Mounted on
/dev/mapper/centos-home xfs   5.0G   67M  5.0G   2% /home 

從上面的資料來看,鳥哥這部主機的 /home 確實是獨立的 filesystem,而且確實是使用了 xfs 檔案系統!所以可以使用底下的流程囉! 此外,由於 VFAT 檔案系統並不支援 Linux Quota 功能,所以我們得要使用 mount 查詢一下 /home 的檔案系統為何才行啊!

在過去的版本中,管理員似乎可以透過 mount -o remount 的機制來重新掛載啟動 quota 的功能,不過 XFS 檔案系統的 quota 似乎是在掛載之初就宣告了, 因此無法使用 remount 來重新啟動 quota 功能,一定得要寫入 /etc/fstab 當中,或者是在初始掛載過程中加入這個項目, 否則不會生效喔!那就來瞧瞧鳥哥改了 fstab 成為怎樣吧!

[root@study ~]# vim /etc/fstab
/dev/mapper/centos-home  /home  xfs  defaults,usrquota,grpquota   0 0
# 其他項目鳥哥並沒有列出來!重點在於第四欄位!於 default 後面加上兩個參數!

[root@study ~]# umount /home
[root@study ~]# mount -a
[root@study ~]# mount | grep home
/dev/mapper/centos-home on /home type xfs (rw,relatime,seclabel,attr2,inode64,usrquota,grpquota)

基本上,針對 quota 限制的項目主要有三項,如下所示:

  • uquota/usrquota/quota:針對使用者帳號的設定
  • gquota/grpquota:針對群組的設定
  • pquota/prjquota:針對單一目錄的設定,但是不可與 grpquota 同時存在!

還是要再次的強調,修改完 /etc/fstab 後,務必要測試一下!若有發生錯誤得要趕緊處理! 因為這個檔案如果修改錯誤,是會造成無法開機完全的情況啊!切記切記!最好使用 vim 來修改啦! 因為會有語法的檢驗,就不會讓你寫錯字了!此外,由於一般用戶的家目錄在 /home 裡面,因此針對這個項目的卸載時, 一定要將所有一般帳號的身份登出,否則肯定無法卸載喔!留意留意!

14.1.4 實作 Quota 流程-2:觀察 Quota 報告資料

製作檔案系統支援之後,當然得要來瞧一瞧到底有沒有正確的將 quota 的管理資料列出來才好!這時我們得要使用 xfs_quota 這個指令才行!這個指令真的是挺復雜的,因為全部的 quota 實作都是這個指令耶!所以裡面的參數有夠多! 不過稍微觀察一下即可!先讓我們來談談觀察目前 quota 的報告內容吧!

[root@study ~]# xfs_quota -x -c "指令" [掛載點]
選項與參數:
-x  :專家模式,後續才能夠加入 -c 的指令參數喔!
-c  :後面加的就是指令,這個小節我們先來談談數據回報的指令
指令:
      print :單純的列出目前主機內的檔案系統參數等資料
      df    :與原本的 df 一樣的功能,可以加上 -b (block) -i (inode) -h (加上單位) 等
      report:列出目前的 quota 項目,有 -ugr (user/group/project) 及 -bi 等資料
      state :說明目前支援 quota 的檔案系統的資訊,有沒有起動相關項目等

範例一:列出目前系統的各的檔案系統,以及檔案系統的 quota 掛載參數支援
[root@study ~]# xfs_quota -x -c "print"
Filesystem          Pathname
/                   /dev/mapper/centos-root
/srv/myproject      /dev/vda4
/boot               /dev/vda2
/home               /dev/mapper/centos-home (uquota, gquota)  # 所以這裡就有顯示支援囉

範例二:列出目前 /home 這個支援 quota 的載點檔案系統使用情況
[root@study ~]# xfs_quota -x -c "df -h" /home
Filesystem     Size   Used  Avail Use% Pathname
/dev/mapper/centos-home
               5.0G  67.0M   4.9G   1% /home
# 如上所示,其實跟原本的 df 差不多啦!只是會更正確就是了。

範例三:列出目前 /home 的所有用戶的 quota 限制值
[root@study ~]# xfs_quota -x -c "report -ubih" /home
User quota on /home (/dev/mapper/centos-home)
                        Blocks                            Inodes
User ID      Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
---------- --------------------------------- ---------------------------------
root           4K      0      0  00 [------]      4      0      0  00 [------]
dmtsai      34.0M      0      0  00 [------]    432      0      0  00 [------]
.....(中間省略).....
myquota1      12K      0      0  00 [------]      7      0      0  00 [------]
myquota2      12K      0      0  00 [------]      7      0      0  00 [------]
myquota3      12K      0      0  00 [------]      7      0      0  00 [------]
myquota4      12K      0      0  00 [------]      7      0      0  00 [------]
myquota5      12K      0      0  00 [------]      7      0      0  00 [------]
# 所以列出了所有用戶的目前的檔案使用情況,並且列出設定值。注意,最上面的 Block
# 代表這個是 block 容量限制,而 inode 則是檔案數量限制喔。另外,soft/hard 若為 0,代表沒限制

範例四:列出目前支援的 quota 檔案系統是否有起動了 quota 功能?
[root@study ~]# xfs_quota -x -c "state"
User quota state on /home (/dev/mapper/centos-home)
  Accounting: ON    # 有啟用計算功能
  Enforcement: ON   # 有實際 quota 管制的功能
  Inode: #1568 (4 blocks, 4 extents)  # 上面四行說明的是有啟動 user 的限制能力
Group quota state on /home (/dev/mapper/centos-home)
  Accounting: ON
  Enforcement: ON
  Inode: #1569 (5 blocks, 5 extents)  # 上面四行說明的是有啟動 group 的限制能力
Project quota state on /home (/dev/mapper/centos-home)
  Accounting: OFF
  Enforcement: OFF
  Inode: #1569 (5 blocks, 5 extents)  # 上面四行說明的是 project 並未支援
Blocks grace time: [7 days 00:00:30]  # 底下則是 grace time 的項目
Inodes grace time: [7 days 00:00:30]
Realtime Blocks grace time: [7 days 00:00:30]

在預設的情況下, xfs_quota 的 report 指令會將支援的 user/group/prject 相關資料列出來,如果只是想要某個特定的項目, 例如我們上面要求僅列出用戶的資料時,就在 report 後面加上 -u 即可喔!這樣就能夠觀察目前的相關設定資訊了。 要注意,限制的項目有 block/inode 同時可以針對每個項目來設定 soft/hard 喔!接下來實際的設定看看吧!

14.1.5 實作 Quota 流程-3:限制值設定方式

確認檔案系統的 quota 支援順利啟用後,也能夠觀察到相關的 quota 限制,接下來就是要實際的給予用戶/群組限制囉! 回去瞧瞧,我們需要每個用戶 250M/300M 的容量限制,群組共 950M/1G 的容量限制,同時 grace time 設定為 14 天喔! 實際的語法與設定流程來瞧瞧:

[root@study ~]# xfs_quota -x -c "limit [-ug] b[soft|hard]=N i[soft|hard]=N name"
[root@study ~]# xfs_quota -x -c "timer [-ug] [-bir] Ndays"
選項與參數:
limit :實際限制的項目,可以針對 user/group 來限制,限制的項目有
        bsoft/bhard : block 的 soft/hard 限制值,可以加單位
        isoft/ihard : inode 的 soft/hard 限制值
        name        : 就是用戶/群組的名稱啊!
timer :用來設定 grace time 的項目喔,也是可以針對 user/group 以及 block/inode 設定

範例一:設定好用戶們的 block 限制值 (題目中沒有要限制 inode 啦!)
[root@study ~]# xfs_quota -x -c "limit -u bsoft=250M bhard=300M myquota1" /home
[root@study ~]# xfs_quota -x -c "limit -u bsoft=250M bhard=300M myquota2" /home
[root@study ~]# xfs_quota -x -c "limit -u bsoft=250M bhard=300M myquota3" /home
[root@study ~]# xfs_quota -x -c "limit -u bsoft=250M bhard=300M myquota4" /home
[root@study ~]# xfs_quota -x -c "limit -u bsoft=250M bhard=300M myquota5" /home
[root@study ~]# xfs_quota -x -c "report -ubih" /home
User quota on /home (/dev/mapper/centos-home)
                        Blocks                            Inodes
User ID      Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
---------- --------------------------------- ---------------------------------
myquota1      12K   250M   300M  00 [------]      7      0      0  00 [------]

範例二:設定好 myquotagrp 的 block 限制值
[root@study ~]# xfs_quota -x -c "limit -g bsoft=950M bhard=1G myquotagrp" /home
[root@study ~]# xfs_quota -x -c "report -gbih" /home
Group quota on /home (/dev/mapper/centos-home)
                        Blocks                            Inodes
Group ID     Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
---------- --------------------------------- ---------------------------------
myquotagrp    60K   950M     1G  00 [------]     36      0      0  00 [------]

範例三:設定一下 grace time 變成 14 天吧!
[root@study ~]# xfs_quota -x -c "timer -ug -b 14days" /home
[root@study ~]# xfs_quota -x -c "state" /home
User quota state on /home (/dev/mapper/centos-home)
.....(中間省略).....
Blocks grace time: [14 days 00:00:30]
Inodes grace time: [7 days 00:00:30]
Realtime Blocks grace time: [7 days 00:00:30]

範例四:以 myquota1 用戶測試 quota 是否真的實際運作呢?
[root@study ~]# su - myquota1
[myquota1@study ~]$ dd if=/dev/zero of=123.img bs=1M count=310
dd: error writing ‘123.img’: Disk quota exceeded
300+0 records in
299+0 records out
314552320 bytes (315 MB) copied, 0.181088 s, 1.7 GB/s
[myquota1@study ~]$ ll -h
-rw-r--r--. 1 myquota1 myquotagrp 300M Jul 24 21:38 123.img

[myquota1@study ~]$ exit
[root@study ~]# xfs_quota -x -c "report -ubh" /home
User quota on /home (/dev/mapper/centos-home)
                        Blocks
User ID      Used   Soft   Hard Warn/Grace
---------- ---------------------------------
myquota1     300M   250M   300M  00 [13 days]
myquota2      12K   250M   300M  00 [------]
# 因為 myquota1 的磁碟用量已經破表,所以當然就會出現那個可怕的 grace time 囉!

這樣就直接製做好 quota 囉!看起來也是挺簡單啦!

14.1.6 實作 Quota 流程-4:project 的限制 (針對目錄限制) (Optional)

現在讓我們來想一想,如果需要限制的是目錄而不是群組時,那該如何處理呢?舉例來說,我們要限制的是 /home/myquota 這個目錄本身, 而不是針對 myquotagrp 這個群組啊!這兩種設定方法的意義不同喔!例如,前一個小節談到的測試範例來說, myquota1 已經消耗了 300M 的容量,而 /home/myquota 其實還沒有任何的使用量 (因為在 myquota1 的家目錄做的 dd 指令)。 不過如果你使用了 xfs_quota -x -c "report -h" /home 這個指令來查看,就會發現其實 myquotagrp 已經用掉了 300M 了! 如此一來,對於目錄的限制來說,就不會有效果!

為了解決這個問題,因此我們這個小節要來設定那個很有趣的 project 項目!只是這個項目不可以跟 group 同時設定喔! 因此我們得要取消 group 設定並且加入 project 設定才行。那就來實驗看看。

  • 修改 /etc/fstab 內的檔案系統支援參數

首先,要將 grpquota 的參數取消,然後加入 prjquota ,並且卸載 /home 再重新掛載才行!那就來測試看看!

# 1. 先修改 /etc/fstab 的參數,並啟動檔案系統的支援
[root@study ~]# vim /etc/fstab
/dev/mapper/centos-home /home xfs  defaults,usrquota,grpquota,prjquota  0 0
# 記得, grpquota 與 prjquota 不可同時設定喔!所以上面刪除 grpquota 加入 prjquota

[root@study ~]# umount /home
[root@study ~]# mount -a
[root@study ~]# xfs_quota -x -c "state"
User quota state on /home (/dev/mapper/centos-home)
  Accounting: ON
  Enforcement: ON
  Inode: #1568 (4 blocks, 4 extents)
Group quota state on /home (/dev/mapper/centos-home)
  Accounting: OFF         <==已經取消囉!
  Enforcement: OFF
  Inode: N/A
Project quota state on /home (/dev/mapper/centos-home)
  Accounting: ON          <==確實啟動囉!
  Enforcement: ON
  Inode: N/A
Blocks grace time: [7 days 00:00:30]
Inodes grace time: [7 days 00:00:30]
Realtime Blocks grace time: [7 days 00:00:30]
  • 規範目錄、專案名稱(project)與專案 ID

目錄的設定比較奇怪,他必須要指定一個所謂的『專案名稱、專案識別碼』來規範才行!而且還需要用到兩個設定檔! 這個讓鳥哥覺得比較怪一些就是了。現在,我們要規範的目錄是 /home/myquota 目錄,這個目錄我們給個 myquotaproject 的專案名稱, 這個專案名稱給個 11 的識別碼,這個都是自己指定的,若不喜歡就自己指定另一個吧!鳥哥的指定方式如下:

# 2.1 指定專案識別碼與目錄的對應在 /etc/projects
[root@study ~]# echo "11:/home/myquota" >> /etc/projects

# 2.2 規範專案名稱與識別碼的對應在 /etc/projid
[root@study ~]# echo "myquotaproject:11" >> /etc/projid

# 2.3 初始化專案名稱
[root@study ~]# xfs_quota -x -c "project -s myquotaproject"
Setting up project myquotaproject (path /home/myquota)...
Processed 1 (/etc/projects and cmdline) paths for project myquotaproject with recursion 
depth infinite (-1).    # 會閃過這些訊息!是 OK 的!別擔心!

[root@study ~]# xfs_quota -x -c "print " /home
Filesystem          Pathname
/home               /dev/mapper/centos-home (uquota, pquota)
/home/myquota       /dev/mapper/centos-home (project 11, myquotaproject)
# 這個 print 功能很不錯!可以完整的查看到相對應的各項檔案系統與 project 目錄對應!

[root@study ~]# xfs_quota -x -c "report -pbih " /home
Project quota on /home (/dev/mapper/centos-home)
                        Blocks                            Inodes
Project ID       Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
---------- --------------------------------- ---------------------------------
myquotaproject      0      0      0  00 [------]      1      0      0  00 [------]
# 喔耶!確定有抓到這個專案名稱囉!接下來準備設定吧!
  • 實際設定規範與測試

依據本章的說明,我們要將 /home/myquota 指定為 500M 的容量限制,那假設到 450M 為 soft 的限制好了! 那麼設定就會變成這樣囉:

# 3.1 先來設定好這個 project 吧!設定的方式同樣使用 limit 的 bsoft/bhard 喔!:
[root@study ~]# xfs_quota -x -c "limit -p bsoft=450M bhard=500M myquotaproject" /home
[root@study ~]# xfs_quota -x -c "report -pbih " /home
Project quota on /home (/dev/mapper/centos-home)
                            Blocks                            Inodes
Project ID       Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace
---------- --------------------------------- ---------------------------------
myquotaproject      0   450M   500M  00 [------]      1      0      0  00 [------]

[root@study ~]# dd if=/dev/zero of=/home/myquota/123.img bs=1M count=510
dd: error writing '/home/myquota/123.img': No space left on device
501+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.96296 s, 544 MB/s
# 你看!連 root 在該目錄底下建立檔案時,也會被擋掉耶!這才是完整的針對目錄的規範嘛!讚!

這樣就設定好了囉!未來如果你還想要針對某些個目錄進行限制,那麼就修改 /etc/projects, /etc/projid 設定一下規範, 然後直接處理目錄的初始化與設定,就完成設定了!好簡單!

當鳥哥跟同事分享這個 project 的功能時,強者我同事蔡董大大說,剛剛好!他有些朋友要求在 WWW 的服務中,要針對某些目錄進行容量的限制! 但是因為容量之前僅針對用戶進行限制,如此一來,由於 WWW 服務都是一個名為 httpd 的帳號管理的,因此所有 WWW 服務所產生的檔案資料, 就全部屬於 httpd 這個帳號,那就無法針對某些特定的目錄進行限制了。有了這個 project 之後,就能夠針對不同的目錄做容量限制! 而不用管在裡頭建立檔案的檔案擁有者!哇!這真是太棒了!實務應用給各位了解囉! ^_^

14.1.7 XFS quota 的管理與額外指令對照表

不管多完美的系統,總是需要可能的突發狀況應付手段啊!所以,接下來我們就來談談,那麼萬一如果你需要暫停 quota 的限制, 或者是重新啟動 quota 的限制時,該如何處理呢?還是使用 xfs_quota 啦!增加幾個內部指令即可:

  • disable:暫時取消 quota 的限制,但其實系統還是在計算 quota 中,只是沒有管制而已!應該算最有用的功能囉!
  • enable:就是回復到正常管制的狀態中,與 disable 可以互相取消、啟用!
  • off:完全關閉 quota 的限制,使用了這個狀態後,你只有卸載再重新掛載才能夠再次的啟動 quota 喔!也就是說, 用了 off 狀態後,你無法使用 enable 再次復原 quota 的管制喔!注意不要亂用這個狀態!一般建議用 disable 即可,除非你需要執行 remove 的動作!
  • remove:必須要在 off 的狀態下才能夠執行的指令~這個 remove 可以『移除』quota 的限制設定,例如要取消 project 的設定, 無須重新設定為 0 喔!只要 remove -p 就可以了!

現在就讓我們來測試一下管理的方式吧:

# 1. 暫時關閉 XFS 檔案系統的 quota 限制功能
[root@study ~]# xfs_quota -x -c "disable -up" /home
[root@study ~]# xfs_quota -x -c "state" /home
User quota state on /home (/dev/mapper/centos-home)
  Accounting: ON
  Enforcement: OFF   <== 意思就是有在計算,但沒有強制管制的意思
  Inode: #1568 (4 blocks, 4 extents)
Group quota state on /home (/dev/mapper/centos-home)
  Accounting: OFF
  Enforcement: OFF
  Inode: N/A
Project quota state on /home (/dev/mapper/centos-home)
  Accounting: ON
  Enforcement: OFF
  Inode: N/A
Blocks grace time: [7 days 00:00:30]
Inodes grace time: [7 days 00:00:30]
Realtime Blocks grace time: [7 days 00:00:30]

[root@study ~]# dd if=/dev/zero of=/home/myquota/123.img bs=1M count=520
520+0 records in
520+0 records out  # 見鬼!竟然沒有任何錯誤發生了!
545259520 bytes (545 MB) copied, 0.308407 s, 180 MB/s

[root@study ~]# xfs_quota -x -c "report -pbh" /home
Project quota on /home (/dev/mapper/centos-home)
                        Blocks
Project ID       Used   Soft   Hard Warn/Grace
---------- ---------------------------------
myquotaproject   520M   450M   500M  00 [-none-]
# 其實,還真的有超過耶!只是因為 disable 的關係,所以沒有強制限制住就是了!

[root@study ~]# xfs_quota -x -c "enable -up" /home  # 重新啟動 quota 限制
[root@study ~]# dd if=/dev/zero of=/home/myquota/123.img bs=1M count=520
dd: error writing ‘/home/myquota/123.img’: No space left on device
# 又開始有限制!這就是 enable/disable 的相關對應功能喔!暫時關閉/啟動用的!

# 完全關閉 quota 的限制行為吧!同時取消 project 的功能試看看!
[root@study ~]# xfs_quota -x -c "off -up" /home
[root@study ~]# xfs_quota -x -c "enable -up" /home
XFS_QUOTAON: Function not implemented
# 您瞧瞧!沒有辦法重新啟動!因為已經完全的關閉了 quota 的功能!所以得要 umount/mount 才行!

[root@study ~]# umount /home; mount -a
# 這個時候使用 report 以及 state 時,管制限制的內容又重新回來了!好!來瞧瞧如何移除project

[root@study ~]# xfs_quota -x -c "off -up" /home
[root@study ~]# xfs_quota -x -c "remove -p" /home
[root@study ~]# umount /home; mount -a
[root@study ~]# xfs_quota -x -c "report -phb" /home
Project quota on /home (/dev/mapper/centos-home)
                        Blocks
Project ID       Used   Soft   Hard Warn/Grace
---------- ---------------------------------
myquotaproject   500M      0      0  00 [------]
# 嘿嘿!全部歸零!就是『移除』所有限制值的意思!

請注意上表中最後一個練習,那個 remove -p 是『移除所有的 project 控制列表』的意思!也就是說,如果你有在 /home 設定多個 project 的限制, 那麼 remove 會刪的一個也不留喔!如果想要回復設定值,那...只能一個一個重新設定回去了!沒有好辦法!

上面就是 XFS 檔案系統的簡易 quota 處理流程~那如果你是使用 EXT 家族呢?能不能使用 quota 呢?除了參考上一版的文件之外,鳥哥這裡也列出相關的參考指令/設定檔案給你對照參考! 沒學過的可以看看流程,有學過的可以對照瞭解! ^_^

設定流程項目XFS檔案系統EXT家族
/etc/fstab參數設定usrquota/grpquota/prjquotausrquota/grpquota
quota 設定檔不需要quotacheck
設定用戶/群組限制值xfs_quota -x -c "limit..."edquota 或 setquota
設定 grace timexfs_quota -x -c "timer..."edquota
設定目錄限制值xfs_quota -x -c "limit..."
觀察報告xfs_quota -x -c "report..."repquota 或 quota
啟動與關閉 quota 限制xfs_quota -x -c "[disable|enable]..."quotaoff, quotaon
發送警告信給用戶目前版本尚未支援warnquota

14.1.8 不更動既有系統的 quota 實例

想一想,如果你的主機原先沒有想到要設定成為郵件主機,所以並沒有規劃將郵件信箱所在的 /var/spool/mail/ 目錄獨立成為一個 partition ,然後目前你的主機已經沒有辦法新增或分割出任何新的分割槽了。那我們知道 quota 的支援與檔案系統有關, 所以並無法跨檔案系統來設計 quota 的 project 功能啊!因此,你是否就無法針對 mail 的使用量給予 quota 的限制呢?

此外,如果你想要讓使用者的郵件信箱與家目錄的總體磁碟使用量為固定,那又該如何是好? 由於 /home 及 /var/spool/mail 根本不可能是同一個 filesystem (除非是都不分割,使用根目錄,才有可能整合在一起), 所以,該如何進行這樣的 quota 限制呢?

其實沒有那麼難啦!既然 quota 是針對 filesystem 來進行限制,假設你又已經有 /home 這個獨立的分割槽了,那麼你只要:

  1. 將 /var/spool/mail 這個目錄完整的移動到 /home 底下;
  2. 利用 ln -s /home/mail /var/spool/mail 來建立連結資料;
  3. 將 /home 進行 quota 限額設定

只要這樣的一個小步驟,嘿嘿!您家主機的郵件就有一定的限額囉!當然囉!您也可以依據不同的使用者與群組來設定 quota 然後同樣的以上面的方式來進行 link 的動作!嘿嘿嘿!就有不同的限額針對不同的使用者提出囉!很方便吧!^_^

Tips 鳥哥 朋友們需要注意的是,由於目前新的 distributions 大多有使用 SELinux 的機制, 因此你要進行如同上面的目錄搬移時,在許多情況下可能會有使用上的限制喔!或許你得要先暫時關閉 SELinux 才能測試, 也或許你得要自行修改 SELinux 的規則才行喔!

14.2 軟體磁碟陣列 (Software RAID)

在過去鳥哥還年輕的時代,我們能使用的硬碟容量都不大,幾十 GB 的容量就是大硬碟了!但是某些情況下,我們需要很大容量的儲存空間, 例如鳥哥在跑的空氣品質模式所輸出的資料檔案一個案例通常需要好幾 GB ,連續跑個幾個案例,磁碟容量就不夠用了。 此時我該如何是好?其實可以透過一種儲存機制,稱為磁碟陣列 (RAID) 的就是了。這種機制的功能是什麼?他有哪些等級?什麼是硬體、軟體磁碟陣列?Linux 支援什麼樣的軟體磁碟陣列? 底下就讓我們來談談!

14.2.1 什麼是 RAID

磁碟陣列全名是『 Redundant Arrays of Independent Disks, RAID 』,英翻中的意思為:獨立容錯式磁碟陣列,舊稱為容錯式廉價磁碟陣列, 反正就稱為磁碟陣列即可!RAID 可以透過一個技術(軟體或硬體),將多個較小的磁碟整合成為一個較大的磁碟裝置; 而這個較大的磁碟功能可不止是儲存而已,他還具有資料保護的功能呢。整個 RAID 由於選擇的等級 (level) 不同,而使得整合後的磁碟具有不同的功能,基本常見的 level 有這幾種(註2):

  • RAID-0 (等量模式, stripe):效能最佳

這種模式如果使用相同型號與容量的磁碟來組成時,效果較佳。這種模式的 RAID 會將磁碟先切出等量的區塊 (名為chunk,一般可設定 4K~1M 之間), 然後當一個檔案要寫入 RAID 時,該檔案會依據 chunk 的大小切割好,之後再依序放到各個磁碟裡面去。由於每個磁碟會交錯的存放資料, 因此當你的資料要寫入 RAID 時,資料會被等量的放置在各個磁碟上面。舉例來說,你有兩顆磁碟組成 RAID-0 , 當你有 100MB 的資料要寫入時,每個磁碟會各被分配到 50MB 的儲存量。RAID-0 的示意圖如下所示:

RAID-0 的磁碟寫入示意圖
圖14.2.1、RAID-0 的磁碟寫入示意圖

上圖的意思是,在組成 RAID-0 時,每顆磁碟 (Disk A 與 Disk B) 都會先被區隔成為小區塊 (chunk)。 當有資料要寫入 RAID 時,資料會先被切割成符合小區塊的大小,然後再依序一個一個的放置到不同的磁碟去。 由於資料已經先被切割並且依序放置到不同的磁碟上面,因此每顆磁碟所負責的資料量都降低了!照這樣的情況來看, 越多顆磁碟組成的 RAID-0 效能會越好,因為每顆負責的資料量就更低了! 這表示我的資料可以分散讓多顆磁碟來儲存,當然效能會變的更好啊!此外,磁碟總容量也變大了! 因為每顆磁碟的容量最終會加總成為 RAID-0 的總容量喔!

只是使用此等級你必須要自行負擔資料損毀的風險,由上圖我們知道檔案是被切割成為適合每顆磁碟分割區塊的大小, 然後再依序放置到各個磁碟中。想一想,如果某一顆磁碟損毀了,那麼檔案資料將缺一塊,此時這個檔案就損毀了。 由於每個檔案都是這樣存放的,因此 RAID-0 只要有任何一顆磁碟損毀,在 RAID 上面的所有資料都會遺失而無法讀取

另外,如果使用不同容量的磁碟來組成 RAID-0 時,由於資料是一直等量的依序放置到不同磁碟中,當小容量磁碟的區塊被用完了, 那麼所有的資料都將被寫入到最大的那顆磁碟去。舉例來說,我用 200G 與 500G 組成 RAID-0 , 那麼最初的 400GB 資料可同時寫入兩顆磁碟 (各消耗 200G 的容量),後來再加入的資料就只能寫入 500G 的那顆磁碟中了。 此時的效能就變差了,因為只剩下一顆可以存放資料嘛!

  • RAID-1 (映射模式, mirror):完整備份

這種模式也是需要相同的磁碟容量的,最好是一模一樣的磁碟啦!如果是不同容量的磁碟組成 RAID-1 時,那麼總容量將以最小的那一顆磁碟為主!這種模式主要是『讓同一份資料,完整的保存在兩顆磁碟上頭』。舉例來說,如果我有一個 100MB 的檔案,且我僅有兩顆磁碟組成 RAID-1 時, 那麼這兩顆磁碟將會同步寫入 100MB 到他們的儲存空間去。 因此,整體 RAID 的容量幾乎少了 50%。由於兩顆硬碟內容一模一樣,好像鏡子映照出來一樣, 所以我們也稱他為 mirror 模式囉~

RAID-1 的磁碟寫入示意圖
圖14.2.2、RAID-1 的磁碟寫入示意圖

如上圖所示,一份資料傳送到 RAID-1 之後會被分為兩股,並分別寫入到各個磁碟裡頭去。 由於同一份資料會被分別寫入到其他不同磁碟,因此如果要寫入 100MB 時,資料傳送到 I/O 匯流排後會被複製多份到各個磁碟, 結果就是資料量感覺變大了!因此在大量寫入 RAID-1 的情況下,寫入的效能可能會變的非常差 (因為我們只有一個南橋啊!)。 好在如果你使用的是硬體 RAID (磁碟陣列卡) 時,磁碟陣列卡會主動的複製一份而不使用系統的 I/O 匯流排,效能方面則還可以。 如果使用軟體磁碟陣列,可能效能就不好了。

由於兩顆磁碟內的資料一模一樣,所以任何一顆硬碟損毀時,你的資料還是可以完整的保留下來的! 所以我們可以說, RAID-1 最大的優點大概就在於資料的備份吧!不過由於磁碟容量有一半用在備份, 因此總容量會是全部磁碟容量的一半而已。雖然 RAID-1 的寫入效能不佳,不過讀取的效能則還可以啦!這是因為資料有兩份在不同的磁碟上面,如果多個 processes 在讀取同一筆資料時, RAID 會自行取得最佳的讀取平衡。

  • RAID 1+0,RAID 0+1

RAID-0 的效能佳但是資料不安全,RAID-1 的資料安全但是效能不佳,那麼能不能將這兩者整合起來設定 RAID 呢? 可以啊!那就是 RAID 1+0 或 RAID 0+1。所謂的 RAID 1+0 就是: (1)先讓兩顆磁碟組成 RAID 1,並且這樣的設定共有兩組; (2)將這兩組 RAID 1 再組成一組 RAID 0。這就是 RAID 1+0 囉!反過來說,RAID 0+1 就是先組成 RAID-0 再組成 RAID-1 的意思。

RAID-1+0 的磁碟寫入示意圖
圖14.2.3、RAID-1+0 的磁碟寫入示意圖

如上圖所示,Disk A + Disk B 組成第一組 RAID 1,Disk C + Disk D 組成第二組 RAID 1, 然後這兩組再整合成為一組 RAID 0。如果我有 100MB 的資料要寫入,則由於 RAID 0 的關係, 兩組 RAID 1 都會寫入 50MB,又由於 RAID 1 的關係,因此每顆磁碟就會寫入 50MB 而已。 如此一來不論哪一組 RAID 1 的磁碟損毀,由於是 RAID 1 的映像資料,因此就不會有任何問題發生了!這也是目前儲存設備廠商最推薦的方法!

Tips 鳥哥 為何會推薦 RAID 1+0 呢?想像你有 20 顆磁碟組成的系統,每兩顆組成一個 RAID1,因此你就有總共 10組可以自己復原的系統了! 然後這 10組再組成一個新的 RAID0,速度立刻拉升 10倍了!同時要注意,因為每組 RAID1 是個別獨立存在的,因此任何一顆磁碟損毀, 資料都是從另一顆磁碟直接複製過來重建,並不像 RAID5/RAID6 必須要整組 RAID 的磁碟共同重建一顆獨立的磁碟系統!效能上差非常多! 而且 RAID 1 與 RAID 0 是不需要經過計算的 (striping) !讀寫效能也比其他的 RAID 等級好太多了!
  • RAID 5:效能與資料備份的均衡考量

RAID-5 至少需要三顆以上的磁碟才能夠組成這種類型的磁碟陣列。這種磁碟陣列的資料寫入有點類似 RAID-0 , 不過每個循環的寫入過程中 (striping),在每顆磁碟還加入一個同位檢查資料 (Parity) ,這個資料會記錄其他磁碟的備份資料, 用於當有磁碟損毀時的救援。RAID-5 讀寫的情況有點像底下這樣:

RAID-5 的磁碟寫入示意圖
圖14.2.4、RAID-5 的磁碟寫入示意圖

如上圖所示,每個循環寫入時,都會有部分的同位檢查碼 (parity) 被記錄起來,並且記錄的同位檢查碼每次都記錄在不同的磁碟, 因此,任何一個磁碟損毀時都能夠藉由其他磁碟的檢查碼來重建原本磁碟內的資料喔!不過需要注意的是, 由於有同位檢查碼,因此 RAID 5 的總容量會是整體磁碟數量減一顆。以上圖為例, 原本的 3 顆磁碟只會剩下 (3-1)=2 顆磁碟的容量。而且當損毀的磁碟數量大於等於兩顆時,這整組 RAID 5 的資料就損毀了。 因為 RAID 5 預設僅能支援一顆磁碟的損毀情況

在讀寫效能的比較上,讀取的效能還不賴!與 RAID-0 有的比!不過寫的效能就不見得能夠增加很多! 這是因為要寫入 RAID 5 的資料還得要經過計算同位檢查碼 (parity) 的關係。由於加上這個計算的動作, 所以寫入的效能與系統的硬體關係較大!尤其當使用軟體磁碟陣列時,同位檢查碼是透過 CPU 去計算而非專職的磁碟陣列卡, 因此效能方面還需要評估。

另外,由於 RAID 5 僅能支援一顆磁碟的損毀,因此近來還有發展出另外一種等級,就是 RAID 6 ,這個 RAID 6 則使用兩顆磁碟的容量作為 parity 的儲存,因此整體的磁碟容量就會少兩顆,但是允許出錯的磁碟數量就可以達到兩顆了! 也就是在 RAID 6 的情況下,同時兩顆磁碟損毀時,資料還是可以救回來!

  • Spare Disk:預備磁碟的功能:

當磁碟陣列的磁碟損毀時,就得要將壞掉的磁碟拔除,然後換一顆新的磁碟。換成新磁碟並且順利啟動磁碟陣列後, 磁碟陣列就會開始主動的重建 (rebuild) 原本壞掉的那顆磁碟資料到新的磁碟上!然後你磁碟陣列上面的資料就復原了! 這就是磁碟陣列的優點。不過,我們還是得要動手拔插硬碟,除非你的系統有支援熱拔插,否則通常得要關機才能這麼做。

為了讓系統可以即時的在壞掉硬碟時主動的重建,因此就需要預備磁碟 (spare disk) 的輔助。 所謂的 spare disk 就是一顆或多顆沒有包含在原本磁碟陣列等級中的磁碟,這顆磁碟平時並不會被磁碟陣列所使用, 當磁碟陣列有任何磁碟損毀時,則這顆 spare disk 會被主動的拉進磁碟陣列中,並將壞掉的那顆硬碟移出磁碟陣列! 然後立即重建資料系統。如此你的系統則可以永保安康啊!若你的磁碟陣列有支援熱拔插那就更完美了! 直接將壞掉的那顆磁碟拔除換一顆新的,再將那顆新的設定成為 spare disk ,就完成了!

舉例來說,鳥哥之前所待的研究室有一個磁碟陣列可允許 16 顆磁碟的數量,不過我們只安裝了 10 顆磁碟作為 RAID 5。 每顆磁碟的容量為 250GB,我們用了一顆磁碟作為 spare disk ,並將其他的 9 顆設定為一個 RAID 5, 因此這個磁碟陣列的總容量為: (9-1)*250G=2000G。運作了一兩年後真的有一顆磁碟壞掉了,我們後來看燈號才發現! 不過對系統沒有影響呢!因為 spare disk 主動的加入支援,壞掉的那顆拔掉換顆新的,並重新設定成為 spare 後, 系統內的資料還是完整無缺的!嘿嘿!真不錯!

  • 磁碟陣列的優點

說的口沫橫飛,重點在哪裡呢?其實你的系統如果需要磁碟陣列的話,其實重點在於:

  1. 資料安全與可靠性:指的並非網路資訊安全,而是當硬體 (指磁碟) 損毀時,資料是否還能夠安全的救援或使用之意;
  2. 讀寫效能:例如 RAID 0 可以加強讀寫效能,讓你的系統 I/O 部分得以改善;
  3. 容量:可以讓多顆磁碟組合起來,故單一檔案系統可以有相當大的容量。

尤其資料的可靠性與完整性更是使用 RAID 的考量重點!畢竟硬體壞掉換掉就好了,軟體資料損毀那可不是鬧著玩的! 所以企業界為何需要大量的 RAID 來做為檔案系統的硬體基準,現在您有點瞭解了吧?那依據這三個重點,我們來列表看看上面幾個重要的 RAID 等級各有哪些優點吧!假設有 n 顆磁碟組成的 RAID 設定喔!

項目RAID0RAID1RAID10RAID5RAID6
最少磁碟數22434
最大容錯磁碟數(1)n-1n/212
資料安全性(1)完全沒有最佳最佳比 RAID5 好
理論寫入效能(2)n1n/2<n-1<n-2
理論讀出效能(2)nnn<n-1<n-2
可用容量(3)n1n/2n-1n-2
一般應用強調效能但資料不重要的環境資料與備份伺服器、雲系統常用資料與備份資料與備份

註:因為 RAID5, RAID6 讀寫都需要經過 parity 的計算機制,因此讀/寫效能都不會剛好滿足於使用的磁碟數量喔!

另外,根據使用的情況不同,一般推薦的磁碟陣列等級也不太一樣。以鳥哥為例,在鳥哥的跑空氣品質模式之後的輸出資料,動輒幾百 GB 的單一大檔案資料, 這些情況鳥哥會選擇放在 RAID6 的陣列環境下,這是考量到資料保全與總容量的應用,因為 RAID 6 的效能已經足以應付模式讀入所需的環境。

近年來鳥哥也比較積極在作一些雲程式環境的設計,在雲環境下,確保每個虛擬機器能夠快速的反應以及提供資料保全是最重要的部份! 因此效能方面比較弱的 RAID5/RAID6 是不考慮的,總結來說,大概就剩下 RAID10 能夠滿足雲環境的效能需求了。在某些更特別的環境下, 如果搭配 SSD 那才更具有效能上的優勢哩!

14.2.2 software, hardware RAID

為何磁碟陣列又分為硬體與軟體呢?所謂的硬體磁碟陣列 (hardware RAID) 是透過磁碟陣列卡來達成陣列的目的。 磁碟陣列卡上面有一塊專門的晶片在處理 RAID 的任務,因此在效能方面會比較好。在很多任務 (例如 RAID 5 的同位檢查碼計算) 磁碟陣列並不會重複消耗原本系統的 I/O 匯流排,理論上效能會較佳。此外目前一般的中高階磁碟陣列卡都支援熱拔插, 亦即在不關機的情況下抽換損壞的磁碟,對於系統的復原與資料的可靠性方面非常的好用。

不過一塊好的磁碟陣列卡動不動就上萬元台幣,便宜的在主機板上面『附贈』的磁碟陣列功能可能又不支援某些高階功能, 例如低階主機板若有磁碟陣列晶片,通常僅支援到 RAID0 與 RAID1 ,鳥哥喜歡的 RAID6 並沒有支援。 此外,作業系統也必須要擁有磁碟陣列卡的驅動程式,才能夠正確的捉到磁碟陣列所產生的磁碟機!

由於磁碟陣列有很多優秀的功能,然而硬體磁碟陣列卡偏偏又貴的很~因此就有發展出利用軟體來模擬磁碟陣列的功能, 這就是所謂的軟體磁碟陣列 (software RAID)。軟體磁碟陣列主要是透過軟體來模擬陣列的任務, 因此會損耗較多的系統資源,比如說 CPU 的運算與 I/O 匯流排的資源等。不過目前我們的個人電腦實在已經非常快速了, 因此以前的速度限制現在已經不存在!所以我們可以來玩一玩軟體磁碟陣列!

我們的 CentOS 提供的軟體磁碟陣列為 mdadm 這套軟體,這套軟體會以 partition 或 disk 為磁碟的單位,也就是說,你不需要兩顆以上的磁碟,只要有兩個以上的分割槽 (partition) 就能夠設計你的磁碟陣列了。此外, mdadm 支援剛剛我們前面提到的 RAID0/RAID1/RAID5/spare disk 等! 而且提供的管理機制還可以達到類似熱拔插的功能,可以線上 (檔案系統正常使用) 進行分割槽的抽換! 使用上也非常的方便呢!

另外你必須要知道的是,硬體磁碟陣列在 Linux 底下看起來就是一顆實際的大磁碟,因此硬體磁碟陣列的裝置檔名為 /dev/sd[a-p] ,因為使用到 SCSI 的模組之故。至於軟體磁碟陣列則是系統模擬的,因此使用的裝置檔名是系統的裝置檔, 檔名為 /dev/md0, /dev/md1...,兩者的裝置檔名並不相同!不要搞混了喔!因為很多朋友常常覺得奇怪, 怎麼他的 RAID 檔名跟我們這裡測試的軟體 RAID 檔名不同,所以這裡特別強調說明喔!

Tips 鳥哥 Intel 的南橋附贈的磁碟陣列功能,在 windows 底下似乎是完整的磁碟陣列,但是在 Linux 底下則被視為是軟體磁碟陣列的一種! 因此如果你有設定過 Intel 的南橋晶片磁碟陣列,那在 Linux 底下反而還會是 /dev/md126, /dev/md127 等等裝置檔名, 而他的分割槽竟然是 /dev/md126p1, /dev/md126p2... 之類的喔!比較特別,所以這裡加強說明!

14.2.3 軟體磁碟陣列的設定

軟體磁碟陣列的設定很簡單呢!簡單到讓你很想笑喔!因為你只要使用一個指令即可!那就是 mdadm 這個指令。 這個指令在建立 RAID 的語法有點像這樣:

[root@study ~]# mdadm --detail /dev/md0
[root@study ~]# mdadm --create /dev/md[0-9] --auto=yes --level=[015] --chunk=NK \
> --raid-devices=N --spare-devices=N /dev/sdx /dev/hdx...
選項與參數:
--create          :為建立 RAID 的選項;
--auto=yes        :決定建立後面接的軟體磁碟陣列裝置,亦即 /dev/md0, /dev/md1...
--chunk=Nk        :決定這個裝置的 chunk 大小,也可以當成 stripe 大小,一般是 64K 或 512K。
--raid-devices=N  :使用幾個磁碟 (partition) 作為磁碟陣列的裝置
--spare-devices=N :使用幾個磁碟作為備用 (spare) 裝置
--level=[015]     :設定這組磁碟陣列的等級。支援很多,不過建議只要用 0, 1, 5 即可
--detail          :後面所接的那個磁碟陣列裝置的詳細資訊

上面的語法中,最後面會接許多的裝置檔名,這些裝置檔名可以是整顆磁碟,例如 /dev/sdb , 也可以是分割槽,例如 /dev/sdb1 之類。不過,這些裝置檔名的總數必須要等於 --raid-devices 與 --spare-devices 的個數總和才行!鳥哥利用我的測試機來建置一個 RAID 5 的軟體磁碟陣列給您瞧瞧! 底下是鳥哥希望做成的 RAID 5 環境:

  • 利用 4 個 partition 組成 RAID 5;
  • 每個 partition 約為 1GB 大小,需確定每個 partition 一樣大較佳;
  • 利用 1 個 partition 設定為 spare disk
  • chunk 設定為 256K 這麼大即可!
  • 這個 spare disk 的大小與其他 RAID 所需 partition 一樣大!
  • 將此 RAID 5 裝置掛載到 /srv/raid 目錄下

最終我需要 5 個 1GB 的 partition。在鳥哥的測試機中,根據前面的章節實做下來,包括課後的情境模擬題目,目前應該還有 8GB 可供利用! 因此就利用這部測試機的 /dev/vda 切出 5 個 1G 的分割槽。實際的流程鳥哥就不一一展示了,自己透過 gdisk /dev/vda 實作一下! 最終這部測試機的結果應該如下所示:

[root@study ~]# gdisk -l /dev/vda
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            6143   2.0 MiB     EF02
   2            6144         2103295   1024.0 MiB  0700
   3         2103296        65026047   30.0 GiB    8E00
   4        65026048        67123199   1024.0 MiB  8300  Linux filesystem
   5        67123200        69220351   1024.0 MiB  FD00  Linux RAID
   6        69220352        71317503   1024.0 MiB  FD00  Linux RAID
   7        71317504        73414655   1024.0 MiB  FD00  Linux RAID
   8        73414656        75511807   1024.0 MiB  FD00  Linux RAID
   9        75511808        77608959   1024.0 MiB  FD00  Linux RAID
# 上面特殊字體的部份就是我們需要的那 5 個 partition 囉!注意注意!

[root@study ~]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda             252:0    0   40G  0 disk
|-vda1          252:1    0    2M  0 part
|-vda2          252:2    0    1G  0 part /boot
|-vda3          252:3    0   30G  0 part
| |-centos-root 253:0    0   10G  0 lvm  /
| |-centos-swap 253:1    0    1G  0 lvm  [SWAP]
| `-centos-home 253:2    0    5G  0 lvm  /home
|-vda4          252:4    0    1G  0 part /srv/myproject
|-vda5          252:5    0    1G  0 part
|-vda6          252:6    0    1G  0 part
|-vda7          252:7    0    1G  0 part
|-vda8          252:8    0    1G  0 part
`-vda9          252:9    0    1G  0 part
  • 以 mdadm 建置 RAID

接下來就簡單啦!透過 mdadm 來建立磁碟陣列先!

[root@study ~]# mdadm --create /dev/md0 --auto=yes --level=5 --chunk=256K \
>  --raid-devices=4 --spare-devices=1 /dev/vda{5,6,7,8,9}
mdadm: /dev/vda5 appears to contain an ext2fs file system
       size=1048576K  mtime=Thu Jun 25 00:35:01 2015   # 某些時刻會出現這個東西!沒關係的!
Continue creating array? y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
# 詳細的參數說明請回去前面看看囉!這裡我透過 {} 將重複的項目簡化!
# 此外,因為鳥哥這個系統經常在建置測試的環境,因此系統可能會抓到之前的 filesystem 
# 所以就會出現如上前兩行的訊息!那沒關係的!直接按下 y 即可刪除舊系統

[root@study ~]# mdadm --detail /dev/md0
/dev/md0:                                           # RAID 的裝置檔名
        Version : 1.2
  Creation Time : Mon Jul 27 15:17:20 2015          # 建置 RAID 的時間
     Raid Level : raid5                             # 這就是 RAID5 等級!
     Array Size : 3142656 (3.00 GiB 3.22 GB)        # 整組 RAID 的可用容量
  Used Dev Size : 1047552 (1023.17 MiB 1072.69 MB)  # 每顆磁碟(裝置)的容量
   Raid Devices : 4                                 # 組成 RAID 的磁碟數量
  Total Devices : 5                                 # 包括 spare 的總磁碟數
    Persistence : Superblock is persistent

    Update Time : Mon Jul 27 15:17:31 2015
          State : clean                             # 目前這個磁碟陣列的使用狀態
 Active Devices : 4                                 # 啟動(active)的裝置數量
Working Devices : 5                                 # 目前使用於此陣列的裝置數
 Failed Devices : 0                                 # 損壞的裝置數
  Spare Devices : 1                                 # 預備磁碟的數量

         Layout : left-symmetric
     Chunk Size : 256K                              # 就是 chunk 的小區塊容量

           Name : study.centos.vbird:0  (local to host study.centos.vbird)
           UUID : 2256da5f:4870775e:cf2fe320:4dfabbc6
         Events : 18

    Number   Major   Minor   RaidDevice State
       0     252        5        0      active sync   /dev/vda5
       1     252        6        1      active sync   /dev/vda6
       2     252        7        2      active sync   /dev/vda7
       5     252        8        3      active sync   /dev/vda8

       4     252        9        -      spare   /dev/vda9
# 最後五行就是這五個裝置目前的情況,包括四個 active sync 一個 spare !
# 至於 RaidDevice  指的則是此 RAID 內的磁碟順序

由於磁碟陣列的建置需要一些時間,所以你最好等待數分鐘後再使用『 mdadm --detail /dev/md0 』去查閱你的磁碟陣列詳細資訊! 否則有可能看到某些磁碟正在『spare rebuilding』之類的建置字樣!透過上面的指令, 你就能夠建立一個 RAID5 且含有一顆 spare disk 的磁碟陣列囉!非常簡單吧! 除了指令之外,你也可以查閱如下的檔案來看看系統軟體磁碟陣列的情況:

[root@study ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 vda8[5] vda9[4](S) vda7[2] vda6[1] vda5[0]                <==第一行
      3142656 blocks super 1.2 level 5, 256k chunk, algorithm 2 [4/4] [UUUU] <==第二行

unused devices: <none>

上述的資料比較重要的在特別指出的第一行與第二行部分(註3):

  • 第一行部分:指出 md0 為 raid5 ,且使用了 vda8, vda7, vda6, vda5 等四顆磁碟裝置。每個裝置後面的中括號 [] 內的數字為此磁碟在 RAID 中的順序 (RaidDevice);至於 vda9 後面的 [S] 則代表 vda9 為 spare 之意。

  • 第二行:此磁碟陣列擁有 3142656 個block(每個 block 單位為 1K),所以總容量約為 3GB, 使用 RAID 5 等級,寫入磁碟的小區塊 (chunk) 大小為 256K,使用 algorithm 2 磁碟陣列演算法。 [m/n] 代表此陣列需要 m 個裝置,且 n 個裝置正常運作。因此本 md0 需要 4 個裝置且這 4 個裝置均正常運作。 後面的 [UUUU] 代表的是四個所需的裝置 (就是 [m/n] 裡面的 m) 的啟動情況,U 代表正常運作,若為 _ 則代表不正常。

這兩種方法都可以知道目前的磁碟陣列狀態啦!

  • 格式化與掛載使用 RAID

接下來就是開始使用格式化工具啦!這部分就需要注意喔!因為涉及到 xfs 檔案系統的優化!還記得第七章的內容吧?我們這裡的參數為:

  • srtipe (chunk) 容量為 256K,所以 su=256k
  • 共有 4 顆組成 RAID5 ,因此容量少一顆,所以 sw=3 喔!
  • 由上面兩項計算出資料寬度為: 256K*3=768k

所以整體來說,要優化這個 XFS 檔案系統就變成這樣:

[root@study ~]# mkfs.xfs -f -d su=256k,sw=3 -r extsize=768k /dev/md0
# 有趣吧!是 /dev/md0 做為裝置被格式化呢!

[root@study ~]# mkdir /srv/raid
[root@study ~]# mount /dev/md0 /srv/raid
[root@study ~]# df -Th /srv/raid
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/md0       xfs   3.0G   33M  3.0G   2% /srv/raid
# 看吧!多了一個 /dev/md0 的裝置,而且真的可以讓你使用呢!還不賴!

14.2.4 模擬 RAID 錯誤的救援模式

俗話說『天有不測風雲、人有旦夕禍福』,誰也不知道你的磁碟陣列內的裝置啥時會出差錯,因此, 瞭解一下軟體磁碟陣列的救援還是必須的!底下我們就來玩一玩救援的機制吧!首先來瞭解一下 mdadm 這方面的語法:

[root@study ~]# mdadm --manage /dev/md[0-9] [--add 裝置] [--remove 裝置] [--fail 裝置] 
選項與參數:
--add    :會將後面的裝置加入到這個 md 中!
--remove :會將後面的裝置由這個 md 中移除
--fail   :會將後面的裝置設定成為出錯的狀態
  • 設定磁碟為錯誤 (fault)

首先,我們來處理一下,該如何讓一個磁碟變成錯誤,然後讓 spare disk 自動的開始重建系統呢?

# 0. 先複製一些東西到 /srv/raid 去,假設這個 RAID 已經在使用了
[root@study ~]# cp -a /etc /var/log /srv/raid
[root@study ~]# df -Th /srv/raid ; du -sm /srv/raid/*
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/md0       xfs   3.0G  144M  2.9G   5% /srv/raid
28      /srv/raid/etc  <==看吧!確實有資料在裡面喔!
51      /srv/raid/log

# 1. 假設 /dev/vda7 這個裝置出錯了!實際模擬的方式:
[root@study ~]# mdadm --manage /dev/md0 --fail /dev/vda7
mdadm: set /dev/vda7 faulty in /dev/md0      # 設定成為錯誤的裝置囉!
/dev/md0:
.....(中間省略).....
    Update Time : Mon Jul 27 15:32:50 2015
          State : clean, degraded, recovering
 Active Devices : 3
Working Devices : 4
 Failed Devices : 1      <==出錯的磁碟有一個!
  Spare Devices : 1
.....(中間省略).....

    Number   Major   Minor   RaidDevice State
       0     252        5        0      active sync   /dev/vda5
       1     252        6        1      active sync   /dev/vda6
       4     252        9        2      spare rebuilding   /dev/vda9
       5     252        8        3      active sync   /dev/vda8

       2     252        7        -      faulty   /dev/vda7
# 看到沒!這的動作要快做才會看到! /dev/vda9 啟動了而 /dev/vda7 死掉了

上面的畫面你得要快速的連續輸入那些 mdadm 的指令才看的到!因為你的 RAID 5 正在重建系統! 若你等待一段時間再輸入後面的觀察指令,則會看到如下的畫面了:

# 2. 已經藉由 spare disk 重建完畢的 RAID 5 情況
[root@study ~]# mdadm --detail /dev/md0
....(前面省略)....
    Number   Major   Minor   RaidDevice State
       0     252        5        0      active sync   /dev/vda5
       1     252        6        1      active sync   /dev/vda6
       4     252        9        2      active sync   /dev/vda9
       5     252        8        3      active sync   /dev/vda8

       2     252        7        -      faulty   /dev/vda7

看吧!又恢復正常了!真好!我們的 /srv/raid 檔案系統是完整的!並不需要卸載!很棒吧!

  • 將出錯的磁碟移除並加入新磁碟

因為我們的系統那個 /dev/vda7 實際上沒有壞掉啊!只是用來模擬而已啊!因此,如果有新的磁碟要替換,其實替換的名稱會一樣啊! 也就是我們需要:

  1. 先從 /dev/md0 陣列中移除 /dev/vda7 這顆『磁碟』
  2. 整個 Linux 系統關機,拔出 /dev/vda7 這顆『磁碟』,並安裝上新的 /dev/vda7 『磁碟』,之後開機
  3. 將新的 /dev/vda7 放入 /dev/md0 陣列當中!
# 3. 拔除『舊的』/dev/vda7 磁碟
[root@study ~]# mdadm --manage /dev/md0 --remove /dev/vda7
# 假設接下來你就進行了上面談到的第 2, 3 個步驟,然後重新開機成功了!

# 4. 安裝『新的』/dev/vda7 磁碟
[root@study ~]# mdadm --manage /dev/md0 --add /dev/vda7
[root@study ~]# mdadm --detail /dev/md0
....(前面省略)....
    Number   Major   Minor   RaidDevice State
       0     252        5        0      active sync   /dev/vda5
       1     252        6        1      active sync   /dev/vda6
       4     252        9        2      active sync   /dev/vda9
       5     252        8        3      active sync   /dev/vda8

       6     252        7        -      spare   /dev/vda7

嘿嘿!你的磁碟陣列內的資料不但一直存在,而且你可以一直順利的運作 /srv/raid 內的資料,即使 /dev/vda7 損毀了!然後透過管理的功能就能夠加入新磁碟且拔除壞掉的磁碟!注意,這一切都是在上線 (on-line) 的情況下進行! 所以,您說這樣的咚咚好不好用啊! ^_^

14.2.5 開機自動啟動 RAID 並自動掛載

新的 distribution 大多會自己搜尋 /dev/md[0-9] 然後在開機的時候給予設定好所需要的功能。不過鳥哥還是建議你, 修改一下設定檔吧! ^_^。software RAID 也是有設定檔的,這個設定檔在 /etc/mdadm.conf !這個設定檔內容很簡單, 你只要知道 /dev/md0 的 UUID 就能夠設定這個檔案啦!這裡鳥哥僅介紹他最簡單的語法:

[root@study ~]# mdadm --detail /dev/md0 | grep -i uuid
           UUID : 2256da5f:4870775e:cf2fe320:4dfabbc6
# 後面那一串資料,就是這個裝置向系統註冊的 UUID 識別碼!

# 開始設定 mdadm.conf
[root@study ~]# vim /etc/mdadm.conf
ARRAY /dev/md0 UUID=2256da5f:4870775e:cf2fe320:4dfabbc6
#     RAID裝置      識別碼內容

# 開始設定開機自動掛載並測試
[root@study ~]# blkid /dev/md0
/dev/md0: UUID="494cb3e1-5659-4efc-873d-d0758baec523" TYPE="xfs"

[root@study ~]# vim /etc/fstab
UUID=494cb3e1-5659-4efc-873d-d0758baec523  /srv/raid xfs defaults 0 0

[root@study ~]# umount /dev/md0; mount -a
[root@study ~]# df -Th /srv/raid
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/md0       xfs   3.0G  111M  2.9G   4% /srv/raid
# 你得確定可以順利掛載,並且沒有發生任何錯誤!

如果到這裡都沒有出現任何問題!接下來就請 reboot 你的系統並等待看看能否順利的啟動吧! ^_^

14.2.6 關閉軟體 RAID(重要!)

除非你未來就是要使用這顆 software RAID (/dev/md0),否則你勢必要跟鳥哥一樣,將這個 /dev/md0 關閉! 因為他畢竟是我們在這個測試機上面的練習裝置啊!為什麼要關掉他呢?因為這個 /dev/md0 其實還是使用到我們系統的磁碟分割槽, 在鳥哥的例子裡面就是 /dev/vda{5,6,7,8,9},如果你只是將 /dev/md0 卸載,然後忘記將 RAID 關閉, 結果就是....未來你在重新分割 /dev/vdaX 時可能會出現一些莫名的錯誤狀況啦!所以才需要關閉 software RAID 的步驟! 那如何關閉呢?也是簡單到爆炸!(請注意,確認你的 /dev/md0 確實不要用且要關閉了才進行底下的玩意兒)

# 1. 先卸載且刪除設定檔內與這個 /dev/md0 有關的設定:
[root@study ~]# umount /srv/raid
[root@study ~]# vim /etc/fstab
UUID=494cb3e1-5659-4efc-873d-d0758baec523  /srv/raid xfs defaults 0 0
# 將這一行刪除掉!或者是註解掉也可以!

# 2. 先覆蓋掉 RAID 的 metadata 以及 XFS 的 superblock,才關閉 /dev/md0 的方法
[root@study ~]# dd if=/dev/zero of=/dev/md0 bs=1M count=50
[root@study ~]# mdadm --stop /dev/md0
mdadm: stopped /dev/md0  <==不囉唆!這樣就關閉了!
[root@study ~]# dd if=/dev/zero of=/dev/vda5 bs=1M count=10
[root@study ~]# dd if=/dev/zero of=/dev/vda6 bs=1M count=10
[root@study ~]# dd if=/dev/zero of=/dev/vda7 bs=1M count=10
[root@study ~]# dd if=/dev/zero of=/dev/vda8 bs=1M count=10
[root@study ~]# dd if=/dev/zero of=/dev/vda9 bs=1M count=10

[root@study ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
unused devices: <none>  <==看吧!確實不存在任何陣列裝置!

[root@study ~]# vim /etc/mdadm.conf
#ARRAY /dev/md0 UUID=2256da5f:4870775e:cf2fe320:4dfabbc6
# 一樣啦!刪除他或是註解他!

你可能會問,鳥哥啊,為啥上面會有數個 dd 的指令啊?幹麻?這是因為 RAID 的相關資料其實也會存一份在磁碟當中,因此,如果你只是將設定檔移除, 同時關閉了 RAID,但是分割槽並沒有重新規劃過,那麼重新開機過後,系統還是會將這顆磁碟陣列建立起來,只是名稱可能會變成 /dev/md127 就是了! 因此,移除掉 Software RAID 時,上述的 dd 指令不要忘記!但是...千千萬萬不要 dd 到錯誤的磁碟~那可是會欲哭無淚耶~

Tips 鳥哥 在這個練習中,鳥哥使用同一顆磁碟進行軟體 RAID 的實驗。不過朋友們要注意的是,如果真的要實作軟體磁碟陣列, 最好是由多顆不同的磁碟來組成較佳!因為這樣才能夠使用到不同磁碟的讀寫,效能才會好! 而資料分配在不同的磁碟,當某顆磁碟損毀時資料才能夠藉由其他磁碟挽救回來!這點得特別留意呢!

14.3 邏輯捲軸管理員 (Logical Volume Manager)

想像一個情況,你在當初規劃主機的時候將 /home 只給他 50G ,等到使用者眾多之後導致這個 filesystem 不夠大, 此時你能怎麼作?多數的朋友都是這樣:再加一顆新硬碟,然後重新分割、格式化,將 /home 的資料完整的複製過來, 然後將原本的 partition 卸載重新掛載新的 partition 。啊!好忙碌啊!若是第二次分割卻給的容量太多!導致很多磁碟容量被浪費了! 你想要將這個 partition 縮小時,又該如何作?將上述的流程再搞一遍!唉~煩死了,尤其複製很花時間ㄟ~有沒有更簡單的方法呢? 有的!那就是我們這個小節要介紹的 LVM 這玩意兒!

LVM 的重點在於『可以彈性的調整 filesystem 的容量!』而並非在於效能與資料保全上面。 需要檔案的讀寫效能或者是資料的可靠性,請參考前面的 RAID 小節。 LVM 可以整合多個實體 partition 在一起, 讓這些 partitions 看起來就像是一個磁碟一樣!而且,還可以在未來新增或移除其他的實體 partition 到這個 LVM 管理的磁碟當中。 如此一來,整個磁碟空間的使用上,實在是相當的具有彈性啊! 既然 LVM 這麼好用,那就讓我們來瞧瞧這玩意吧!

14.3.1 什麼是 LVM: PV, PE, VG, LV 的意義

LVM 的全名是 Logical Volume Manager,中文可以翻譯作邏輯捲軸管理員。之所以稱為『捲軸』可能是因為可以將 filesystem 像捲軸一樣伸長或縮短之故吧!LVM 的作法是將幾個實體的 partitions (或 disk) 透過軟體組合成為一塊看起來是獨立的大磁碟 (VG) ,然後將這塊大磁碟再經過分割成為可使用分割槽 (LV), 最終就能夠掛載使用了。但是為什麼這樣的系統可以進行 filesystem 的擴充或縮小呢?其實與一個稱為 PE 的項目有關! 底下我們就得要針對這幾個項目來好好聊聊!

  • Physical Volume, PV, 實體捲軸

我們實際的 partition (或 Disk) 需要調整系統識別碼 (system ID) 成為 8e (LVM 的識別碼),然後再經過 pvcreate 的指令將他轉成 LVM 最底層的實體捲軸 (PV) ,之後才能夠將這些 PV 加以利用! 調整 system ID 的方是就是透過 gdisk 啦!

  • Volume Group, VG, 捲軸群組

所謂的 LVM 大磁碟就是將許多 PV 整合成這個 VG 的東西就是啦!所以 VG 就是 LVM 組合起來的大磁碟!這麼想就好了。 那麼這個大磁碟最大可以到多少容量呢?這與底下要說明的 PE 以及 LVM 的格式版本有關喔~在預設的情況下, 使用 32位元的 Linux 系統時,基本上 LV 最大僅能支援到 65534 個 PE 而已,若使用預設的 PE 為 4MB 的情況下, 最大容量則僅能達到約 256GB 而已~不過,這個問題在 64位元的 Linux 系統上面已經不存在了!LV 幾乎沒有啥容量限制了!

  • Physical Extent, PE, 實體範圍區塊

LVM 預設使用 4MB 的 PE 區塊,而 LVM 的 LV 在 32 位元系統上最多僅能含有 65534 個 PE (lvm1 的格式),因此預設的 LVM 的 LV 會有 4M*65534/(1024M/G)=256G。這個 PE 很有趣喔!他是整個 LVM 最小的儲存區塊,也就是說,其實我們的檔案資料都是藉由寫入 PE 來處理的。簡單的說,這個 PE 就有點像檔案系統裡面的 block 大小啦。 這樣說應該就比較好理解了吧?所以調整 PE 會影響到 LVM 的最大容量喔!不過,在 CentOS 6.x 以後,由於直接使用 lvm2 的各項格式功能,以及系統轉為 64 位元,因此這個限制已經不存在了。

  • Logical Volume, LV, 邏輯捲軸

最終的 VG 還會被切成 LV,這個 LV 就是最後可以被格式化使用的類似分割槽的咚咚了!那麼 LV 是否可以隨意指定大小呢? 當然不可以!既然 PE 是整個 LVM 的最小儲存單位,那麼 LV 的大小就與在此 LV 內的 PE 總數有關。 為了方便使用者利用 LVM 來管理其系統,因此 LV 的裝置檔名通常指定為『 /dev/vgname/lvname 』的樣式!

此外,我們剛剛有談到 LVM 可彈性的變更 filesystem 的容量,那是如何辦到的?其實他就是透過『交換 PE 』來進行資料轉換, 將原本 LV 內的 PE 移轉到其他裝置中以降低 LV 容量,或將其他裝置的 PE 加到此 LV 中以加大容量! VG、LV 與 PE 的關係有點像下圖:

PE 與 VG 的相關性圖示
圖14.3.1、PE 與 VG 的相關性圖示

如上圖所示,VG 內的 PE 會分給虛線部分的 LV,如果未來這個 VG 要擴充的話,加上其他的 PV 即可。 而最重要的 LV 如果要擴充的話,也是透過加入 VG 內沒有使用到的 PE 來擴充的!

  • 實作流程

透過 PV, VG, LV 的規劃之後,再利用 mkfs 就可以將你的 LV 格式化成為可以利用的檔案系統了!而且這個檔案系統的容量在未來還能夠進行擴充或減少, 而且裡面的資料還不會被影響!實在是很『福氣啦!』那實作方面要如何進行呢?很簡單呢! 整個流程由基礎到最終的結果可以這樣看:

LVM 各元件的實現流程圖示
圖14.3.2、LVM 各元件的實現流程圖示

如此一來,我們就可以利用 LV 這個玩意兒來進行系統的掛載了。不過,你應該要覺得奇怪的是, 那麼我的資料寫入這個 LV 時,到底他是怎麼寫入硬碟當中的? 呵呵!好問題~其實,依據寫入機制的不同,而有兩種方式:

  • 線性模式 (linear):假如我將 /dev/vda1, /dev/vdb1 這兩個 partition 加入到 VG 當中,並且整個 VG 只有一個 LV 時,那麼所謂的線性模式就是:當 /dev/vda1 的容量用完之後,/dev/vdb1 的硬碟才會被使用到, 這也是我們所建議的模式。

  • 交錯模式 (triped):那什麼是交錯模式?很簡單啊,就是我將一筆資料拆成兩部分,分別寫入 /dev/vda1 與 /dev/vdb1 的意思,感覺上有點像 RAID 0 啦!如此一來,一份資料用兩顆硬碟來寫入,理論上,讀寫的效能會比較好。

基本上,LVM 最主要的用處是在實現一個可以彈性調整容量的檔案系統上, 而不是在建立一個效能為主的磁碟上,所以,我們應該利用的是 LVM 可以彈性管理整個 partition 大小的用途上,而不是著眼在效能上的。因此, LVM 預設的讀寫模式是線性模式啦! 如果你使用 triped 模式,要注意,當任何一個 partition 『歸天』時,所有的資料都會『損毀』的! 所以啦,不是很適合使用這種模式啦!如果要強調效能與備份,那麼就直接使用 RAID 即可, 不需要用到 LVM 啊!

14.3.2 LVM 實作流程

LVM 必需要核心有支援且需要安裝 lvm2 這個軟體,好佳在的是, CentOS 與其他較新的 distributions 已經預設將 lvm 的支援與軟體都安裝妥當了!所以你不需要擔心這方面的問題!用就對了!

假設你剛剛也是透過同樣的方法來處理鳥哥的測試機 RAID 實作,那麼現在應該有 5 個可用的分割槽才對! 不過,建議你還是得要修改一下 system ID 比較好!將 RAID 的 fd 改為 LVM 的 8e 吧!現在,我們實作 LVM 有點像底下的模樣:

  • 使用 4 個 partition ,每個 partition 的容量均為 1GB 左右,且 system ID 需要為 8e;
  • 全部的 partition 整合成為一個 VG,VG 名稱設定為 vbirdvg;且 PE 的大小為 16MB;
  • 建立一個名為 vbirdlv 的 LV,容量大約 2G 好了!
  • 最終這個 LV 格式化為 xfs 的檔案系統,且掛載在 /srv/lvm 中
  • 0. Disk 階段 (實際的磁碟)

鳥哥就不仔細的介紹實體分割了,請您自行參考第七章的 gdisk 來達成底下的範例:

[root@study ~]# gdisk -l /dev/vda
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            6143   2.0 MiB     EF02
   2            6144         2103295   1024.0 MiB  0700
   3         2103296        65026047   30.0 GiB    8E00
   4        65026048        67123199   1024.0 MiB  8300  Linux filesystem
   5        67123200        69220351   1024.0 MiB  8E00  Linux LVM
   6        69220352        71317503   1024.0 MiB  8E00  Linux LVM
   7        71317504        73414655   1024.0 MiB  8E00  Linux LVM
   8        73414656        75511807   1024.0 MiB  8E00  Linux LVM
   9        75511808        77608959   1024.0 MiB  8E00  Linux LVM
# 其實 system ID 不改變也沒關係!只是為了讓我們管理員清楚知道該 partition 的內容,
# 所以這裡建議還是修訂成正確的磁碟內容較佳!

上面的 /dev/vda{5,6,7,8} 這 4 個分割槽就是我們的實體分割槽!也就是底下會實際用到的資訊!至於 /dev/vda9 則先保留下來不使用。 注意看,那個 8e 的出現會導致 system 變成『 Linux LVM 』哩!其實沒有設定成為 8e 也沒關係, 不過某些 LVM 的偵測指令可能會偵測不到該 partition 就是了!接下來,就一個一個的處理各流程吧!

  • 1. PV 階段

要建立 PV 其實很簡單,只要直接使用 pvcreate 即可!我們來談一談與 PV 有關的指令吧!

  • pvcreate :將實體 partition 建立成為 PV ;
  • pvscan :搜尋目前系統裡面任何具有 PV 的磁碟;
  • pvdisplay :顯示出目前系統上面的 PV 狀態;
  • pvremove :將 PV 屬性移除,讓該 partition 不具有 PV 屬性。

那就直接來瞧一瞧吧!

# 1. 檢查有無 PV 在系統上,然後將 /dev/vda{5-8} 建立成為 PV 格式
[root@study ~]# pvscan
  PV /dev/vda3   VG centos   lvm2 [30.00 GiB / 14.00 GiB free]
  Total: 1 [30.00 GiB] / in use: 1 [30.00 GiB] / in no VG: 0 [0   ]
# 其實安裝的時候,我們就有使用 LVM 了喔!所以會有 /dev/vda3 存在的!

[root@study ~]# pvcreate /dev/vda{5,6,7,8}
  Physical volume "/dev/vda5" successfully created
  Physical volume "/dev/vda6" successfully created
  Physical volume "/dev/vda7" successfully created
  Physical volume "/dev/vda8" successfully created
# 這個指令可以一口氣建立這四個 partition 成為 PV 啦!注意大括號的用途

[root@study ~]# pvscan
  PV /dev/vda3   VG centos   lvm2 [30.00 GiB / 14.00 GiB free]
  PV /dev/vda8               lvm2 [1.00 GiB]
  PV /dev/vda5               lvm2 [1.00 GiB]
  PV /dev/vda7               lvm2 [1.00 GiB]
  PV /dev/vda6               lvm2 [1.00 GiB]
  Total: 5 [34.00 GiB] / in use: 1 [30.00 GiB] / in no VG: 4 [4.00 GiB]
# 這就分別顯示每個 PV 的資訊與系統所有 PV 的資訊。尤其最後一行,顯示的是:
# 整體 PV 的量 / 已經被使用到 VG 的 PV 量 / 剩餘的 PV 量

# 2. 更詳細的列示出系統上面每個 PV 的個別資訊:
[root@study ~]# pvdisplay /dev/vda5
  "/dev/vda5" is a new physical volume of "1.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/vda5  <==實際的 partition 裝置名稱
  VG Name                          <==因為尚未分配出去,所以空白!
  PV Size               1.00 GiB   <==就是容量說明
  Allocatable           NO         <==是否已被分配,結果是 NO
  PE Size               0          <==在此 PV 內的 PE 大小
  Total PE              0          <==共分割出幾個 PE
  Free PE               0          <==沒被 LV 用掉的 PE
  Allocated PE          0          <==尚可分配出去的 PE 數量
  PV UUID               Cb717z-lShq-6WXf-ewEj-qg0W-MieW-oAZTR6
# 由於 PE 是在建立 VG 時才給予的參數,因此在這裡看到的 PV 裡頭的 PE 都會是 0
# 而且也沒有多餘的 PE 可供分配 (allocatable)。

講是很難,作是很簡單!這樣就將 PV 建立了起來囉!簡單到不行吧! ^_^!繼續來玩 VG 去!

  • 2. VG 階段

建立 VG 及 VG 相關的指令也不少,我們來看看:

  • vgcreate :就是主要建立 VG 的指令啦!他的參數比較多,等一下介紹。
  • vgscan :搜尋系統上面是否有 VG 存在?
  • vgdisplay :顯示目前系統上面的 VG 狀態;
  • vgextend :在 VG 內增加額外的 PV ;
  • vgreduce :在 VG 內移除 PV;
  • vgchange :設定 VG 是否啟動 (active);
  • vgremove :刪除一個 VG 啊!

與 PV 不同的是, VG 的名稱是自訂的!我們知道 PV 的名稱其實就是 partition 的裝置檔名, 但是這個 VG 名稱則可以隨便你自己取啊!在底下的例子當中,我將 VG 名稱取名為 vbirdvg 。建立這個 VG 的流程是這樣的:

[root@study ~]# vgcreate [-s N[mgt]] VG名稱 PV名稱
選項與參數:
-s :後面接 PE 的大小 (size) ,單位可以是 m, g, t (大小寫均可)

# 1. 將 /dev/vda5-7 建立成為一個 VG,且指定 PE 為 16MB 喔!
[root@study ~]# vgcreate -s 16M vbirdvg /dev/vda{5,6,7}
  Volume group "vbirdvg" successfully created

[root@study ~]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "vbirdvg" using metadata type lvm2  # 我們手動製作的
  Found volume group "centos" using metadata type lvm2   # 之前系統安裝時作的

[root@study ~]# pvscan
  PV /dev/vda5   VG vbirdvg   lvm2 [1008.00 MiB / 1008.00 MiB free]
  PV /dev/vda6   VG vbirdvg   lvm2 [1008.00 MiB / 1008.00 MiB free]
  PV /dev/vda7   VG vbirdvg   lvm2 [1008.00 MiB / 1008.00 MiB free]
  PV /dev/vda3   VG centos    lvm2 [30.00 GiB / 14.00 GiB free]
  PV /dev/vda8                lvm2 [1.00 GiB]
  Total: 5 [33.95 GiB] / in use: 4 [32.95 GiB] / in no VG: 1 [1.00 GiB]
# 嘿嘿!發現沒!有三個 PV 被用去,剩下 1 個 /dev/vda8 的 PV 沒被用掉!

[root@study ~]# vgdisplay vbirdvg
  --- Volume group ---
  VG Name               vbirdvg
  System ID
  Format                lvm2
  Metadata Areas        3
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                3
  Act PV                3
  VG Size               2.95 GiB        <==整體的 VG 容量有這麼大
  PE Size               16.00 MiB       <==內部每個 PE 的大小
  Total PE              189             <==總共的 PE 數量共有這麼多!
  Alloc PE / Size       0 / 0
  Free  PE / Size       189 / 2.95 GiB  <==尚可配置給 LV 的 PE數量/總容量有這麼多!
  VG UUID               Rx7zdR-y2cY-HuIZ-Yd2s-odU8-AkTW-okk4Ea
# 最後那三行指的就是 PE 能夠使用的情況!由於尚未切出 LV,因此所有的 PE 均可自由使用。

這樣就建立一個 VG 了!假設我們要增加這個 VG 的容量,因為我們還有 /dev/vda8 嘛!此時你可以這樣做:

# 2. 將剩餘的 PV (/dev/vda8) 丟給 vbirdvg 吧!
[root@study ~]# vgextend vbirdvg /dev/vda8
  Volume group "vbirdvg" successfully extended

[root@study ~]# vgdisplay vbirdvg
....(前面省略)....
  VG Size               3.94 GiB
  PE Size               16.00 MiB
  Total PE              252
  Alloc PE / Size       0 / 0
  Free  PE / Size       252 / 3.94 GiB
# 基本上,不難吧!這樣就可以抽換整個 VG 的大小啊!

我們多了一個裝置喔!接下來為這個 vbirdvg 進行分割吧!透過 LV 功能來處理!

  • 3. LV 階段

創造出 VG 這個大磁碟之後,再來就是要建立分割區啦!這個分割區就是所謂的 LV 囉!假設我要將剛剛那個 vbirdvg 磁碟,分割成為 vbirdlv ,整個 VG 的容量都被分配到 vbirdlv 裡面去!先來看看能使用的指令後,就直接工作了先!

  • lvcreate :建立 LV 啦!
  • lvscan :查詢系統上面的 LV ;
  • lvdisplay :顯示系統上面的 LV 狀態啊!
  • lvextend :在 LV 裡面增加容量!
  • lvreduce :在 LV 裡面減少容量;
  • lvremove :刪除一個 LV !
  • lvresize :對 LV 進行容量大小的調整!
[root@study ~]# lvcreate [-L N[mgt]] [-n LV名稱] VG名稱
[root@study ~]# lvcreate [-l N] [-n LV名稱] VG名稱
選項與參數:
-L  :後面接容量,容量的單位可以是 M,G,T 等,要注意的是,最小單位為 PE,
      因此這個數量必須要是 PE 的倍數,若不相符,系統會自行計算最相近的容量。
-l  :後面可以接 PE 的『個數』,而不是數量。若要這麼做,得要自行計算 PE 數。
-n  :後面接的就是 LV 的名稱啦!
更多的說明應該可以自行查閱吧! man lvcreate 

# 1. 將 vbirdvg 分 2GB 給 vbirdlv 喔!
[root@study ~]# lvcreate -L 2G -n vbirdlv vbirdvg
  Logical volume "vbirdlv" created
# 由於本案例中每個 PE 為 16M ,如果要用 PE 的數量來處理的話,那使用下面的指令也 OK喔!
# lvcreate -l 128 -n vbirdlv vbirdvg

[root@study ~]# lvscan
  ACTIVE            '/dev/vbirdvg/vbirdlv' [2.00 GiB] inherit  <==新增加的一個 LV 囉!
  ACTIVE            '/dev/centos/root' [10.00 GiB] inherit
  ACTIVE            '/dev/centos/home' [5.00 GiB] inherit
  ACTIVE            '/dev/centos/swap' [1.00 GiB] inherit

[root@study ~]# lvdisplay /dev/vbirdvg/vbirdlv
  --- Logical volume ---
  LV Path                /dev/vbirdvg/vbirdlv   # 這個是 LV 的全名喔!
  LV Name                vbirdlv
  VG Name                vbirdvg
  LV UUID                QJJrTC-66sm-878Y-o2DC-nN37-2nFR-0BwMmn
  LV Write Access        read/write
  LV Creation host, time study.centos.vbird, 2015-07-28 02:22:49 +0800
  LV Status              available
  # open                 0
  LV Size                2.00 GiB               # 容量就是這麼大!
  Current LE             128
  Segments               3
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:3

如此一來,整個 LV partition 也準備好啦!接下來,就是針對這個 LV 來處理啦!要特別注意的是, VG 的名稱為 vbirdvg , 但是 LV 的名稱必須使用全名!亦即是 /dev/vbirdvg/vbirdlv 才對喔! 後續的處理都是這樣的!這點初次接觸 LVM 的朋友很容易搞錯!

  • 檔案系統階段

這個部分鳥哥我就不再多加解釋了!直接來進行吧!

# 1. 格式化、掛載與觀察我們的 LV 吧!
[root@study ~]# mkfs.xfs /dev/vbirdvg/vbirdlv <==注意 LV 全名!
[root@study ~]# mkdir /srv/lvm
[root@study ~]# mount /dev/vbirdvg/vbirdlv /srv/lvm
[root@study ~]# df -Th /srv/lvm
Filesystem                  Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv xfs   2.0G   33M  2.0G   2% /srv/lvm

[root@study ~]# cp -a /etc /var/log /srv/lvm
[root@study ~]# df -Th /srv/lvm
Filesystem                  Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv xfs   2.0G  152M  1.9G   8% /srv/lvm  <==確定是可用的啊!

透過這樣的功能,我們現在已經建置好一個 LV 了!你可以自由的應用 /srv/lvm 內的所有資源!

14.3.3 放大 LV 容量

我們不是說 LVM 最大的特色就是彈性調整磁碟容量嗎?好!那我們就來處理一下,如果要放大 LV 的容量時, 該如何進行完整的步驟呢?其實一點都不難喔!如果你回去看圖 14.3.2 的話,那麼你會知道放大檔案系統時, 需要底下這些流程的:

  1. VG 階段需要有剩餘的容量:因為需要放大檔案系統,所以需要放大 LV,但是若沒有多的 VG 容量, 那麼更上層的 LV 與檔案系統就無法放大的。因此,你得要用盡各種方法來產生多的 VG 容量才行。一般來說,如果 VG 容量不足, 最簡單的方法就是再加硬碟!然後將該硬碟使用上面講過的 pvcreate 及 vgextend 增加到該 VG 內即可!

  2. LV 階段產生更多的可用容量:如果 VG 的剩餘容量足夠了, 此時就可以利用 lvresize 這個指令來將剩餘容量加入到所需要增加的 LV 裝置內!過程相當簡單!

  3. 檔案系統階段的放大:我們的 Linux 實際使用的其實不是 LV 啊!而是 LV 這個裝置內的檔案系統! 所以一切最終還是要以檔案系統為依歸!目前在 Linux 環境下,鳥哥測試過可以放大的檔案系統有 XFS 以及 EXT 家族! 至於縮小僅有 EXT 家族,目前 XFS 檔案系統並不支援檔案系統的容量縮小喔!要注意!要注意!XFS 放大檔案系統透過簡單的 xfs_growfs 指令即可!

其中最後一個步驟最重要!我們在第七章當中知道, 整個檔案系統在最初格式化的時候就建立了 inode/block/superblock 等資訊,要改變這些資訊是很難的! 不過因為檔案系統格式化的時候建置的是多個 block group ,因此我們可以透過在檔案系統當中增加 block group 的方式來增減檔案系統的量!而增減 block group 就是利用 xfs_growfs 囉!所以最後一步是針對檔案系統來處理的, 前面幾步則是針對 LVM 的實際容量大小!

Tips 鳥哥 因此,嚴格說起來,放大檔案系統並不是沒有進行『格式化』喔!放大檔案系統時,格式化的位置在於該裝置後來新增的部份,裝置的前面已經存在的檔案系統則沒有變化。 而新增的格式化過的資料,再反饋回原本的 supberblock 這樣而已!

讓我們來實作個範例,假設我們想要針對 /srv/lvm 再增加 500M 的容量,該如何處置?

# 1. 由前面的過程我們知道 /srv/lvm 是 /dev/vbirdvg/vbirdlv 這個裝置,所以檢查 vbirdvg 吧!
[root@study ~]# vgdisplay vbirdvg
  --- Volume group ---
  VG Name               vbirdvg
  System ID
  Format                lvm2
  Metadata Areas        4
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                4
  Act PV                4
  VG Size               3.94 GiB
  PE Size               16.00 MiB
  Total PE              252
  Alloc PE / Size       128 / 2.00 GiB
  Free  PE / Size       124 / 1.94 GiB    # 看起來剩餘容量確實超過 500M 的!
  VG UUID               Rx7zdR-y2cY-HuIZ-Yd2s-odU8-AkTW-okk4Ea
# 既然 VG 的容量夠大了!所以直接來放大 LV 吧!!

# 2. 放大 LV 吧!利用 lvresize 的功能來增加!
[root@study ~]# lvresize -L +500M /dev/vbirdvg/vbirdlv
  Rounding size to boundary between physical extents: 512.00 MiB
  Size of logical volume vbirdvg/vbirdlv changed from 2.00 GiB (128 extents) to 2.50 GiB 
(160 extents).
  Logical volume vbirdlv successfully resized
# 這樣就增加了 LV 了喔!lvresize 的語法很簡單,基本上同樣透過 -l 或 -L 來增加!
# 若要增加則使用 + ,若要減少則使用 - !詳細的選項請參考 man lvresize 囉!

[root@study ~]# lvscan
  ACTIVE            '/dev/vbirdvg/vbirdlv' [2.50 GiB] inherit
  ACTIVE            '/dev/centos/root' [10.00 GiB] inherit
  ACTIVE            '/dev/centos/home' [5.00 GiB] inherit
  ACTIVE            '/dev/centos/swap' [1.00 GiB] inherit
# 可以發現 /dev/vbirdvg/vbirdlv 容量由 2G 增加到 2.5G 囉!

[root@study ~]# df -Th /srv/lvm
Filesystem                  Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv xfs   2.0G  111M  1.9G   6% /srv/lvm

看到了吧?最終的結果中 LV 真的有放大到 2.5GB 喔!但是檔案系統卻沒有相對增加!而且,我們的 LVM 可以線上直接處理,並不需要特別給他 umount 哩!真是人性化! 但是還是得要處理一下檔案系統的容量啦!開始觀察一下檔案系統,然後使用 xfs_growfs 來處理一下吧!

# 3.1 先看一下原本的檔案系統內的 superblock 記錄情況吧!
[root@study ~]# xfs_info /srv/lvm
meta-data=/dev/mapper/vbirdvg-vbirdlv isize=256    agcount=4, agsize=131072 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=524288, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

[root@study ~]# xfs_growfs /srv/lvm  # 這一步驟才是最重要的!
[root@study ~]# xfs_info /srv/lvm
meta-data=/dev/mapper/vbirdvg-vbirdlv isize=256    agcount=5, agsize=131072 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=655360, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

[root@study ~]# df -Th /srv/lvm
Filesystem                  Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv xfs   2.5G  111M  2.4G   5% /srv/lvm

[root@study ~]# ls -l /srv/lvm
drwxr-xr-x. 131 root root 8192 Jul 28 00:12 etc
drwxr-xr-x.  16 root root 4096 Jul 28 00:01 log
# 剛剛複製進去的資料可還是存在的喔!並沒有消失不見!

在上表中,注意看兩次 xfs_info 的結果,你會發現到 1)整個 block group (agcount) 的數量增加一個!那個 block group 就是紀錄新的裝置容量之檔案系統所在! 而你也會 2)發現整體的 block 數量增加了!這樣整個檔案系統就給他放大了!同時,使用 df 去查閱時,就真的看到增加的量了吧! 檔案系統的放大可以在 On-line 的環境下實作耶!超棒的!

最後,請注意!目前的 XFS 檔案系統中,並沒有縮小檔案系統容量的設計!也就是說,檔案系統只能放大不能縮小喔!如果你想要保有放大、縮小的本事, 那還請回去使用 EXT 家族最新的 EXT4 檔案系統囉!XFS 目前是辦不到的!

14.3.4 使用 LVM thin Volume 讓 LVM 動態自動調整磁碟使用率

想像一個情況,你有個目錄未來會使用到大約 5T 的容量,但是目前你的磁碟僅有 3T,問題是,接下來的兩個月你的系統都還不會超過 3T 的容量, 不過你想要讓用戶知道,就是他最多有 5T 可以使用就是了!而且在一個月內你確實可以將系統提升到 5T 以上的容量啊! 你又不想要在提升容量後才放大到 5T!那可以怎麼辦?呵呵!這時可以考慮『實際用多少才分配多少容量給 LV 的 LVM Thin Volume 』功能!

另外,再想像一個環境,如果你需要有 3 個 10GB 的磁碟來進行某些測試,問題是你的環境僅有 5GB 的剩餘容量,再傳統的 LVM 環境下, LV 的容量是一開始就分配好的,因此你當然沒有辦法在這樣的環境中產生出 3 個 10GB 的裝置啊!而且更嘔的是,那個 10GB 的裝置其實每個實際使用率都沒有超過 10%, 也就是總用量目前僅會到 3GB 而已!但...我實際就有 5GB 的容量啊!為何不給我做出 3 個只用 1GB 的 10GB 裝置呢?有啊!就還是 LVM thin Volume 啊!

什麼是 LVM thin Volume 呢?這東西其實挺好玩的,他的概念是:先建立一個可以實支實付、用多少容量才分配實際寫入多少容量的磁碟容量儲存池 (thin pool), 然後再由這個 thin pool 去產生一個『指定要固定容量大小的 LV 裝置』,這個 LV 就有趣了!雖然你會看到『宣告上,他的容量可能有 10GB ,但實際上, 該裝置用到多少容量時,才會從 thin pool 去實際取得所需要的容量』!就如同上面的環境說的,可能我們的 thin pool 僅有 1GB 的容量, 但是可以分配給一個 10GB 的 LV 裝置!而該裝置實際使用到 500M 時,整個 thin pool 才分配 500M 給該 LV 的意思!當然啦! 在所有由 thin pool 所分配出來的 LV 裝置中,總實際使用量絕不能超過 thin pool 的最大實際容量啊!如這個案例說的, thin pool 僅有 1GB, 那所有的由這個 thin pool 建置出來的 LV 裝置內的實際用量,就絕不能超過 1GB 啊!

我們來實作個環境好了!剛剛鳥哥的 vbirdvg 應該還有剩餘容量,那麼請這樣作看看:

  1. 由 vbirdvg 的剩餘容量取出 1GB 來做出一個名為 vbirdtpool 的 thin pool LV 裝置,這就是所謂的磁碟容量儲存池 (thin pool)
  2. 由 vbirdvg 內的 vbirdtpool 產生一個名為 vbirdthin1 的 10GB LV 裝置
  3. 將此裝置實際格式化為 xfs 檔案系統,並且掛載於 /srv/thin 目錄內!

話不多說,我們來實驗看看!

# 1. 先以 lvcreate 來建立 vbirdtpool 這個 thin pool 裝置:
[root@study ~]# lvcreate -L 1G -T vbirdvg/vbirdtpool  # 最重要的建置指令
[root@study ~]# lvdisplay /dev/vbirdvg/vbirdtpool
  --- Logical volume ---
  LV Name                vbirdtpool
  VG Name                vbirdvg
  LV UUID                p3sLAg-Z8jT-tBuT-wmEL-1wKZ-jrGP-0xmLtk
  LV Write Access        read/write
  LV Creation host, time study.centos.vbird, 2015-07-28 18:27:32 +0800
  LV Pool metadata       vbirdtpool_tmeta
  LV Pool data           vbirdtpool_tdata
  LV Status              available
  # open                 0
  LV Size                1.00 GiB   # 總共可分配出去的容量
  Allocated pool data    0.00%      # 已分配的容量百分比
  Allocated metadata     0.24%      # 已分配的中介資料百分比
  Current LE             64
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:6
# 非常有趣吧!竟然在 LV 裝置中還可以有再分配 (Allocated) 的項目耶!果然是儲存池!

[root@study ~]# lvs vbirdvg  # 語法為 lvs VGname
  LV         VG      Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  vbirdlv    vbirdvg -wi-ao---- 2.50g
  vbirdtpool vbirdvg twi-a-tz-- 1.00g             0.00   0.24
# 這個 lvs 指令的輸出更加簡單明瞭!直接看比較清晰!

# 2. 開始建立 vbirdthin1 這個有 10GB 的裝置,注意!必須使用 --thin 與 vbirdtpool 連結喔!
[root@study ~]# lvcreate -V 10G -T vbirdvg/vbirdtpool -n vbirdthin1

[root@study ~]# lvs vbirdvg
  LV         VG      Attr       LSize  Pool       Origin Data%  Meta%  Move Log Cpy%Sync Convert
  vbirdlv    vbirdvg -wi-ao----  2.50g
  vbirdthin1 vbirdvg Vwi-a-tz-- 10.00g vbirdtpool        0.00
  vbirdtpool vbirdvg twi-aotz--  1.00g                   0.00   0.27
# 很有趣吧!明明連 vbirdvg 這個 VG 都沒有足夠大到 10GB 的容量,透過 thin pool
# 竟然就產生了 10GB 的 vbirdthin1 這個裝置了!好有趣!

# 3. 開始建立檔案系統
[root@study ~]# mkfs.xfs /dev/vbirdvg/vbirdthin1
[root@study ~]# mkdir /srv/thin
[root@study ~]# mount /dev/vbirdvg/vbirdthin1 /srv/thin
[root@study ~]# df -Th /srv/thin
Filesystem                     Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdthin1 xfs    10G   33M   10G   1% /srv/thin
# 真的有 10GB 耶!!

# 4. 測試一下容量的使用!建立 500MB 的檔案,但不可超過 1GB 的測試為宜!
[root@study ~]# dd if=/dev/zero of=/srv/thin/test.img bs=1M count=500
[root@study ~]# lvs vbirdvg
  LV         VG      Attr       LSize  Pool       Origin Data%  Meta%  Move Log Cpy%Sync Convert
  vbirdlv    vbirdvg -wi-ao----  2.50g
  vbirdthin1 vbirdvg Vwi-aotz-- 10.00g vbirdtpool        4.99
  vbirdtpool vbirdvg twi-aotz--  1.00g                   49.93  1.81
# 很要命!這時已經分配出 49% 以上的容量了!而 vbirdthin1 卻只看到用掉 5% 而已!
# 所以鳥哥認為,這個 thin pool 非常好用!但是在管理上,得要特別特別的留意!

這就是用多少算多少的 thin pool 實作方式!基本上,用來騙人挺嚇人的!小小的一個磁碟可以模擬出好多容量!但實際上,真的可用容量就是實際的磁碟儲存池內的容量! 如果突破該容量,這個 thin pool 可是會爆炸而讓資料損毀的!要注意!要注意!

14.3.5 LVM 的 LV 磁碟快照

現在你知道 LVM 的好處咯,未來如果你有想要增加某個 LVM 的容量時,就可以透過這個放大的功能來處理。 那麼 LVM 除了這些功能之外,還有什麼能力呢?其實他還有一個重要的能力,那就是 LV 磁碟的快照 (snapshot)。 什麼是 LV 磁碟快照啊?快照就是將當時的系統資訊記錄下來,就好像照相記錄一般! 未來若有任何資料更動了,則原始資料會被搬移到快照區,沒有被更動的區域則由快照區與檔案系統共享。 用講的好像很難懂,我們用圖解說明一下好了:

LVM 快照區域的備份示意圖
圖14.3.3、LVM 快照區域的備份示意圖

左圖為最初建置 LV 磁碟快照區的狀況,LVM 會預留一個區域 (左圖的左側三個 PE 區塊) 作為資料存放處。 此時快照區內並沒有任何資料,而快照區與系統區共享所有的 PE 資料, 因此你會看到快照區的內容與檔案系統是一模一樣的。 等到系統運作一陣子後,假設 A 區域的資料被更動了 (上面右圖所示),則更動前系統會將該區域的資料移動到快照區, 所以在右圖的快照區被佔用了一塊 PE 成為 A,而其他 B 到 I 的區塊則還是與檔案系統共用!

照這樣的情況來看,LVM 的磁碟快照是非常棒的『備份工具』,因為他只有備份有被更動到的資料, 檔案系統內沒有被變更的資料依舊保持在原本的區塊內,但是 LVM 快照功能會知道那些資料放置在哪裡, 因此『快照』當時的檔案系統就得以『備份』下來,且快照所佔用的容量又非常小!所以您說,這不是很棒的工具又是什麼?

那麼快照區要如何建立與使用呢?首先,由於快照區與原本的 LV 共用很多 PE 區塊,因此快照區與被快照的 LV 必須要在同一個 VG 上頭。

另外,或許你跟鳥哥一樣,會想到說:『咦! 我們能不能使用 thin pool 的功能來製作快照』呢?老實說,是可以的!不過使用上面的限制非常的多!包括最好要在同一個 thin pool 內的原始 LV 磁碟, 如果為非 thin pool 內的原始 LV 磁碟快照,則該磁碟快照『不可以寫入』,亦即 LV 磁碟要設定成唯讀才行!同時, 使用 thin pool 做出來的快照,通常都是不可啟動 (inactive) 的預設情況,啟動又有點麻煩~所以,至少目前 (CentOS 7.x) 的環境下, 鳥哥還不是很建議你使用 thin pool 快照喔!

底下我們針對傳統 LV 磁碟進行快照的建置,大致流程為:

  • 預計被拿來備份的原始 LV 為 /dev/vbirdvg/vbirdlv 這個東西~
  • 使用傳統方式快照建置,原始碟為 /dev/vbirdvg/vbirdlv,快照名稱為 vbirdsnap1,容量為 vbirdvg 的所有剩餘容量
  • 傳統快照區的建立
# 1. 先觀察 VG 還剩下多少剩餘容量
[root@study ~]# vgdisplay vbirdvg
....(其他省略)....
  Total PE              252
  Alloc PE / Size       226 / 3.53 GiB
  Free  PE / Size       26 / 416.00 MiB
# 就只有剩下 26 個 PE 了!全部分配給 vbirdsnap1 囉!

# 2. 利用 lvcreate 建立 vbirdlv 的快照區,快照被取名為 vbirdsnap1,且給予 26 個 PE
[root@study ~]# lvcreate -s -l 26 -n vbirdsnap1 /dev/vbirdvg/vbirdlv
  Logical volume "vbirdsnap1" created
# 上述的指令中最重要的是那個 -s 的選項!代表是 snapshot 快照功能之意!
# -n 後面接快照區的裝置名稱, /dev/.... 則是要被快照的 LV 完整檔名。
# -l 後面則是接使用多少個 PE 來作為這個快照區使用。

[root@study ~]# lvdisplay /dev/vbirdvg/vbirdsnap1
  --- Logical volume ---
  LV Path                /dev/vbirdvg/vbirdsnap1
  LV Name                vbirdsnap1
  VG Name                vbirdvg
  LV UUID                I3m3Oc-RIvC-unag-DiiA-iQgI-I3z9-0OaOzR
  LV Write Access        read/write
  LV Creation host, time study.centos.vbird, 2015-07-28 19:21:44 +0800
  LV snapshot status     active destination for vbirdlv
  LV Status              available
  # open                 0
  LV Size                2.50 GiB    # 原始碟,就是 vbirdlv 的原始容量
  Current LE             160
  COW-table size         416.00 MiB  # 這個快照能夠紀錄的最大容量!
  COW-table LE           26
  Allocated to snapshot  0.00%       # 目前已經被用掉的容量!
  Snapshot chunk size    4.00 KiB
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:11

您看看!這個 /dev/vbirdvg/vbirdsnap1 快照區就被建立起來了!而且他的 VG 量竟然與原本的 /dev/vbirdvg/vbirdlv 相同!也就是說,如果你真的掛載這個裝置時,看到的資料會跟原本的 vbirdlv 相同喔!我們就來測試看看:

[root@study ~]# mkdir /srv/snapshot1
[root@study ~]# mount -o nouuid /dev/vbirdvg/vbirdsnap1 /srv/snapshot1
[root@study ~]# df -Th /srv/lvm /srv/snapshot1
Filesystem                     Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv    xfs   2.5G  111M  2.4G   5% /srv/lvm
/dev/mapper/vbirdvg-vbirdsnap1 xfs   2.5G  111M  2.4G   5% /srv/snapshot1
# 有沒有看到!這兩個咚咚竟然是一模一樣喔!我們根本沒有動過
# /dev/vbirdvg/vbirdsnap1 對吧!不過這裡面會主動記錄原 vbirdlv 的內容!

因為 XFS 不允許相同的 UUID 檔案系統的掛載,因此我們得要加上那個 nouuid 的參數,讓檔案系統忽略相同的 UUID 所造成的問題! 沒辦法啊!因為快照出來的檔案系統當然是會一模一樣的!

  • 利用快照區復原系統

首先,我們來玩一下,如何利用快照區復原系統吧!不過你要注意的是,你要復原的資料量不能夠高於快照區所能負載的實際容量。由於原始資料會被搬移到快照區, 如果你的快照區不夠大,若原始資料被更動的實際資料量比快照區大,那麼快照區當然容納不了,這時候快照功能會失效喔!

我們的 /srv/lvm 已經有 /srv/lvm/etc, /srv/lvm/log 等目錄了,接下來我們將這個檔案系統的內容作個變更, 然後再以快照區資料還原看看:

# 1. 先將原本的 /dev/vbirdvg/vbirdlv 內容作些變更,增增減減一些目錄吧!
[root@study ~]# df -Th /srv/lvm /srv/snapshot1
Filesystem                     Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv    xfs   2.5G  111M  2.4G   5% /srv/lvm
/dev/mapper/vbirdvg-vbirdsnap1 xfs   2.5G  111M  2.4G   5% /srv/snapshot1

[root@study ~]# cp -a /usr/share/doc /srv/lvm
[root@study ~]# rm -rf /srv/lvm/log
[root@study ~]# rm -rf /srv/lvm/etc/sysconfig
[root@study ~]# df -Th /srv/lvm /srv/snapshot1
Filesystem                     Type  Size  Used Avail Use% Mounted on
/dev/mapper/vbirdvg-vbirdlv    xfs   2.5G  146M  2.4G   6% /srv/lvm
/dev/mapper/vbirdvg-vbirdsnap1 xfs   2.5G  111M  2.4G   5% /srv/snapshot1
[root@study ~]# ll /srv/lvm /srv/snapshot1
/srv/lvm:
total 60
drwxr-xr-x. 887 root root 28672 Jul 20 23:03 doc
drwxr-xr-x. 131 root root  8192 Jul 28 00:12 etc

/srv/snapshot1:
total 16
drwxr-xr-x. 131 root root 8192 Jul 28 00:12 etc
drwxr-xr-x.  16 root root 4096 Jul 28 00:01 log
# 兩個目錄的內容看起來已經不太一樣了喔!檢測一下快照 LV 吧!

[root@study ~]# lvdisplay /dev/vbirdvg/vbirdsnap1
  --- Logical volume ---
  LV Path                /dev/vbirdvg/vbirdsnap1
....(中間省略)....
  Allocated to snapshot  21.47%
# 鳥哥僅列出最重要的部份!就是全部的容量已經被用掉了 21.4% 囉!

# 2. 利用快照區將原本的 filesystem 備份,我們使用 xfsdump 來處理!
[root@study ~]# xfsdump -l 0 -L lvm1 -M lvm1 -f /home/lvm.dump /srv/snapshot1
# 此時你就會有一個備份資料,亦即是 /home/lvm.dump 了!

為什麼要備份呢?為什麼不可以直接格式化 /dev/vbirdvg/vbirdlv 然後將 /dev/vbirdvg/vbirdsnap1 直接複製給 vbirdlv 呢? 要知道 vbirdsnap1 其實是 vbirdlv 的快照,因此如果你格式化整個 vbirdlv 時,原本的檔案系統所有資料都會被搬移到 vbirdsnap1。 那如果 vbirdsnap1 的容量不夠大 (通常也真的不夠大),那麼部分資料將無法複製到 vbirdsnap1 內,資料當然無法全部還原啊! 所以才要在上面表格中製作出一個備份檔案的!瞭解乎?

而快照還有另外一個功能,就是你可以比對 /srv/lvm 與 /srv/snapshot1 的內容,就能夠發現到最近你到底改了啥咚咚! 這樣也是很不賴啊!您說是吧! ^_^!接下來讓我們準備還原 vbirdlv 的內容吧!

# 3. 將 vbirdsnap1 卸載並移除 (因為裡面的內容已經備份起來了)
[root@study ~]# umount /srv/snapshot1
[root@study ~]# lvremove /dev/vbirdvg/vbirdsnap1
Do you really want to remove active logical volume "vbirdsnap1"? [y/n]: y
  Logical volume "vbirdsnap1" successfully removed

[root@study ~]# umount /srv/lvm
[root@study ~]# mkfs.xfs -f /dev/vbirdvg/vbirdlv
[root@study ~]# mount /dev/vbirdvg/vbirdlv /srv/lvm
[root@study ~]# xfsrestore -f /home/lvm.dump -L lvm1 /srv/lvm
[root@study ~]# ll /srv/lvm
drwxr-xr-x. 131 root root 8192 Jul 28 00:12 etc
drwxr-xr-x.  16 root root 4096 Jul 28 00:01 log
# 是否與最初的內容相同啊!這就是透過快照來還原的一個簡單的方法囉!
  • 利用快照區進行各項練習與測試的任務,再以原系統還原快照

換個角度來想想,我們將原本的 vbirdlv 當作備份資料,然後將 vbirdsnap1 當作實際在運作中的資料, 任何測試的動作都在 vbirdsnap1 這個快照區當中測試,那麼當測試完畢要將測試的資料刪除時,只要將快照區刪去即可! 而要複製一個 vbirdlv 的系統,再作另外一個快照區即可!這樣是否非常方便啊? 這對於教學環境中每年都要幫學生製作一個練習環境主機的測試,非常有幫助呢!

Tips 鳥哥 以前鳥哥老是覺得使用 LVM 的快照來進行備份不太合理,因為還要製作一個備份檔!後來仔細研究並參考徐秉義老師的教材(註4)後,才發現 LVM 的快照實在是一個棒到不行的工具!尤其是在虛擬機器當中建置多份給同學使用的測試環境, 你只要有一個基礎的環境保持住,其他的環境使用快照來提供即可。即時同學將系統搞爛了,你只要將快照區刪除, 再重建一個快照區!這樣環境就恢復了!天吶!實在是太棒了! ^_^

14.3.6 LVM 相關指令彙整與 LVM 的關閉

好了,我們將上述用過的一些指令給他彙整一下,提供給您參考參考:

任務PV 階段VG 階段LV 階段filesystem
(XFS / EXT4)
搜尋(scan)pvscanvgscanlvscanlsblk, blkid
建立(create)pvcreatevgcreatelvcreatemkfs.xfsmkfs.ext4
列出(display)pvdisplayvgdisplaylvdisplaydf, mount
增加(extend) vgextendlvextend (lvresize)xfs_growfsresize2fs
減少(reduce) vgreducelvreduce (lvresize)不支援resize2fs
刪除(remove)pvremovevgremovelvremoveumount, 重新格式化
改變容量(resize)  lvresizexfs_growfsresize2fs
改變屬性(attribute)pvchangevgchangelvchange/etc/fstab, remount

至於檔案系統階段 (filesystem 的格式化處理) 部分,還需要以 xfs_growfs 來修訂檔案系統實際的大小才行啊! ^_^ 。至於雖然 LVM 可以彈性的管理你的磁碟容量,但是要注意,如果你想要使用 LVM 管理您的硬碟時,那麼在安裝的時候就得要做好 LVM 的規劃了, 否則未來還是需要先以傳統的磁碟增加方式來增加後,移動資料後,才能夠進行 LVM 的使用啊!

會玩 LVM 還不行!你必須要會移除系統內的 LVM 喔!因為你的實體 partition 已經被使用到 LVM 去, 如果你還沒有將 LVM 關閉就直接將那些 partition 刪除或轉為其他用途的話,系統是會發生很大的問題的! 所以囉,你必須要知道如何將 LVM 的裝置關閉並移除才行!會不會很難呢?其實不會啦! 依據以下的流程來處理即可:

  1. 先卸載系統上面的 LVM 檔案系統 (包括快照與所有 LV);
  2. 使用 lvremove 移除 LV ;
  3. 使用 vgchange -a n VGname 讓 VGname 這個 VG 不具有 Active 的標誌;
  4. 使用 vgremove 移除 VG:
  5. 使用 pvremove 移除 PV;
  6. 最後,使用 fdisk 修改 ID 回來啊!

好吧!那就實際的將我們之前建立的所有 LVM 資料給刪除吧!

[root@study ~]# umount /srv/lvm /srv/thin /srv/snapshot1
[root@study ~]# lvs vbirdvg
  LV         VG      Attr       LSize  Pool       Origin Data%  Meta%  Move Log Cpy%Sync 
  vbirdlv    vbirdvg -wi-a-----  2.50g
  vbirdthin1 vbirdvg Vwi-a-tz-- 10.00g vbirdtpool        4.99
  vbirdtpool vbirdvg twi-aotz--  1.00g                   49.93  1.81
# 要注意!先刪除 vbirdthin1 --> vbirdtpool --> vbirdlv 比較好!

[root@study ~]# lvremove /dev/vbirdvg/vbirdthin1 /dev/vbirdvg/vbirdtpool
[root@study ~]# lvremove /dev/vbirdvg/vbirdlv
[root@study ~]# vgchange -a n vbirdvg
  0 logical volume(s) in volume group "vbirdvg" now active

[root@study ~]# vgremove vbirdvg
  Volume group "vbirdvg" successfully removed

[root@study ~]# pvremove /dev/vda{5,6,7,8}

最後再用 gdisk 將磁碟的 ID 給他改回來 83 就好啦!整個過程就這樣的啦! ^_^

14.4 重點回顧

  • Quota 可公平的分配系統上面的磁碟容量給使用者;分配的資源可以是磁碟容量(block)或可建立檔案數量(inode);
  • Quota 的限制可以有 soft/hard/grace time 等重要項目;
  • Quota 是針對整個 filesystem 進行限制,XFS 檔案系統可以限制目錄!
  • Quota 的使用必須要核心與檔案系統均支援。檔案系統的參數必須含有 usrquota, grpquota, prjquota
  • Quota 的 xfs_quota 實作的指令有 report, print, limit, timer... 等指令;
  • 磁碟陣列 (RAID) 有硬體與軟體之分,Linux 作業系統可支援軟體磁碟陣列,透過 mdadm 套件來達成;
  • 磁碟陣列建置的考量依據為『容量』、『效能』、『資料可靠性』等;
  • 磁碟陣列所建置的等級常見有的 raid0, raid1, raid1+0, raid5 及 raid6
  • 硬體磁碟陣列的裝置檔名與 SCSI 相同,至於 software RAID 則為 /dev/md[0-9]
  • 軟體磁碟陣列的狀態可藉由 /proc/mdstat 檔案來瞭解;
  • LVM 強調的是『彈性的變化檔案系統的容量』;
  • 與 LVM 有關的元件有: PV/VG/PE/LV 等元件,可以被格式化者為 LV
  • 新的 LVM 擁有 LVM thin volume 的功能,能夠動態調整磁碟的使用率!
  • LVM 擁有快照功能,快照可以記錄 LV 的資料內容,並與原有的 LV 共享未更動的資料,備份與還原就變的很簡單;
  • XFS 透過 xfs_growfs 指令,可以彈性的調整檔案系統的大小

14.5 本章習題

( 要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )
  • 情境模擬題一:由於 LVM 可以彈性調整 filesystem 的大小,但是缺點是可能沒有加速與硬體備份(與快照不同)的功能。 而磁碟陣列則具有效能與備份的功能,但是無法提供類似 LVM 的優點。在此情境中,我們想利用『在 RAID 上面建置 LVM』的功能,以達到兩者兼顧的能力。

    • 目標:測試在 RAID 磁碟上面架構 LVM 系統;
    • 需求:需要具有磁碟管理的能力,包括 RAID 與 LVM;
    • 前提:會用到本章建立出來的 /dev/vda5, /dev/vda6, /dev/vda7 三個分割槽!

    那要如何處理呢?如下的流程一個步驟一個步驟的實施看看吧:

    1. 重新處理系統,我們在這個練習當中,需要 /dev/vda5, /dev/vda6, /dev/vda7 建置成一個 RAID5 的 /dev/md0 磁碟!詳細的作法這裡就不談了! 你得要使用 gdisk 來處理成為如下的模樣:

      [root@study ~]# gdisk -l /dev/vda
      Number  Start (sector)    End (sector)  Size       Code  Name
         1            2048            6143   2.0 MiB     EF02
         2            6144         2103295   1024.0 MiB  0700
         3         2103296        65026047   30.0 GiB    8E00
         4        65026048        67123199   1024.0 MiB  8300  Linux filesystem
         5        67123200        69220351   1024.0 MiB  FD00  Linux RAID
         6        69220352        71317503   1024.0 MiB  FD00  Linux RAID
         7        71317504        73414655   1024.0 MiB  FD00  Linux RAID
      

    2. 開始使用 mdadm 來建立一個簡單的 RAID5 陣列!簡易的流程如下:
      [root@study ~]# mdadm --create /dev/md0 --auto=yes  --level=5  \
      > --raid-devices=3 /dev/vda{5,6,7}
      [root@study ~]# mdadm --detail /dev/md0 | grep -i uuid
                 UUID : efc7add0:d12ee9ca:e5cb0baa:fbdae4e6
      [root@study ~]# vim /etc/mdadm.conf
      ARRAY /dev/md0 UUID=efc7add0:d12ee9ca:e5cb0baa:fbdae4e6
      
      若無出現任何錯誤訊息,此時你已經具有 /dev/md0 這個磁碟陣列裝置了!接下來讓我們處理 LVM 吧!

    3. 開始處理 LVM ,現在我們假設所有的參數都使用預設值,包括 PE ,然後 VG 名為 raidvg ,LV 名為 raidlv ,底下為基本的流程:
      [root@study ~]# pvcreate /dev/md0                  <==建立 PV
      [root@study ~]# vgcreate raidvg /dev/md0           <==建立 VG
      [root@study ~]# lvcreate -L 1.5G -n raidlv raidvg  <==建立 LV
      [root@study ~]# lvscan
        ACTIVE            '/dev/raidvg/raidlv' [1.50 GiB] inherit
      
      這樣就搞定了 LVM 了!而且這個 LVM 是架構在 /dev/md0 上面的喔!然後就是檔案系統的建立與掛載了!

    4. 嘗試建立成為 XFS 檔案系統,且掛載到 /srv/raidlvm 目錄下:
      [root@study ~]# mkfs.xfs /dev/raidvg/raidlv
      [root@study ~]# blkid /dev/raidvg/raidlv
      /dev/raidvg/raidlv: UUID="4f6a587d-3257-4049-afca-7da1d405117d" TYPE="xfs"
      [root@study ~]# vim /etc/fstab
      UUID="4f6a587d-3257-4049-afca-7da1d405117d" /srv/raidlvm xfs    defaults 0 0
      
      [root@study ~]# mkdir /srv/raidlvm
      [root@study ~]# mount -a
      [root@study ~]# df -Th /srv/raidlvm
      Filesystem                Type  Size  Used Avail Use% Mounted on
      /dev/mapper/raidvg-raidlv xfs   1.5G   33M  1.5G   3% /srv/raidlvm
      

    5. 上述就是 LVM 架構在 RAID 上面的技巧,之後的動作都能夠使用本章的其他管理方式來管理, 包括 RAID 熱拔插機制、LVM 放大縮小機制等等。

簡答題部分:
  • 在前一章的第一個大量新增帳號範例中, 如果我想要讓每個用戶均具有 soft/hard 各為 40MB/50MB 的容量時,應該如何修改這個 script ?
    你得先要依據本章的作法,先將 /home 製作好 quota 的環境然後, 你可以在 do...done 內的最後一行,新增一行內容為:
    xfs_quota -x -c "limit -u bsoft=40M bhard=50M ${username}" /home
    這樣就可以在製作用戶時,指定更新密碼且給予 quota 的限制!
  • 如果我想要讓 RAID 具有保護資料的功能,防止因為硬體損毀而導致資料的遺失,那我應該要選擇的 RAID 等級可能有哪些? (請以本章談到的等級來思考即可)
    具有備份資料的有: RAID-1, RAID-5, RAID-6
  • 在預設的 LVM 設定中,請問 LVM 能否具有『備份』的功能?
    是有的,就是那個快照 (snopshot) 的功能,此功能即可進行資料的備份!
  • 如果你的電腦主機有提供 RAID 0 的功能,你將你的三顆硬碟全部在 BIOS 階段使用 RAID 晶片整合成為一顆大磁碟, 則此磁碟在 Linux 系統當中的檔名為何?
    由於硬體磁碟陣列是在 BIOS 階段完成的,因此 Linux 系統會捉到一個完整的大的 RAID 磁碟,此磁碟的檔名就會是『 /dev/sda 』! 但如果是 Intel 的晶片組,則還是可能會成為 /dev/md127 等相關的檔名!

14.6 參考資料與延伸閱讀

修改歷史:
  • 2002/07/14:第一次完成
  • 2003/02/10:重新編排與加入 FAQ
  • 2003/09/02:加入 quotacheck 發生錯誤時的解決方法。
  • 2005/09/06:將舊的文章移動到 此處
  • 2005/09/06:進行版面風格的轉換,並且進行資料的查詢,加入 repquota 的簡單說明而已!
  • 2009/03/04:將原本舊的基於 FC4 的文件移動到 此處
  • 2009/03/06:加入 warnquota 這玩意兒!挺有趣的哩!
  • 2009/03/12:加入了 software RAID 與 LVM 的加強說明,尤其是 LVM 的快照 (snapshot) 的說明!
  • 2009/09/10:修改一些字樣之外,增加情境模擬,以及後續的簡答題部分題目。
  • 2012/06/14:在解釋 PE 的部分有錯誤!是 Physical Extent 而不是 Physical Extend !真抱歉!
  • 2017/03/29:將 RAID 的名稱做個修訂~感謝網友的建議。
2002/05/06以來統計人數
計數器
其他連結
環境工程模式篇
鳥園討論區
鳥哥舊站

今日 人數統計
昨日 人數統計
本月 人數統計
上月 人數統計