Skip to content

LVM

LVM 是逻辑卷管理(Logical Volume Manager)的缩写,是 Linux 下对磁盘分区进行管理的一种机制。

LVM 和 普通分区

普通分区和 LVM 的区别用一个图来表示:

lvm vs pat

普通分区通常需要在安装期间就需要决定。在正在运行的系统中修改普通分区是比较困难的事情。

而 LVM 提供了一种中间层即卷组(VG)他屏蔽了底层的区别,卷组是允许跨多个物理磁盘的,而普通分区通过逻辑卷(LV)提供。操作系统访问这些逻辑卷(LV)而不是物理分区。卷组(VG)可以跨多个磁盘,这样多个磁盘或部分磁盘可以构成一个 VG。LVM 以这种方式提供了一种对物理磁盘空间的抽象,从而能够以比物理分区更方便、更安全的方式更改硬盘空间的分段。

LVM 模型

lvm module

上图是经典的 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 pat

上图是一个标准的 基于 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 的操作流程:

Bash
[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 不同模型的详细信息:

Bash
[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 的前提是需要新的磁盘空间被添加,这有两种情况下:

  1. 现有磁盘有空余容量(对应虚拟机中的添加磁盘空间)
  2. 插入新的磁盘(虚拟机中可以添加额外的虚拟磁盘)

无论哪种方式都需要使用 fdisk 等分区工具来创建一个传统分区:

  1. 现有磁盘有空余容量: fdisk /dev/sda一定不要重新创建分区表,因为已经存在分区表了,直接 n 创建新的分区并指定Linxu LVM即可
  2. 插入新的磁盘: 需要使用 fdisk /dev/sdb 创建磁盘分区的常规操作: 创建分区表->创建分区->更改分区类型->保存 即可

无论那种方式创建好分区之后还需要执行 pvcreate 命令将分区标记为 PV:

Bash
# 通过为现有磁盘添加额外的空间来创建 PV
[root@localhost ~]# pvcreate /dev/sda3
  Physical volume "/dev/sda3" successfully created

扩展 VG

创建好的 PV 需要添加到 VG 即存储池中,这通过 vgextend 命令实现:

Bash
[root@localhost ~]# vgextend VolGroup /dev/sda3
  Volume group "VolGroup" successfully extended

VolGroup 是 VG Name,可以通过 vgdisplay 查看,当我们扩展完成后重新查看下 vg 的属性:

Bash
[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 来实现:

Bash
[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 的形式来指定所用剩余空间,也可以是其他形式:

Bash
# 使用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 联机或脱机 仅限脱机
Bash
[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.