原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章?原始出處?、作者信息和本聲明。否則將追究法律責任。http://jagen.blog.51cto.com/2889774/1312868
2.5? 磁盤的管理方式
用戶也好,權限也罷,它們總是要有一個證明自己的天地;文件也罷,程序也好,它們總是得有一個安身立命的家園;即便 Linux 自己也必須得有自己的棲身之所。那就是磁盤。其實 Linux 對磁盤的管理十分對得起兩個字:“不賴”!
2.5.1 Linux 的文件系統
只要是磁盤就得格式化,好像已經是天經地義的事情了,幾乎沒有人去問為什么。很多有經驗的人在似乎都有個這樣的經歷,就是風風火火的從朋友那里借來了一張裝滿高清 “ A ” 片的移動硬盤,暗爽過后還想留下一些待以后慢慢品味,可是總有那么一些質量比較好的片子(尺寸超過 4G )復制失敗。追問原因還往往被高手們嘲笑: “ 都什么年代了你還用 FAT32 ,趕緊換 NTFS 吧”。我想這個時候你就不得不追問一下,為什么 FAT32 不行而 NTFS 卻能行吧?
因為它們是不同的文件系統,功能不同,能力不同。 FAT32 是在 Windows95 時代開始采用的文件系統,到現在都有人在用(比如 U 盤),可以說是伴隨著我們成長的文件系統。 FAT 是 File Allocation Table 的縮寫,從字面意義上就能看出這是一種類似表格一樣的文件系統。由于其用于描述文件大小的屬性是一個 32 位的值,導致其能夠支持的單個文件最大不能超過 4G 。而 NTFS 是微軟專門為 NT 系統設計的,單個文件最大可以達到 2T 。現在最為常用的 Windows XP 和 Windows 7 都支持 NTFS 。至于 NTFS 是怎么管理文件的有點不太好說,因為微軟一直當它是個“秘密 ” 。
Linux 也有自己的文件系統格式,被稱為 ExtN ( N=2 、 3 、 4 )。如果要追溯 ExtN 的起源,其實要比 FAT32 和 NTFS 都要古老,也就是我們前面所說的基于 inode 的文件系統。如前面所述, ExtN 文件系統必定要包含 inode 數據結構來代表一個文件,并且存儲這個文件的各種屬性和權限。至于實際的數據則放在 data block 塊區中。除此之外, ExtN 文件系統還有一個超級塊區( superblock ),用于記錄整個文件系統的整體信息,包括 inode 與 data block 的總量、使用量和剩余量。
data block 與 inode 一樣,每一個都有一個唯一編號, inode 只需要記錄這些編號,就能夠定位整個文件的任意一段數據。我們假定有一個編號為 3 的 inode ,它所代表的文件的數據被放置在編號為 2 、 5 、 6 、 8 、 13 和 20 的這幾個 data block 中。那么讀取這個文件的過程則如圖 2.4 所示。采用這種數據存取的方法的文件系統被稱之為 “ 索引式文件系統”。它與伴隨著很多人成長的 FAT32 有什么不同呢?圖 2.5 對比了這個過程。
通過對兩個圖的比較,我們可以清晰的看出, ExtN 通過 inode 能夠一次性獲得文件數據所存放的位置,可以據此來安排磁盤的閱讀順序,盡量保證在磁盤只旋轉一圈的情況下將所有內容讀出來。而 FAT32 則只有將對應的 data block 讀入之后才知道下一個 data block 在什么地方。如果一個文件的 data block 比較分散的話,將很難保證在磁盤只旋轉一圈的情況下讀取全部數據,有時候甚至要多轉很多圈才能讀完數據。
這就是我們非常熟悉的 “ 磁盤碎片 ” 問題。由于長時間的對文件進行創建、刪除、讀寫,很難保證同一個文件的 data block 的位置相鄰。而由于 FAT32 的讀寫特性,在 data block 不相鄰的情況下讀寫性能會極具下降。所以為了提高 Windows 系統的磁盤性能,經常性的做 “ 磁盤碎片整理 ” 是非常有必要的。
而對于 Linux 這種文件系統,則基本上不需要進行磁盤碎片整理。而且你也基本上找不到類似的工具。但是 Linux 系統經過長時間使用之后,還是會有文件數據過于分散的問題的。即便能夠做到很好的規劃,但是對性能多多稍稍還是會有一些影響,只是沒有使用 FAT32 的 Windows 那么嚴重罷了。所以,一個使用時間很久的 Linux 系統也會因為磁盤碎片問題而變慢,這也是事實。只是不需要太過在意它。
圖 2.4 ExtN 文件系統讀取數據過程示意圖
圖 2.5 FAT32 文件系統讀取數據過程示意圖
2.5.2? 磁盤的基本操作
在前面的小結中介紹過幾個最常用的文件操作命令: ls 、 cd 、 cp 、 rm 和 mv 。雖然它們也都是作用在磁盤上,但是它們面向的對象更為高級一些,屬于文件范疇的。而我們現在要介紹的是稍微低級一點,面對是的文件的載體 —— 磁盤的一些基本操作。最常用的是: df 、 du 、 dd 、 fsck 和 mount 。
df 命令用于查看系統中所有磁盤的整體使用量。在我們的測試系統中能夠得到如下所示信息:
Filesystem 1K-blocks Used Available Use% Mountedon
/dev/mapper/VolGroup-lv_root
51606140 5587240 43397460 12% /
tmpfs 250860 272 250588 1% /dev/shm
/dev/sda1 495844 31891 438353 7% /boot
/dev/mapper/VolGroup-lv_home
9877432 1681704 7693968 18% /home
可見 df 命令的輸出還是比較清晰的。但是有兩個概念可能需要解釋一下,就是這里所說的 “ Filesystem ” 和 “ Mounted on ” 。如果要翻譯成中文(很多人的機器中可能顯示的字段名)則是 “ 文件系統 ” 和 “ 掛載點 ” 。
這里所說的 “ 文件系統 ” 與我們之前所說的操作系統中的文件系統的概念有點不盡相同,著這里更多的含義指的是磁盤分區。之所以叫它是文件系統,是因為每一個磁盤分區都是一個文件系統的具體實例,如果套用面向對象的說法就是,類和對象。諸如 ExtN 這樣的就是類,而具體的磁盤分區就是這個類的對象。至于 “ 掛載點 ” 則比較有趣,它是某個具體的目錄。
從 df 每一個行的輸出上看,難道具體的磁盤分區會與某個具體的目錄有關?事實的確是這樣的。前面也是說過, Linux 沒有 Windows 中的 C 盤、 D 盤的概念。精通 Windows 的同學都清楚, Windows 中的分區會有一個盤符與它對應,在分區中的文件和目錄的組織結構就像一顆樹一樣,樹根就是盤符 + “:” 。 Linux 組織文件和目錄的方式最終也能被看作是一棵樹。但是由于沒有 C 盤、 D 盤的概念,更沒有盤符一說,于是就特意規定了一個總的樹根叫 “ / ” ,而具體某個分區的樹根就從某個目錄開始。至于不同的分區應該從哪個目錄開始這個就沒有明確的規定。其實不規定也就是有規定,即你可以隨意指派。而具體指派哪個分區與哪個目錄對應,就由 mount 命令來指定了。之后只要訪問哪個目錄里的任何文件或目錄,都是對具體的分區進行訪問了。而這個目錄則被稱為 “ 掛載點 ” 。
根據 df 命令的輸出 內容可以看出, Linux 文件中的總樹根 “ / ” 與 “ 分區 ” /dev/mapper/VolGroup-lv_root 相關聯,而 /dev/shm 目錄與 “ 分區 ” tmpfs 相關聯, /boot 目錄與分區 /dev/sda1 相關聯, …… 。這些 “ 分區名 ” 都什么含義呢?其實在這些所謂的分區中,只有 /dev/sda1 才是真正的磁盤分區,而這個名稱則是這個磁盤分區的 “ 設備名 ” 。在 Linux 系統中, /dev 目錄下的所有文件都與一個具體的設備有關,有物理的,也有虛擬的。而 sda1 這個就是一個物理的設備。它對應系統第一塊串口硬盤的第一個分區。那么如果是第二個分區呢? sda2 ,第三個是 sda3 …… ,而對應整塊硬盤的則是 sda 。由此遞推,第二塊串口硬盤,應該是 sdb ,第三塊應該是 sdc …… 。而 /dev/mapper/* 這些又是什么呢?這個就是虛擬的設備了,它實際上是邏輯卷。有關邏輯卷的概念我們稍后在說,現在你只要知道它是虛擬的磁盤分區就行了。不過更奇怪的是 tmpfs ,這個設備文件在什么地方呢?答案是沒有,因為它不對應任何設備。它實際上是真正的文件系統名稱。而這個文件系統是在內存中虛擬的,與具體的硬盤無關,所以也沒有具體的設備。于是在 df 的輸出中所幸就與 “ 類名 ” 代替了。這樣的文件系統還有很多,比如 procfs 、 sysfs 等,本書會有專門的一章來介紹這些特種文件系統。
(可以這樣理解,一個filesystem就是一個分區,分區就是實際的存儲空間,但是分區要掛載在目錄下才能訪問,而目錄可以隨便創建,只要把分區掛載在這個目錄下,就可以通過這個目錄訪問這個分區了)
df 命令本身就沒有什么好繼續再介紹的了,上述的一些概念遠比 df 本身要重要很多,這個是大家應該更加注意的。對于 /dev 目錄下的那些文件,本書不會逐個的去講述它們都代表誰。畢竟每個人的系統都不同,所以也沒法說,你沒看到你怎么信我呢?比較好辦的辦法是問百度或谷歌,它們是你學習 Linux 必不可少的工具。好了,我不能再說多了,因為這樣你們都會不買我的書而逛百度去了。
df 命令是用來觀察總體磁盤使用量的,要觀察局部使用量,需要使用 du 命令。 df 命令可以通過讀取磁盤的 superblock 來實現,而 du 命令則不同,它要搜索所有的 inode 來計算局部數據,所以 du 命令的執行效率,經常要比 df 差很多。
從嚴格意義上來講, dd 命令應該不屬于管理磁盤的命令,因為在聯機幫助中說它的功能是 “ convert and copy a file ” 。但是如果你想要直接讀寫磁盤的每一個扇區,或者鏡像整個磁盤, dd 命令則是非常好的選擇。通常 dd 命令的格式如下:
dd if=input_file of=out_file
從這個基本用法,如果像聯機幫助中說描述的,復制一個文件,可以使用類似這樣的命令:
# dd if=/etc/bashrc of=./bashrc
這個命令與 cp /etc/bashrc ./bashrc 是等價的。其實“ if ”和“ of ”這兩個參數也不用給定,會有默認值。“ if ”的默認值是標準輸入,“ of ”的默認值是標準輸出。如果要模擬 cat 命令,可以使用這樣的命令:
# dd if=/etc/bashrc
根據前面的講述的內容,具體的硬件設備在 /dev 目錄下會由具體的文件與之對應,比如 /dev/sda1 。如果要制作第一個串口磁盤第一個分區的鏡像文件,可以使用這樣的命令:
# dd if=/dev/sda1 of=./sda1.img
需要注意,執行上面的命令時,輸出文件所在的分區必須大于 sda1 分區,至于為什么我想你懂的。如果還希望對生成的鏡像文件壓縮一下,可以使用這樣的命令:
# dd if=/dev/sda1 | gzip -9 > ./sda1.img
按照這個思路,我們將整個磁盤都做一個鏡像呢?
# dd if=/dev/sda | gzip -9 > ./sda.img
如果要恢復這個磁盤的內容,就可以這樣: # gzip -dc ./sda.img | ddof=/dev/sda
通過這兩條命令,大家想到了什么?這個是不是與我們在 Windows 下經常使用 ghost 非常像呢?感覺塞門鐵克公司的老大應該找塊豆腐撞死。而 dd 命令還不止這點本事,它還能指定讀寫數據量。比如 bs 和 count 這兩個參數,能夠指定依次讀寫的自己數和讀寫次數,這樣就能夠指定讀寫數量了。比如我要備份磁盤的主引導記錄,可以這樣:
# dd if=/dev/sda of=./mbr.img bs=512 count=1
這要求值讀取 sda 磁盤的首個 512 個字節的信息,也就是第一個扇區的內容,將它保存到 mbr.img 文件。對 mbr 內容感興趣的同學,可以使用反匯編工具,將這個文件反匯編掉,就能知道計算機是怎么啟動的了。
使用 dd 命令能夠做的事情還有很多,比如銷毀磁盤數據、測試磁盤讀寫速度、修復磁盤等,為了方便你使用,我將這些技巧列下來:
# dd if=/dev/urandom of=/dev/sda1
# dd if=/dev/zero of=./test.file bs=1024count=1000000
# dd if=./test.file bs=8k | dd of=/dev/null
# dd if=/dev/sda of=/dev/sda
看完這些,我覺得你們更會認為賽門鐵克公司的老大應該買塊豆腐撞死。特別說明一下 /dev/urandom 、 /dev/zero 和 /dev/null 這三個虛擬設備設備文件非常有用。 urandom 代表隨即數,每次讀入的數據都不會相同; zero 代表 0 ,每次讀入的數據都是 0 ;而 null 主要面對寫,相當于是一個黑洞一樣,無論寫什么都會消失得無影無蹤。
不知道通過我上面的介紹,大家是否已經理解 dd 在磁盤管理中的作用了呢?既然到了這個份上,理不理解我也管不了了。生活還得繼續,我們的內容接著往下走,該說一下 fsck 了。
fsck 一般我們很少手工執行,基本上都是在系統啟動階段就執行了。至于它是什么作用則非常簡單,與 Windows 的 scandisk 一樣,對文件系統的損壞進行修復。需要注意, fsck 只能對文件系統的損壞進行修復,對磁盤的損壞它是沒有辦法的。后面我們會有單獨的章節來介紹 fsck 的工作原理,這里就不做復述。具體的使用方法就是:
# fsck -t? 文件系統 設備名
比如 :
# fsck -f -t ext3 /dev/hda3
其中參數 “ -f ” 要求進行強制檢查。如果不增加 -f 選項,在沒有報錯的磁盤中是不會做檢查的。至于磁盤什么時候會報錯呢?一般就是非法關機的時候了 !
期待已久的 mount 的終于登場了。前面已經講過 “ 掛接點 ” 是個什么東西了,相信大家還在為 Linux 這種 “ 怪異 ” 的設計而嘖嘖稱奇呢。但是早已用慣 Linux 的我反倒覺得 Windows 的設計非常奇怪。相比之下, Linux 的方式更為靈活。就比如在 Windows 下有一個軟件必須在 D 盤下的某個目錄中讀取文件,而這個軟件若是在一個沒有 D 盤的系統中就無法執行了;相反的,在 Linux 下,只需要特意創建一個目錄即可,如果需要單獨的磁盤分區來存儲它,使用 mount 命令指定給它就好了。
雖說 mount 命令聽起來有點神奇,但是使用起來卻是非常簡單。一般的用法是這樣的:
# mount [-t? 文件系統 ]? 設備名稱 掛接點
比如我們要將系統中第二塊串口硬盤的第一個分區(如果有的話)掛接到 /data 目錄下,可以這樣用:
# mount /dev/sdb1 /data
或
# mount -t vfat /dev/sdb1 /data
怎么樣,夠簡單的吧?對于第二種用法很多時候 “ -t ” 參數是多余的,因為類似 ext2 、 ext3 這樣的 ExtN 類的基于 inode 的文件系統,都是都有超級塊的。利用超級塊就能夠了解到具體的文件系統。所以第一種用法在大多數時候都會成功。而第二種用法多數用于掛接 Windows 分區時使用,因為這些文件文件系統不具備超級快。
其實掛接磁盤分區還只是 mount 命令的最平常的一種用法。由于 Linux 使用設備文件來描述一個設備,那么如果有一個實際的文件中的內容與在某個磁盤設備文件中的讀到的內容一致,那么這個實際的文件也能夠掛接進來。就比如我們之前使用 dd 命令創建的 sda1.img 文件(未壓縮的),就可以利用這樣的命令來掛進到一個目錄上:
# mount -o loop ./sda1.img /mnt/sda1
這樣你就會發現 /mnt/sda1 目錄下的內容與 /boot 目錄下的內容相同(別忘了之前 df 命令的輸出)。以此類推,我們下載到的 *.iso 文件也可以使用同樣的方法掛接到某個目錄上直接訪問了。 例如:
# mount -o loop ./CentOS-6.4-x86_64-bin-DVD1.iso/mnt/centos
看到這里是不是覺得 Windows 下那些虛擬光驅軟件的作者們都開買塊豆腐撞死了?
在這種 mount 的用法中,比較重要的是“ -o ” 命令選項,這是個 mount 比較靈活的一個選項,有很多可選參數。比如 “ro” 說明掛接的磁盤是只讀的、“ rw ” 說明掛接的磁盤是可讀寫的等等。而 loop 則說明要掛接的文件是一個虛擬設備,而這個虛擬設備是環形的設備。為什么是“環形”呢?想想硬盤、光盤、軟盤等都是什么形狀就行了。還不知道?圓形的啊!
與 mount 相反的操作就是卸載了,使用 umount 命令。它的操作更加簡單,給定掛接點目錄或具體設備就行了。比如 :
# umount /data
或
#umount /dev/sdb1
如果你的系統中有這些設備,則這兩種方法是等價的。
其余的有關進行磁盤分區和格式化的命令就不做詳細介紹了。因為很多人連 Windows 下這樣的工具怎么用都還搞不清楚,可見它們都是很少用到的東西。為了滿足一份同學的好奇心,我們在這里只說一下它們的名字。
用于磁盤分區的命令是 fdisk ,這與 Windows 或 DOS 下的命令名是一致的。比 fdisk 更好用一些的分區工具是 cfdisk , Cent OS 中有提供。而對磁盤做格式化的則不是 format 命令。在 Linux 是下 mkfs.* 命令。至于 * 是什么,取決于你格式化成什么系統。比如要格式化成 ext3 文件系統,就應該是 mkfs.ext3 。如果想了解系統中都對那些文件系統支持這樣的命令,直接到 /sbin 目錄下查看就是了。而更為通用的格式化命令則是 mkfs ,具體如何使用,查看聯機幫助吧。這類工具與之前介紹的那些磁盤工具也是一樣的,可以對某個磁盤中的一個具體文件進行 “ 分區 ” 和格式化。
2.5.3? /etc/fstab 文件
現在大家已經了解到了 Linux 磁盤的一些基本管理方式,也了解了 “ 掛接 ” 這個新鮮玩意兒。 Windows 是怎么操作的我們不是很清楚,但是在 Linux 啟動之后,其文件布局能夠像你所見到的這樣都是經過一步一步的掛接來完成的。決定讓磁盤的各個分區具體要掛接到哪個目錄是由 /etc/fstab 文件所決定的,所以這個文件是 Linux 系統中十分重要的文件,一旦損壞或丟失,系統將無法正常啟動。所以掌握這個文件的格式并能手工恢復它,將是成為 Linux 系統管理員的必修課程。 這個文件( /etc/fstab )在我們的測試系統中如下所示:
#
# /etc/fstab
# Created by anaconda on Sat Mar 17 05:12:212012
#
# Accessible filesystems, by reference, aremaintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8)and/or blkid(8) for more info
#
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=ec11a28b-9bf2-4f7e-95dc-2b7ccd5992ca /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_home /home ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
我們可以清楚地看到,這個文件一共分為 6 個字段,分別是:
l 設備文件、磁盤卷標或者 UUID
l 掛接點
l 文件系統類型
l mount 命令的 -o 選項參數, defaults 不給定 -o 選項時的行為
l 是否使用 dump 命令備份, 0 代表不做, 1 代表每天備份
l 是否使用 fsck 命令檢查磁盤; 0 代表不檢查, 1 代表最早檢查(一般只有樹根“ / ”是 1 ), 2 也是要檢查,只是比 1 要晚(除樹根之外的一般都使用這個)
在第一個字段中,我們看到了一些在 df 命令中出現的“分區”,而有一些則沒看到過。其實使用 “ df –a ” 就可以查看更多了。而比較讓人困惑的是 /dev/sda1 確不見了,但是能明顯看出來是“ UUID=ec11a28b-2bf2-4f7e-95dc-2b7ccd5992ca ” 這個設備。使用命令 blkid 命令就能露出真面目了。實際上在這里直接寫 /dev/sda1 也是沒有問題的。
雖然 /dev/sda1 找到主了,但是還有一個分區在 df 命令的輸出怎么也找不到,那就是類型為 swap 的這個分區。這個是什么呢?這個是交換分區!交換分區是什么概念呢?與 Windows 的頁面文件是相同的概念!
所謂的頁面交換文件,實際上就是虛擬內存管理時要使用的內存置換文件,就是用來擴展虛擬內存空間的。當然,也是拖慢系統的罪魁禍首之一。需要注意,如果你使用的是 32 位的系統,而且已經配備了 4G 的內存,那么就沒有必要給 Windows 分配頁面交換文件(在沒有開啟 PAE 模式的情況下)。 Linux 下也有這樣的規矩,只是將頁面交換文件變成交換分區了。
創建交換分區可以使用 fdisk 命令,格式化它使用 mkswap 命令。這個似乎并沒有逃出我們之前所掌握的一些知識。但是到了具體掛接的時候就不一樣了,它不是掛接的,即不是使用 mount 命令來用的。取而代之的是使用 swapon 命令。如果需要關掉某個交換分區,則使用 swapoff 命令。
此外,根據我們之前的經驗,普通文件也是能夠成為 “ 交換分區 ” 的(還記得前面講的虛擬光驅嗎? ) ,我們所幸就叫它交換文件好了。方法就是使用 dd 命令來創建一個空的文件,然后使用 mkswap 命令來 “ 格式化 ” 它。比如創建一個 1G 的交互文件,可以這樣:
# dd if=/dev/zero of=/tmp/swap bs=1Mcount=1024
# mkswap /tmp/swap
至于接下來該怎么做,我想你懂的。
2.5.4? 邏輯卷
在前一小節中我們留下了一個小尾巴,說 /dev/mapper/* 這些都是邏輯卷。而具體邏輯卷是什么就沒有繼續說,主要是因為這個小尾巴其實并不小,一不小心可能夾到尾巴。
1.什么是邏輯卷
那么到底什么是邏輯卷呢?這個可能得需要一個比較實際的場景來解釋一下,正好還有一個。
前幾天我有一個同事,在自己的電腦中與他的 Windows 并行安裝了一個 Ubuntu 。他在使用 Linux 的時候總是顯得很小氣,只給他的 Ubuntu 分了 10G 的硬盤空間,并劃分了三個分區分別給了“ / ” 、“ /home ” 和 swap 。樹根“ / ” 分配 2G 的空間,“ /home ” 分配了 7G , swap 為 1G 。這樣的分配方法還是比較專業的。只是沒過幾天他就遇到了麻煩。他想用這個 Linux 系統來定制一套 Android 系統,于是就需要下載到 Android 的全部源代碼。但是沒想到 Google 實在是大方, 7G 的磁盤空間不夠裝 Android 的源代碼。好了,我想問問各位同學,你遇到這樣的問題要怎么做?
按照我們前面掌握的知識可以這樣做。首先再從硬盤中劃分一個更大的分區出來,比如 100G ;然后再將這個分區格式化成 Linux 的文件系統,并將 /home 目錄下的內容全部復制到新的分區;最后修改 /etc/fstab 文件,讓新的分區成為 /home 。重啟之后就大功告成了。看來問題解決的非常好, Linux 的靈活性顯然不一般。但是如果覺得 100G 給的太多了呢, Windows 又不夠用了怎么辦?難道再重復上述動作?天哪,復制文件是要花很長很長時間的,尤其是這種源代碼的東西,無數的小文件。
好了,邏輯卷就是來解決這個問題的,它能夠彈性的調整文件系統的容量。從理論上說,邏輯卷就是在磁盤分區和文件系統之間增加了一個邏輯層。這樣,當文件系統的容量覺得不夠用時,可以向邏輯卷中增加新的分區來實現擴大容量的目的;而當發現文件系統過大而有磁盤浪費的時候,可以選擇去除一些基本沒有使用的磁盤分區來達到容量的目的。在 Linux 系統中實現邏輯卷更能的是 LVM, 即 Logical Volume Manager ,邏輯卷管理器。
2.基本術語與原理
在進一步講述邏輯卷之前,我們先了解一下它的基本術語。
l Physical Volume , PV ,物理卷
物理卷就是具體的硬盤分區,或者與硬盤分區具有相同功能的設備,比如 raid 等,是 LVM 的基本存儲單元。但是與基本的物理存儲介質,比如普通的硬盤分區等,物理卷還要包含與 LVM 相關的管理參數。
l Volume Group , VG ,卷組
卷組類似于非 LVM 系統中的物理硬盤,由多個物理卷組成。可以在卷組上創建一個或多個 LVM 分區。
l Physical Extend , PE ,物理擴展區
每一個物理卷被進一步劃分成被稱為物理擴展區的基本單元,換句話說 PE 是 LVM 使用的最小存儲區,與物理磁盤中的“扇區”或文件系統中的“簇”的概念基本相同。 LVM 的默認 PE 大小是 4M ,每個卷組最多僅能含有 65534 個 PE 。所以,一個卷組的最大容量就是 4M*65534=256G 。如果改變 PE 的大小,就能夠改變卷組的最大容量。
l Logical Volume , LV ,邏輯卷
最后我們說道正題上了,就是邏輯卷。這個邏輯卷就是在卷組之上再進行切分,與在物理磁盤上繼續劃分分區是一樣的道理。但是邏輯卷的大小必須是 PE 的整數倍。這就是 LVM 能夠彈性調整邏輯卷容量的秘密所在。需要增加容量,就增加 PE ;需要減少容量,就減少 PE 。 LVM 的構成原理見圖 2.6 所示。
圖 2.6? LVM 的構成原理
到了具體的邏輯卷上,就可以應用 mkfs 命令進行格式化了,如此以來就能夠使用 mount 命令掛接到系統中了。
構成原理現在算是搞定了,但是對于一個邏輯卷可能會對應到多個物理分區上,那么在向硬盤中寫入數據的時候是怎么操作的呢?目前有兩種模式:
l 線性模式( linear ):即逐個物理分區使用。比如一個邏輯卷占用了 /dev/sda1 和 /dev/sda2 兩個分區,那么首先寫 /dev/sda1 ,直到滿了之后才會使用 /dev/sda2 。
l 交錯模式( triped ):這個就將一筆數據拆成兩個部分,分別寫入 /dev/sda1 和 /dev/sda2 。這個與 RAID 0 很像。如果使用 /dev/sda1 和 /dev/sdb1 這樣的組合來做邏輯卷,有相當于一份數據用兩個硬盤來寫,理論上是能夠提升讀寫效率的。
需要注意,雖然交錯模式的邏輯卷有點像 RAID ,但是它的最終目的還是用于磁盤容量的彈性可調的。如果要關注性能,還是直接使用 RAID 比較好。而且 triped 模式的邏輯卷與 RAID 0 是類似的,即當某個分區掛掉了,那么你的數據也會跟著灰飛煙滅的。所以邏輯卷的默認工作模式是 linear 的。
3.基本操作
Cent OS 已經默認支持邏輯卷了,所以如果選擇了 Cent OS 的同學,現在就已經在使用邏輯卷了。但是如果你選擇了 Ubuntu 這樣的發行版,就沒有這么幸運了,因為 Ubuntu 并沒有提供這方面的支持。但是也不要緊,我們可以手動安裝。
首先,邏輯卷必須有內核支持才能工作。所以必須保證你所使用的內核已經開啟了的邏輯卷的支持(好在大多數主流發行版的內核都支持);其次,需要安裝 lvm2 軟件包。當這些都準備妥當之后,就可開始具體的工作了。
第一步就是準備磁盤空余空間( PQ 絕對是個好工具),硬盤多的同學可以考慮利用第二塊硬盤。然后在這些準備好的空余空間中劃出幾個分區來,并設置分區類型為 Linux LVM (分區標志是 8e )。我們這里正好有一個塊 20G 的老硬盤,我們將它劃分了 4 個分區,平均每個分區 5G 。
第二步是創建物理卷。與物理卷相關的命令有: pvcreate 、 pvscan 、 pvdisplay 和 pvremove 四個。具體都提供那些功能,相比通過名稱都能了解到。我們將剛剛劃分的 4 個分區都設置成物理卷,執行這樣的命令:
# pvcreate /dev/hdb1
# pvcreate /dev/hdb2
# pvcreate /dev/hdb3
# pvcreate /dev/hdb4
或
# pvcreate /dev/hdb{1 , 2 , 3 , 4 }
顯然后一種的風格更加簡便,所以我們后面的所有操作都將采用這種風格。
第三步就是創建卷組 VG 。操作卷組的命令有: vgcreate 、 vgscan 、 vgdisplay 、 vgextend 、 vgreduce 、 vgchange 和 vgremove 。創建一個新卷組可以執行類似這樣的命令:
# vgcreate /dev/hdb{1 , 2 , 3} NewVolGroup
我們知道卷組是由多個物理卷構成的,現在我們將 /dev/hdb1 、 /dev/hdb2 和 /dev/hdb3 做成一個名為 NewVolGroup 的卷組,留下的那個用于放在后面說明如果動態增加或減少容量用。在卷組中額外添加或刪除物理卷的命令是 vgextend 和 vgreduce 。在創建創建卷組的這一時刻,可以給 vgcreate 命令傳遞“ -s ”選項指定物理擴展區 PE 的大小,比如 16M 。可能有同學會覺得設置較大的 PE 會導致磁盤的浪費。其實不然, PE 與磁盤的最小存儲單元“扇區”或“簇”不同,他只是 LVM 用于進行動態伸縮尺寸的一個最小分配單元,而在真正存儲文件的時候,還是會利用磁盤本身的最小存儲單元。
第四步是創建邏輯卷 LV ,就相當于對卷組這個大磁盤進行分區。與邏輯卷 LV 有關的命令有: lvcreate 、 lvscan 、 lvdisplay 、 lvextend 、 lvreduce 、 lvremove 和 lvresize 。出于方便考慮,我們將整個 VG 只劃分為一個 LV ,使用命令:
# lvcreate -l 3842 -n lv_data NewVolGroup
在這個命令中“ -l ”選項說明分配的 PE 數量,“ -n ”選擇則為新的 LV 命名。本例中 3842 正是我們現有的全部 PE 數量。我們從哪里獲得的呢?利用 vgdisplay 命令就行。
這樣,一個新的邏輯卷就創建完畢了。剩下的事情就是格式化并掛接它。我們使用如下命令:
# mkfs.ext4 /dev/mapper/NewVolGroup-lv_data
# mkdir /mnt/data
# mount /dev/mapper/NewVolGroup-lv_data/mnt/data
之后就可以使用 df 命令來確認這個新的磁盤使用情況了。
4.縮放邏輯卷
使用邏輯卷的目的就是沖著它能任意縮放的,所以如何縮放邏輯卷才是關鍵所在。我們先來看一下如何給邏輯卷增加容量。
我們之前特意留下了 /dev/hda4 來做這件事。在實際應用中,還需要經歷創建分區和物理卷的階段。將一個新的物理卷加入到一個已有的卷組中使用 vgextend 命令。在我們的例子中這樣操作:
$ vgextend NewVolGroup /dev/hda4
之后我們使用 vgdisplay 命令就能發現有新的 Free PE 出現,在我們的測試機中是 1274 個。這個階段是擴大了卷組的容量,但是邏輯卷的還沒有改變。還需要使用 lvresize 命令將新增加的 PE 加入到邏輯卷中。在我們的例子中這樣操作:
$ lvresize -l +1274/dev/mapper/NewVolGroup-lv_data
這樣再使用 vgdisply 命令就發現已經沒有 Free PE 了。不過這個時候我們使用 df 命令查看磁盤空間情況時,并沒有發現有什么變化。主要是因為我們還差一個步驟,就是執行 resize2fs 命令。具體的原因其實很簡單,我們新增加的那些磁盤空間還沒有格式化呢。這個命令很簡單,在我們的例子中只需要這樣:
$ resize2fs /dev/mapper/NewVolGroup-lv_data
這樣,我們的磁盤容量就增大了,完全是在線的,是不是相當神奇呢?
好了,說完了增加容量,就來看看如何減小容量吧。這次我們要把 /dev/hda1 抽出來。但是減小容量相對來講就要麻煩一些了,首先它就是不能在線的了。
我們先要確定 /dev/hda1 到底有多大,可以通過 pvdisplay 命令獲得。在我們的測試機中得到的結果是 5.01G 。而我們的硬盤是 20G 的,那么先要使用 resize2fs 命令將我們的磁盤調整到 20G-5.01G=14990M 的大小。我們執行這樣的命令:
# umount /mnt/data
# e2fsck -f /dev/mapper/NewVolGroup-lv_data
# resize2fs /dev/mapper/NewVolGroup-lv_data14990M
# mount /dev/mapper/NewVolGroup-lv_data/mnt/data
這之后我們再通過 df 命令查看就能看出磁盤容量已經縮減了。但是此時我們還有沒回收任何 PE 。這個時候還需要使用 lvresize 命令來回收 PE 。回收多少呢?當然是 /dev/hda1 中含有的那些了。通過 pvdisplay 命令可以查到有 1282 個,所以執行命令:
# lvresize -l -1282/dev/mapper/NewVolGroup-lv_data
那現在是不是就可以將 /dev/hda1 抽出來了呢?還不行。因為通過 pvdisplay 命令發現, /dev/sda1 并沒有空閑的 PE ,而空閑的 PE 現在在 /dev/sda3 和 /dev/sda4 上。 /dev/sda4 上有 1274 個 Free PE ,而 /dev/sda3 上有 8 個 Free PE (總共 1280 個 PE) 。要抽出 /dev/sda1 ,必須是的它的全部 PE 為 Free 狀態,這個可以借由 pvmove 命令完成。在我們這個場景中可以使用類似這樣的命令:
# psmove /dev/hda1:0-1273 /dev/hda4:0-1273
# psmove /dev/hda1:1274-1281/dev/hda3:1272-1279
這之后再使用 pvdisplay 查看,就發現 /dev/sda1 的 PE 都為 Free 狀態了。這之后就可以使用 vgreduce 命令,將 /dev/sda1 抽出了。在我們的場景中可執行類似這樣的命令:
# vgreduce NewVolGroup /dev/hda1
需要提醒大家一下,在我們這個例子中,由于 /dev/sda1 是所有分區中最大的一個,使得無法將它的整個數據移入到任何其他分區中,所以我們在使用 psmove 命令的時候參數有些復雜。但是這種情況卻是在實際應用當中經常遇到的情況。如果遇到了目標分區空余空間比原分區大的時候, PE 編號范圍就可以省略了。順便提一句, PE 編號是從零開始的。
總結
以上是生活随笔 為你收集整理的融于心而表于行 之 磁盘的管理方式 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。