LVM
LVM 是逻辑卷管理(Logical Volume Manager)的缩写,是 Linux 下对磁盘分区进行管理的一种机制。
LVM 和 普通分区
普通分区和 LVM 的区别用一个图来表示:
普通分区通常需要在安装期间就需要决定。在正在运行的系统中修改普通分区是比较困难的事情。
而 LVM 提供了一种中间层即卷组(VG)他屏蔽了底层的区别,卷组是允许跨多个物理磁盘的,而普通分区通过逻辑卷(LV)提供。操作系统访问这些逻辑卷(LV)而不是物理分区。卷组(VG)可以跨多个磁盘,这样多个磁盘或部分磁盘可以构成一个 VG。LVM 以这种方式提供了一种对物理磁盘空间的抽象,从而能够以比物理分区更方便、更安全的方式更改硬盘空间的分段。
LVM 模型
上图是经典的 LVM 模型视图,他表述了 LVM 涉及的几个重要的术语:
- PP(Physical Partition): 物理分区,这个可能有歧义,这实际上指代的是物理硬盘
- PV(Physical Volume): 物理卷,可以认为就是普通的分区,不过分区类型通常需要设置为 8e(Linux LVM)。还需要使用 pvcreate 转换一下
- VG(Volumes Group): 卷组,由一个或多个 PV 构成的分组形成一个整体的存储空间,他可用看作是普通分区时的磁盘
- LV(Logical Volume): 逻辑卷,也就是 LVM 中的分区。文件系统就是建立在 LV 之上的
- PE(Physical Extent): 物理区域,指定卷组中最小物理单位,类似于扇区的概念。默认是 4M,创建 LV 实际上是指定需要多少个 PE
LVM 通过将多个磁盘抽象成一个整体的 VG 作为存储空间,这样的好处就是如果添加了新的磁盘同样可用直接添加到这个 VG 中,而只要 VG 中还有空间就可以创建新的 LV 或者更改 LV 的大小。这样极大的提高了磁盘管理的灵活性。
LVM 分区模拟
上图是一个标准的 基于 LVM 分区的环境,其中:
/dev/hdc
: 创建了两个分区(fdisk 命令创建)/dev/hdc1 -> /boot
: 第一个分区挂载到/boot
路径用于系统引导(如果是 GPT/UEFI 通常还需要指定类型为 EFI 分区)/dev/hdc2
: 添加到 VG 中
/dev/hda
和/dev/hdb
都是单分区直接用于构造 VG
之后我们真正使用的分区需要从 VG 中来创建,这个就是 LV:
/
: 挂载根目录/home
: 挂载家目录
而没有使用 Free Space 能够构造其他的 LV。
整个过程中比较特殊的就是传统分区,他可以作为传统分区那样被使用(
/boot
),还能够作为 PV 为 VG 提供存储池
LVM 实际操作: 磁盘扩容
我们以添加一个新的硬盘为例来说明整个 LVM 的操作流程:
[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]
/dev/sda
有两个分区,其中 /dev/sda1
是传统分区被挂载到了 /boot
上用于系统引导。而 /dev/sda2
被作为 LVM 的 PV 分区。
查看目前 LVM 分区
使用 pv|vg|lvdisplay
可以查看 LVM 不同模型的详细信息:
[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
创建 PV 的前提是需要新的磁盘空间被添加,这有两种情况下:
- 现有磁盘有空余容量(对应虚拟机中的添加磁盘空间)
- 插入新的磁盘(虚拟机中可以添加额外的虚拟磁盘)
无论哪种方式都需要使用 fdisk 等分区工具来创建一个传统分区:
- 现有磁盘有空余容量:
fdisk /dev/sda
时一定不要重新创建分区表,因为已经存在分区表了,直接 n 创建新的分区并指定Linxu LVM
即可 - 插入新的磁盘: 需要使用
fdisk /dev/sdb
创建磁盘分区的常规操作:创建分区表->创建分区->更改分区类型->保存
即可
无论那种方式创建好分区之后还需要执行 pvcreate 命令将分区标记为 PV:
# 通过为现有磁盘添加额外的空间来创建 PV
[root@localhost ~]# pvcreate /dev/sda3
Physical volume "/dev/sda3" successfully created
扩展 VG
创建好的 PV 需要添加到 VG 即存储池中,这通过 vgextend 命令实现:
VolGroup 是 VG Name,可以通过 vgdisplay 查看,当我们扩展完成后重新查看下 vg 的属性:
[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
可以看到Free PE/Size
中有了新的空余。
vgcreate -s 4M VG-Name PV_Device
这样的形式来创建 vg 不过通常在安装 Linux 系统时创建
扩展 LV
当前存在两个 LV:
/dev/VolGroup/lv_swap
/dev/VolGroup/lv_root
只要 VG 中有 Free PE 我们就可以为 LV 添加额外的空间,这可以使用 lvextend 来实现:
[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.
上面使用 -l +100%Free
的形式来指定所用剩余空间,也可以是其他形式:
# 使用M、G等常用单位扩容,支持的单位为[bBsSkKmMgGtTpPeE]
lvextend -L +10G /dev/VolGroup/lv_root
# 使用PE数量扩容,通用一个PE为4M。空闲PE的数量和单个PE的大小可通过`vgdisplay`查看
lvextend -l +2560 /dev/VolGroup/lv_root
如果要新建 LV 可以使用
lvcreate -L 10G -n lv_home VolGroup
的方式来实现
扩展文件系统大小
扩展 LV 仅仅是为 LV 添加了容量,而要想容量可用还需要扩展文件系统的大小,也就是说所谓的格式化。不过这种格式化不能影响原有的数据:
文件系统 | 实用程序 | 增加大小(增大) | 减小大小(收缩) |
---|---|---|---|
Btrfs | btrfs filesystem resize | 联机 | 联机 |
XFS | xfs_growfs | 联机 | 不支持 |
Ext2/3/4 | 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.