Linux 中的物理卷、卷组、逻辑卷详解

一、概述

1. 相关概念

  • 物理卷(Physical Volume, PV):物理磁盘或分区
  • 卷组(Volume Group, VG):PV 的集合
  • 逻辑卷(Logic Volume, LV):VG 中划出来的一块逻辑磁盘
  • 逻辑卷管理(Logic Volume Manager, LVM):Linux 环境下对磁盘分区进行管理的一种机制,通过将底层的物理硬盘抽象的封装起来,然后以逻辑卷的方式呈现给上层应用
  • 物理磁盘或者磁盘分区转换为物理卷,一个或多个物理卷聚集形成一个或多个卷组,而逻辑卷就是从某个卷组里面抽象出来的一块磁盘空间

pv-vg-lv

2. 逻辑卷的用途

  • 物理磁盘直接分区、格式化为文件系统后就可以直接使用,而逻辑卷主要用来处理如下场景:
    • 业务上需要使用大容量的磁盘。比如需要在 /data 目录挂载 30TB 的存储,单个物理磁盘无法满足要求
    • 方便扩展和收缩磁盘。比如业务初期无法确定所需的磁盘空间,如果使用物理卷,扩展和收缩麻烦

二、创建物理卷

1. 环境准备

  • 为虚拟机添加了两块 2G 的磁盘 sdb 和 sdc
1
2
3
4
5
6
7
8
9
10
11
$ fdisk -l /dev/sdb /dev/sdc

Disk /dev/sdb: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sdc: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

2. sdb 使用磁盘直接创建物理卷

  • 物理磁盘可以直接添加到 LVM 物理卷中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 将sdb磁盘直接创建为物理卷(注意该命令将格式化磁盘上的所有数据)
$ pvcreate /dev/sdb
Physical volume "/dev/sdb" successfully created.

# 查看物理卷信息(pvdisplay、pvs)
$ pvdisplay /dev/sdb
"/dev/sdb" is a new physical volume of "2.00 GiB"
--- NEW Physical volume ---
PV Name /dev/sdb
VG Name
PV Size 2.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID dNrZgG-S7uw-mWNG-S8FG-lj27-YKgN-0fU0Ev
$ pvs
PV VG Fmt Attr PSize PFree
/dev/sdb lvm2 --- 2.00g 2.00g

3. sdc 使用磁盘分区创建物理卷

  • 如果想要使用 LVM 管理磁盘分区,可以使用 fdisk 将其分区类型 ID 改为 LVM 可以识别的值,即 8e
  • sdc 新建了两个 1G 的主分区,并将分区类型 ID 从 83(Linux)改为了 8e(Linux LVM),具体操作详见:https://www.itcoca.cn/linux/mount-disk.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$ fdisk -l /dev/sdc

Disk /dev/sdc: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x19b0f5b2

Device Boot Start End Blocks Id System
/dev/sdc1 2048 2099199 1048576 8e Linux LVM
/dev/sdc2 2099200 4194303 1047552 8e Linux LVM

# 将sdc1和sdc2磁盘分区创建为物理卷
$ pvcreate /dev/sdc1
Physical volume "/dev/sdc1" successfully created.
$ pvcreate /dev/sdc2
Physical volume "/dev/sdc2" successfully created.

# 查看物理卷信息
$ pvdisplay /dev/sdc1 /dev/sdc2
"/dev/sdc1" is a new physical volume of "1.00 GiB"
--- NEW Physical volume ---
PV Name /dev/sdc1
VG Name
PV Size 1.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID XkZj6m-h65A-tSPx-uX6Z-5Nyr-QX1b-pwolMq

"/dev/sdc2" is a new physical volume of "1023.00 MiB"
--- NEW Physical volume ---
PV Name /dev/sdc2
VG Name
PV Size 1023.00 MiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID 0xlegc-np4k-LjDg-wx2U-Vy1W-jLGf-2Gv2E1
$ pvs
PV VG Fmt Attr PSize PFree
/dev/sdc1 lvm2 --- 1.00g 1.00g
/dev/sdc2 lvm2 --- 1023.00m 1023.00m

