我經常用虛擬機裝各種版本的Linux系統來跑程序,一般硬盤分得比較小。比如CentOS 6就只分了16G,跑的是服務端的程序,不用安裝界面,整個系統也就占3G不到,一般也夠用。直到某一天,我需要把一個20G的sql腳本導入到數據庫里。這才發覺自己從來沒做過Linux的硬盤擴容,一番鼓搗之后,做個筆記本留檔。
現在主流的Linux,基本都使用LVM分區。哪啥是LVM?這得先來了解一下基礎概念。Logical Volume Manager
中文名叫邏輯卷管理器,簡稱LVM,它是Linux下對邏輯卷進行管理的一套程序,LVM分區,就是LVM管理下的一個邏輯卷。LVM通常涉及下面幾個術語:
-
PP(physical Partition)
物理分區,通常指硬盤中的主分區,邏輯分區。嚴格來講整個硬盤或者其他能存東西的物理介質包括網絡存儲也能作為一個物理分區,但一定是有實物的 -
PV(Physical Volume)
物理卷,就是在PP(物理分區)的基礎上,使用pvcreate
指令寫入一些數據,轉換為可供LVM識別后的物理介質。 -
VG(Volumes Group)
卷組,由一個或多個PV組成的一個分組,形成一大塊存儲空間 -
LV(Logical Volume)
邏輯卷,也就是LVM分區,在VG上划分一塊空間稱為邏輯卷,一個VG上只要還有空間就可以建立多個LV。在邏輯卷之上可以建立文件系統(ext3、ext4等),然后即可把數據存到分區里 -
PE(Physical Extent)
具有唯一編號的PE是可以被LVM尋址的最小單元,其大小是在創建VG時確定的,默認為4MB(可通過vgcreate -s
指定)。一個VG包含N個PE,從VG上划分一塊空間作為LV時就是把其中一部分數量的PE標記為該LV。
它們之間的關系,可以簡單地概括為:一塊硬盤,被分成了幾個分區(PP),然后把PP轉換為PV,多個PV可以組成一個VG。組成VG后,就得到了一塊很大的空間,它的大小是以PE的來衡量的。現在從VG上划分一塊空間形成一個LV,然后就可以在LV上創建文件系統,進行讀寫數據。
(圖片來源於網絡)
這么做的目的,就是把物理存儲介質和具體使用的空間解耦,例如/home
這個文件夾,可能一部分在硬盤A,另一部分在硬盤B。這就是為什么被稱為邏輯卷
,因為這個卷是通過邏輯虛擬出來的,物理上不存在這個卷。解耦之后整個系統的空間就可以方便的擴容、更換物理介質,這對長期運行,不停服更換硬件的服務器很重要。
我的CentOS 6是在VritualBox中以一個硬盤以默認方式安裝的,它的分區如下:
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
14G 2.1G 11G 16% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/sda1 477M 34M 418M 8% /boot
可以看到,默認情況下只有一個根分區,從參數/dev/mapper/VolGroup-lv_root
可以看出來它是一個LVM分區。所有數據都存在這個唯一的分區里,所以這次就是要對這個分區進行擴容。
使用lsblk
則可以更清析地看到硬盤的分區結構
[root@localhost ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 58.2M 0 rom
sda 8:0 0 16G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 15.5G 0 part
├─VolGroup-lv_root (dm-0) 253:0 0 13.9G 0 lvm /
└─VolGroup-lv_swap (dm-1) 253:1 0 1.6G 0 lvm [SWAP]
可以看到系統中有一個光驅sr0
;一個硬盤sda
。硬盤被分為兩個區(sda1、sda2),而sda2被划分為兩個LVM分區(VolGroup-lv_root、VolGroup-lv_swap)。假如需要看到硬盤的一些更詳細的信息,可以使用parted
:
[root@localhost ~]# parted /dev/sda
GNU Parted 2.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print all
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 17.2GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 525MB 524MB primary ext4 boot
2 525MB 17.2GB 16.7GB primary lvm
可以看到當前這個硬盤大小為17.2GB,有兩個主分區,一個為ext4,另一個被標記為lvm。對於這個lvm管理的分區,它有PV、VG、LV等參數,可通過pvdisplay、vgdisplay、lvdisyplay打印出來:
[root@localhost ~]# pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name VolGroup
PV Size 15.51 GiB / not usable 3.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 3970
Free PE 0
Allocated PE 3970
PV UUID XydIzE-RJIT-Hcfc-5vCw-NnKE-goPE-VFwhn3
[root@localhost ~]# vgdisplay
--- Volume group ---
VG Name VolGroup
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 3
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 1
Act PV 1
VG Size 15.51 GiB
PE Size 4.00 MiB
Total PE 3970
Alloc PE / Size 3970 / 15.51 GiB
Free PE / Size 0 / 0
VG UUID 43d3d6-xFIm-s2vF-Z1jY-pKBc-sniG-wT0VTL
[root@localhost ~]# lvdisplay
--- Logical volume ---
LV Path /dev/VolGroup/lv_root
LV Name lv_root
VG Name VolGroup
LV UUID 2OJpKu-4KI9-DpUX-ZiVl-wanM-gdlY-yMbCau
LV Write Access read/write
LV Creation host, time localhost.localdomain, 2022-03-14 17:48:16 +0800
LV Status available
# open 1
LV Size 13.91 GiB
Current LE 3561
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0
--- Logical volume ---
LV Path /dev/VolGroup/lv_swap
LV Name lv_swap
VG Name VolGroup
LV UUID jWqLXl-yzPu-xzJ9-ao4a-9JB5-KYXu-X2niXP
LV Write Access read/write
LV Creation host, time localhost.localdomain, 2022-03-14 17:48:18 +0800
LV Status available
# open 1
LV Size 1.60 GiB
Current LE 409
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:1
通過上面的信息,可以看到整個系統中有一個PV(物理卷,也就是sda2這個分區);有一個VG名字叫VolGroup,一共有3970個PE,每個PE大小為4MB,所以整個VG大小為15.51GB,空閑的PE(Free PE)為0,說明空間都被用光了;有兩個LV,都是從VolGroup這個VG上划分出來的,一個13.91GB,一個1.6GB。
了解當前系統的信息后,開始對硬盤進行擴容。由於是虛擬機,就不用去買新硬盤了,可以直接在虛擬機上調整硬盤大小。VirtualBox的操作方式為:
關閉虛擬機,在菜單“管理/虛擬介質管理”中找到對應虛擬機的硬盤,設置新的大小即可。
我這里直接把它調整到128GB,現在重新啟動虛擬機,df -h
可以看到各個分區大小沒變,而parted
使用print free可以看到硬盤大小變了,后面多出120G空間。這是因為系統是根據分區表來確定分區大小的,新加的空間沒法直接使用。
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
14G 2.1G 11G 16% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/sda1 477M 34M 418M 8% /boot
[root@localhost ~]# parted /dev/sda
GNU Parted 2.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 137GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
32.3kB 1049kB 1016kB Free Space
1 1049kB 525MB 524MB primary ext4 boot
2 525MB 17.2GB 16.7GB primary lvm
17.2GB 137GB 120GB Free Space
(parted)
如果是新增一個硬盤,可以直接整個硬盤作為一個PP轉換為PV(當然把整個硬盤格式化成一個分區來操作也是可以的)
pvcreate /dev/sdc
Physical volume "/dev/sdc" successfully created
但現在是在原有硬盤上擴展空間,因此只能分區。分區使用fdisk
或者parted
都可以,這里用更廣泛一些的fdisk
[root@localhost ~]# fdisk /dev/sda
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (2089-16709, default 2089):
Using default value 2089
Last cylinder, +cylinders or +size{K,M,G} (2089-16709, default 16709):
Using default value 16709
Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 8e
Changed system type of partition 3 to 8e (Linux LVM)
Command (m for help): p
Disk /dev/sda: 137.4 GB, 137438953472 bytes
255 heads, 63 sectors/track, 16709 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000a342
Device Boot Start End Blocks Id System
/dev/sda1 * 1 64 512000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 64 2089 16264192 8e Linux LVM
/dev/sda3 2089 16709 117437826+ 8e Linux LVM
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
Command (m for help): n
使用n指令創建分區,選p創建主分區(由上面的信息可知,默認情況下系統分了sda1 sda2兩個主分區,那我干脆也分一個主分區3)
Partition number (1-4): 3
設置主分區id為3,即sda3
First cylinder (2089-16709, default 2089):
輸入分區開始的第一個扇區,默認為空閑空間的第一個扇區2089,所以我這里直接回車
Last cylinder, +cylinders or +size{K,M,G} (2089-16709, default 16709):
輸入分區結束的最后一個扇區,默認為空閑空間的最后一個扇區16709,所以我這里直接回車
Command (m for help): t
使用t指令修改分區的類型
Partition number (1-4): 3
選擇要修改的分區id
Hex code (type L to list codes): 8e
選擇分區的類型(8e就表示lvm),輸入l可列出所有支持的類型
Command (m for help): p
現在打印一下當前分區表,確認是不是自己想要的
Command (m for help): w
確認分區表正確后,用w寫入硬盤。我這里出現了一個警告,按提示是要重啟一下
現在把新建的分區sda3
轉換為PV。由於我忽略了上面的警告,結果找不到sda3
,這可能和VirtualBox的硬盤模擬有關,其他機子不一定會出現:
[root@localhost ~]# pvcreate sda3
Device sda3 not found (or ignored by filtering).
重啟后再執行即可
[root@localhost ~]# pvcreate /dev/sda3
Physical volume "/dev/sda3" successfully created
由之前vgdisplay
查看的數據可知道,當前系統有一個名字為VolGroup的VG,現在要把剛轉換好的PV添加到這個VG里
[root@localhost ~]# vgextend VolGroup /dev/sda3
Volume group "VolGroup" successfully extended
再次用vgdisplay
,可以看到VG已經被擴大,現在有很多空閑的PE了
[root@localhost ~]# vgdisplay
--- Volume group ---
VG Name VolGroup
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 2
Act PV 2
VG Size 127.50 GiB
PE Size 4.00 MiB
Total PE 32641
Alloc PE / Size 3970 / 15.51 GiB
Free PE / Size 28671 / 112.00 GiB
VG UUID 43d3d6-xFIm-s2vF-Z1jY-pKBc-sniG-wT0VTL
由之前lvdisplay
查看的數據可知道,當前有兩個LV,一個lv_swap
路徑為/dev/VolGroup/lv_swap
,一個lv_root
路徑為/dev/VolGroup/lv_root
。記住路徑,下面的擴容操作是使用路徑來操作。現在需要對lv_root
進行擴容
[root@localhost ~]# lvextend -l +100%FREE /dev/VolGroup/lv_root
Size of logical volume VolGroup/lv_root changed from 13.91 GiB (3561 extents) to 125.91 GiB (32232 extents).
Logical volume lv_root successfully resized.
上面是使用百分比來擴容,通過lvextend --help
可以知道,還有很多種方式指定擴容的單位,比如
# 使用M、G等常用單位擴容,支持的單位為[bBsSkKmMgGtTpPeE]
lvextend -L +10G /dev/VolGroup/lv_root
# 使用PE數量擴容,通用一個PE為4M。空閑PE的數量和單個PE的大小可通過`vgdisplay`查看
lvextend -l +2560 /dev/VolGroup/lv_root
lvm分區的大小擴展了,但是通過df -h
來查看,可以看到空間還是不變的。因為在lvm分區之上,linux還有一層文件系統(ext3、ext4等等),需要對文件系統擴展才行。ext3 和 ext4文件系統使用resize2fs
,其他系統查下資料才知道
[root@localhost ~]# resize2fs /dev/VolGroup/lv_root
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/VolGroup/lv_root is mounted on /; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 8
Performing an on-line resize of /dev/VolGroup/lv_root to 33005568 (4k) blocks.
The filesystem on /dev/VolGroup/lv_root is now 33005568 blocks long.
現在使用df -h
可以看到空間已經擴展了。
相比之下,Window的區分則顯得更加簡單、直觀。Windows的分區直接就是采用“物理卷”,即分區怎么分,在物理上就是怎么划分的,使用DiskGenius
或者傲梅分區助手
等流行的工具可以直觀地調整分區的大小
不過這種簡單也是有限制的,那就是需要進入PE系統來操作,沒辦法不停機操作(也許有,但我不會),當然這對於個人電腦來說並不是一個重要的指標。