Add extra second disks using LVM to an existing Ubuntu Linux system to increase the size of root directory.
若是今天Linux的LVM空間不足了,現有硬碟整個容量用完了,我們可以買一個新硬碟插到電腦,將那個新硬碟空間加入到現有硬碟LVM的VG,從而擴充整個系統的空間。
即是說,讓原本Linux硬碟的根目錄(/
)的空間延展到第二個硬碟,將兩個硬碟合併為一個大硬碟使用。
本文Ivon的操作以Ubuntu 24.04 LTS系統為範例,請在系統安裝之初就啟用LVM。
1. 檢查現有的硬碟#
LVM操作的時候不用將電腦關機,可即時新增硬碟擴充容量。拆開機殼,將新硬碟插到電腦 。
了解一下LVM怎麼管理硬碟架構。對LVM而言,所有電腦上的實體硬碟都是屬於PV(Physical Volume),我們要把它加入到VG(Volume Group),才能分割為LV(Logical Volume),最後在LV新增檔案系統,給Linux掛載使用。其中VG、LV的空間是可以延展與縮小的。
要確認目前Linux電腦有哪些硬碟,用
lsblk
指令查看。Linux的硬碟代號通常是:/dev/hda
或/dev/sda
或/dev/nvme0
或/dev/vda
例如,我目前裝有Ubuntu的硬碟是
/dev/vda
,總空間128GB。Ubuntu桌面版安裝系統的時候自動切了三個分區,/dev/vda3
有一個LVM的VG叫做ubuntu-vg
,還有一個LV叫做ubuntu-lv
,掛載Linux的根目錄。
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 128G 0 disk
├─vda1 253:1 0 1G 0 part /boot/efi
├─vda2 253:2 0 2G 0 part /boot
└─vda3 253:3 0 124.9G 0 part
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm /
vdb 253:16 0 128G 0 disk
接著,我插入一個新的128GB硬碟,應該會是最下面的
/dev/vdb
,目前是屬於未分配空間。我們要將它新增為LVM的PV,再加入VG,最後才能將LV的根目錄空間延展到這個新的硬碟。
2. 能把HDD加入到SSD的VG嗎?#
其實可以,LVM不會管背後硬碟是什麼類型,但是兩者速度差太多不要這麼做吧!新增的第二個硬碟應該也要是同等速度的SSD。
雖然理論上可以將SSD的部份當成HDD的快取,增加整體LVM的讀寫效能,但是這樣搞更複雜了。
Linux並沒有規定一定要把硬碟加入LVM VG才能讀取,若你有一個額外的HDD資料碟,可以以一般mount指令的方式掛載,而不用加入VG。
若是硬要新增HDD,那麼應該獨立為一個LVM VG,不要跟SSD的混在一起。
本文Ivon使用的硬碟皆是SSD裝置,兩顆SSD的讀寫效能應該盡可能接近。
3. 將新硬碟格式化#
此為選擇性步驟。如果你的硬碟不是全新的,含有舊資料,務必將其格式化再繼續。
這裡新插入的硬碟為
/dev/vdb
,使用sudo fdisk /dev/vdb
指令將其格式化。下面為範例輸出,新增GPT分割表(硬碟超過2TB的話MBR無法定址),新增一個分割區
/dev/vdb1
,填滿整個硬碟,並將分區類型設定為Linux LVM
user@ubuntu:~$ sudo fdisk /dev/vdb
Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
命令 (m 以獲得說明): g
Created a new GPT disklabel (GUID: E928B73F-871B-440E-BC6D-BE44CBC9073F).
命令 (m 以獲得說明): n
分割區編號 (1-128, default 1):
First sector (2048-268435422, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-268435422, default 268433407):
Created a new partition 1 of type 'Linux filesystem' and of size 128 GiB.
命令 (m 以獲得說明): t
Selected partition 1
Partition type or alias (type L to list all): lvm
Changed type of partition 'Linux filesystem' to 'Linux LVM'.
命令 (m 以獲得說明): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
- 因為我們要將現有根目錄延展到這個硬碟,因此格式化以後不用新增檔案系統。
4. 新增硬碟到LVM的VG#
- 列出目前的硬碟,
/dev/vdb
有了一個分區/dev/vdb1
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 128G 0 disk
├─vda1 253:1 0 1G 0 part /boot/efi
├─vda2 253:2 0 2G 0 part /boot
└─vda3 253:3 0 124.9G 0 part
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm /
vdb 253:16 0 128G 0 disk
└─vdb1 253:33 0 128G 0 part
- 使用以下指令將新硬碟
/dev/vdb1
新增為PV,讓LVM能辨識到。中間若顯示remove GPT signature就輸入y。
sudo pvcreate /dev/vdb1
- 再將
/dev/vdb1
加入到ubuntu-vg
sudo vgextend ubuntu-vg /dev/vdb1
- 使用
sudo lvdisplay
指令確認目前的LV的空間
--- Logical volume ---
LV Path /dev/ubuntu-vg/ubuntu-lv
LV Name ubuntu-lv
VG Name ubuntu-vg
LV Size 128 GiB
ubuntu-vg
已經加入了新的PV/dev/vdb1
,所以讓ubuntu-lv
填滿剩餘可用空間
sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
- 使用
resize2fs
指令重新整理LV,調整過的LV大小才會真正變更。
sudo resize2fs -p /dev/ubuntu-vg/ubuntu-lv
- 使用
sudo lvdisplay
指令,可知道目前的LV容量變成了256GB
--- Logical volume ---
LV Path /dev/ubuntu-vg/ubuntu-lv
LV Name ubuntu-lv
VG Name ubuntu-vg
LV Size 252.94 GiB
- 使用指令
lsblk
檢視,你可以看到ubuntu-vg
旁邊顯示的總容量變成了256GB。
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 128G 0 disk
├─vda1 253:1 0 1G 0 part /boot/efi
├─vda2 253:2 0 2G 0 part /boot
└─vda3 253:3 0 124.9G 0 part
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm /
vdb 253:16 0 128G 0 disk
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm /
- 如此一來Linux根目錄的空間就會變大,兩個硬碟的空間就會合併在一起了。
5. 啟用交錯模式提升讀寫效能#
由於LVM預設採用線性模式(Linear),Linux會先將LVM中的第一個LV(也就是第一個硬碟)資料填滿之後,才開始往第二個LV放資料。
你可以用lvconvert
指令手動調整為交錯模式(Striped),讓Linux把資料分配存放在多個LV。若LV各自位於不同的硬碟的話,這樣能夠提升讀寫效能。
另外,lvconvert
能將LV作為LV的鏡射模式(Mirror),用於備份資料和提升容錯性。
不過要備份的話,先建置硬體RAID1再設定LVM可能是更好的做法。
6. 如何更換VG快壞掉的硬碟?#
如果第二個硬碟快壞了,如何將資料保存,並替換新硬碟?好問題,再買一個硬碟!然後把資料移動過去。
LVM提供pvmove
指令,能搬移一個PV的資料到另一個PV。把新硬碟插入電腦,新增為PV,加入VG,然後把壞掉舊硬碟用pvmove
移到新的硬碟,再從電腦移除壞掉的硬碟。
因為我們將全部的PV都掛在同一個VG下的LV的Linux根目錄,LVM不能夠編輯掛載中的硬碟,而根目錄是無法卸載的。這時若使用pvmove
會顯示無空間可移動(No extents available for allocation),且如果用lvreduce
把其中一個LV移除,整個Linux系統就炸掉了。
所以最好的辦法是使用LiveUSB去調整現有系統的LVM。
使用Ubuntu的LiveUSB開機
啟用目前電腦的LVM
sudo vgscan
sudo vgchange -ay
- 開啟終端機,使用
lsblk
確認現有硬碟,假設我要移除的硬碟是/dev/vdb
,而這裡我已經插入了第三個新的硬碟,顯示為/dev/vdc
。他的可用空間應該比/dev/vdb1
一樣或更多。
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 128G 0 disk
├─vda1 253:1 0 1G 0 part
├─vda2 253:2 0 2G 0 part
└─vda3 253:3 0 124.9G 0 part
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm
vdb 253:16 0 128G 0 disk
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm
vdc 253:32 0 128G 0 disk
- 參照前面的步驟,格式化並新增分區,將
/dev/vdc1
加入ubuntu-vg
,但不要延展ubuntu-lv
sudo fdisk /dev/vdc
sudo pvcreate /dev/vdc1
sudo vgextend ubuntu-vg /dev/vdc1
- 使用pvmove指令,將
/dev/vdb
的資料移動到/dev/vdc1
。
sudo pvmove /dev/vdb /dev/vdc1
- 等進度條跑完,再從
ubuntu-vg
移除/dev/vdb
sudo vgreduce ubuntu-vg /dev/vdb1
- 最後從PV移除
/dev/vdb
sudo pvremove /dev/vdb1
將電腦關機,拔掉舊硬碟。
重開機,使用
lsblk
查看硬碟分區狀況。
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 128G 0 disk
├─vda1 253:1 0 1G 0 part
├─vda2 253:2 0 2G 0 part
└─vda3 253:3 0 124.9G 0 part
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm
vdb 253:16 0 128G 0 disk
└─ubuntu--vg-ubuntu--lv 252:0 0 252.9G 0 lvm
7. 如何更換VG快壞掉的硬碟並搬移boot分區?#
假設是裝有Ubuntu系統的那個硬碟快壞掉了,那麼我們也是可以搬移資料。
插上一個新硬碟
開機進入Ubuntu LiveUSB,安裝以下套件
sudo apt install lvm2 arch-install-scripts
先給這個新硬碟進行硬碟分割,假設它的裝置為
/dev/vdc
,參照原有Ubuntu系統硬碟/dev/vda
的分割法,使用fdisk指令新增三個分割區出來,分為/boot
、/boot/efi
,還有要作為LVM的分割區。這樣我就有了三個分割區:/dev/vdc1
、/dev/vdc2
、/dev/vdc3
。啟用目前電腦的LVM
sudo vgscan
sudo vgchange -ay
- 將
/dev/vdc3
新增至VG
sudo pvcreate /dev/vdc3
sudo vgextend ubuntu-vg /dev/vdc3
- 將
/dev/vda3
資料搬移到/dev/vdc3
sudo pvmove /dev/vda3 /dev/vdc3
原本Ubuntu的boot分區資料也要搬移到新分區。
新增EFI檔案系統
sudo mkfs.vfat -F 32 /dev/vdc1
sudo mkfs.ext4 /dev/vdc2
- 將舊的
/boot
分區下的檔案複製到新分區
sudo mount /dev/vdc1 /mnt
sudo cp -av /boot/* /mnt/
sudo umount /mnt
sudo mount /dev/vdc2 /mnt
sudo cp -av /boot/efi/* /mnt/
sudo umount /mnt
- chroot到新硬碟上的系統
sudo mount /dev/mapper/ubuntu-vg-ubuntu-lv /mnt
sudo mount /dev/vdc1 /mnt/boot
sudo mount /dev/vdc2 /mnt/boot/efi
sudo arch-chroot /mnt
- 查看硬碟分區的blkid
sudo blkid /dev/vdc1
sudo blkid /dev/vdc2
- 編輯
/etc/fstab
,更新每個硬碟分區後面對應的UUID=
sudo vim /etc/fstab
- 重新安裝GRUB
sudo grub-install /dev/vdc
sudo update-grub
- 退出chroot
exit
- 將
/dev/vda3
從VG和PV移除
sudo vgreduce ubuntu-vg /dev/vda3
sudo pvremove /dev/vda3
- 重開機,拔掉舊硬碟。