三、创建、扩容卷组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 1. 使用两个物理卷创建一个名为VG_TEST的卷组
$ vgcreate VG_TEST /dev/sdb /dev/sdc1
Volume group "VG_TEST" successfully created

# 2. 查看卷组(vgdisplay、vgs、vgscan)
$ vgdisplay VG_TEST
--- Volume group ---
VG Name VG_TEST
System ID
Format lvm2
Metadata Areas 2
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 2
Act PV 2
VG Size 2.99 GiB
PE Size 4.00 MiB # 扩展块大小,可通过`vgcreate -s 4M ...`指定
Total PE 766 # 总的扩展块数量
Alloc PE / Size 0 / 0
Free PE / Size 766 / 2.99 GiB
VG UUID JZLwlf-0SPy-Jgjx-VX4n-i1bo-znO3-VZY85j
$ vgs
VG #PV #LV #SN Attr VSize VFree
VG_TEST 2 0 0 wz--n- 2.99g 2.99g
$ vgscan
Reading volume groups from cache.
Found volume group "VG_TEST" using metadata type lvm2

# 3. 扩容卷组(添加新的物理卷)
$ vgextend VG_TEST /dev/sdc2
Volume group "VG_TEST" successfully extended
# 查看扩容后的卷组
$ vgs
VG #PV #LV #SN Attr VSize VFree
VG_TEST 3 0 0 wz--n- <3.99g <3.99g

四、创建、扩容逻辑卷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 1. 从卷组VG_TEST中创建一个名为lv_test,大小为1G的逻辑卷
$ lvcreate -L 1g -n lv_test VG_TEST # 或者使用`-l 256`指定256个扩展块,代替`-L 1g`
Logical volume "lv_test" created.

# 2. 查看逻辑卷(lvdisplay、lvs、lvscan)
$ lvdisplay /dev/VG_TEST/lv_test
--- Logical volume ---
LV Path /dev/VG_TEST/lv_test
LV Name lv_test
VG Name VG_TEST
LV UUID MbYfcB-0D9l-rm2E-LhRw-t5Nz-nVru-r5RzBY
LV Write Access read/write
LV Creation host, time linux130, 2024-02-22 15:26:22 +0800
LV Status available
# open 0
LV Size 1.00 GiB
Current LE 256 # 256个扩展块
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:2
$ lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_test VG_TEST -wi-a----- 1.00g
$ lvscan
ACTIVE '/dev/VG_TEST/lv_test' [1.00 GiB] inherit

# 3. 使用逻辑卷
$ mkfs.ext4 /dev/VG_TEST/lv_test # 创建文件系统
$ mkdir /test # 创建挂载点
$ mount /dev/VG_TEST/lv_test /test # 挂载文件系统
$ df -h # 查看结果
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VG_TEST-lv_test 976M 2.6M 907M 1% /test

# 4. 扩容逻辑卷(先用`vgs`看卷组是否有足够的空间)
$ lvextend -L +500M /dev/VG_TEST/lv_test
Size of logical volume VG_TEST/lv_test changed from 1.00 GiB (256 extents) to <1.49 GiB (381 extents).
Logical volume VG_TEST/lv_test successfully resized.
# 此时查看磁盘大小没有变化,需要重新调整文件系统大小
$ df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/VG_TEST-lv_test ext4 976M 2.6M 907M 1% /test
# 调整文件系统大小(**`ext`类型的用`resize2fs`;`xfs`类型的用`xfs_growfs`**)
$ resize2fs /dev/VG_TEST/lv_test
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/VG_TEST/lv_test is mounted on /test; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/VG_TEST/lv_test is now 390144 blocks long.
# 再次查看磁盘大小
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VG_TEST-lv_test 1.5G 3.0M 1.4G 1% /test

参考