传统分区方案中,分区大小在创建时就固定了,扩展需要停机、备份、重建分区。LVM (Logical Volume Manager) 在物理磁盘和文件系统之间引入了抽象层,实现了动态扩容、快照、跨磁盘等能力。
┌────────────────────────────────────────────────┐
│ 文件系统 (ext4/xfs/btrfs) │
│ 挂载在 /dev/vg0/data │
├────────────────────────────────────────────────┤
│ LV (Logical Volume) 逻辑卷 │
│ 可动态扩展/缩减的逻辑磁盘 │
├────────────────────────────────────────────────┤
│ VG (Volume Group) 卷组 │
│ PV的集合,磁盘池 │
├────────────────────────────────────────────────┤
│ PV (Physical Volume) 物理卷 │
│ /dev/sdb1 /dev/sdc1 /dev/sdd1 │
├────────────────────────────────────────────────┤
│ 物理磁盘 │
│ /dev/sdb /dev/sdc /dev/sdd │
└────────────────────────────────────────────────┘
| 概念 | 缩写 | 说明 |
|---|---|---|
| Physical Volume | PV | 物理磁盘或分区,LVM的底层单元 |
| Volume Group | VG | PV的集合,相当于磁盘池 |
| Logical Volume | LV | 从VG中分配的逻辑卷,可格式化挂载 |
| Physical Extent | PE | PV的最小分配单元(默认4MB) |
| Logical Extent | LE | LV的最小分配单元,与PE一一对应 |
$ pvs
${OUT_PVS}
$ vgs
${OUT_VGS}
$ lvs
${OUT_LVS}
$ lsblk
${OUT_LSBLK}
# === 步骤1:创建物理卷(PV) ===
# 将磁盘或分区初始化为PV
sudo pvcreate /dev/sdb # 整块磁盘
sudo pvcreate /dev/sdc1 # 单个分区
sudo pvcreate /dev/sdb /dev/sdc1 /dev/sdd # 多个
# 验证
sudo pvdisplay
sudo pvs
# === 步骤2:创建卷组(VG) ===
# 将PV组合为VG
sudo vgcreate vg0 /dev/sdb /dev/sdc1
# 指定PE大小(默认4MB,大数据建议64MB)
sudo vgcreate -s 64M vg0 /dev/sdb
# 验证
sudo vgdisplay vg0
sudo vgs
# === 步骤3:创建逻辑卷(LV) ===
# 按大小创建
sudo lvcreate -L 50G -n data vg0
# 按百分比创建(使用VG全部剩余空间)
sudo lvcreate -l 100%FREE -n data vg0
# 按百分比创建(使用VG的50%)
sudo lvcreate -l 50%VG -n data vg0
# 验证
sudo lvdisplay /dev/vg0/data
sudo lvs
# === 步骤4:格式化并挂载 ===
sudo mkfs.ext4 /dev/vg0/data
sudo mkdir -p /mnt/data
sudo mount /dev/vg0/data /mnt/data
# 写入fstab(使用设备路径或UUID)
echo '/dev/vg0/data /mnt/data ext4 defaults,noatime 0 2' | sudo tee -a /etc/fstab
# 在线扩展LV(无需卸载!)
# 步骤1:检查VG剩余空间
sudo vgs
# 如果VG有剩余空间,直接扩展LV
# 步骤2:扩展LV
sudo lvextend -L +10G /dev/vg0/data # 增加10G
sudo lvextend -l +100%FREE /dev/vg0/data # 使用全部剩余空间
# 步骤3:扩展文件系统
sudo resize2fs /dev/vg0/data # ext4在线扩展
sudo xfs_growfs /mnt/data # xfs在线扩展(必须挂载状态)
# 合并为一步(ext4)
sudo lvextend -L +10G -r /dev/vg0/data # -r自动扩展文件系统
# 验证
df -h /mnt/data
# 当VG空间不足时,添加新磁盘
# 步骤1:创建新PV
sudo pvcreate /dev/sdd
# 步骤2:扩展VG
sudo vgextend vg0 /dev/sdd
# 步骤3:扩展LV
sudo lvextend -l +100%FREE /dev/vg0/data
# 步骤4:扩展文件系统
sudo resize2fs /dev/vg0/data
# ext4缩减流程(xfs不支持缩减)
# 步骤1:卸载文件系统
sudo umount /mnt/data
# 步骤2:检查文件系统
sudo e2fsck -f /dev/vg0/data
# 步骤3:缩减文件系统
sudo resize2fs /dev/vg0/data 30G # 缩减到30G
# 步骤4:缩减LV
sudo lvreduce -L 30G /dev/vg0/data # 必须与文件系统大小一致
# 步骤5:重新挂载
sudo mount /dev/vg0/data /mnt/data
LVM快照使用COW (Copy-On-Write) 技术:创建快照时不复制数据,仅记录元数据。当原始LV的数据块被修改时,旧数据块被复制到快照区域。快照空间只需预留变化量。
# 创建快照
sudo lvcreate -L 5G -s -n data-snap /dev/vg0/data
# -L 5G: 快照空间(变化量预估)
# -s: 快照标记
# -n: 快照名称
# 查看快照
sudo lvs
# 挂载快照(只读)
sudo mkdir -p /mnt/snap
sudo mount -o ro /dev/vg0/data-snap /mnt/snap
# 从快照恢复
sudo umount /mnt/data
sudo lvconvert --merge /dev/vg0/data-snap
# 合并后快照自动删除,需要重启或重新激活LV
# 删除快照
sudo lvremove /dev/vg0/data-snap
# 跨多个PV条带化,提升IO性能
sudo lvcreate -i 3 -I 64K -L 100G -n striped vg0
# -i 3: 跨3个PV
# -I 64K: 条带大小
# 创建2路镜像
sudo lvcreate -m 1 -L 50G -n mirrored vg0
# -m 1: 1份镜像(2路)
# 创建精简池
sudo lvcreate -L 100G -T vg0/thinpool
# 从精简池创建精简LV(可以超过池大小!)
sudo lvcreate -V 200G -T vg0/thinpool -n thinvol1
sudo lvcreate -V 500G -T vg0/thinpool -n thinvol2
# 总分配700G,但池只有100G,按需实际使用
# 查看VG状态
sudo vgscan
sudo vgdisplay vg0
# 如果PV设备丢失但VG仍可用
sudo vgreduce --removemissing vg0
# 如果PV设备恢复
sudo vgck vg0
# 手动激活VG
sudo vgchange -ay vg0
# 激活单个LV
sudo lvchange -ay /dev/vg0/data
# 查看不活跃的LV
sudo lvs -a -o +devices
在虚拟环境中完成以下操作(使用loop设备模拟):
# 创建loop设备模拟磁盘
dd if=/dev/zero of=/tmp/disk1.img bs=1M count=500
dd if=/dev/zero of=/tmp/disk2.img bs=1M count=500
sudo losetup /dev/loop10 /tmp/disk1.img
sudo losetup /dev/loop11 /tmp/disk2.img
# 创建PV → VG → LV → 格式化 → 挂载
sudo pvcreate /dev/loop10 /dev/loop11
sudo vgcreate vg_test /dev/loop10 /dev/loop11
sudo lvcreate -L 200M -n lv_test vg_test
sudo mkfs.ext4 /dev/vg_test/lv_test
sudo mkdir -p /mnt/lvm-test
sudo mount /dev/vg_test/lv_test /mnt/lvm-test
# 扩展LV
sudo lvextend -L +100M -r /dev/vg_test/lv_test
df -h /mnt/lvm-test
# 清理
sudo umount /mnt/lvm-test
sudo lvremove /dev/vg_test/lv_test
sudo vgremove vg_test
sudo pvremove /dev/loop10 /dev/loop11
sudo losetup -d /dev/loop10 /dev/loop11
✅ 理解PV → VG → LV三层架构
✅ 掌握LVM创建、扩展、缩减
✅ 学会LVM快照与恢复
✅ 了解条带化、镜像、精简配置
# 主配置文件
/etc/lvm/lvm.conf
# 常见配置项
# filter: 控制哪些设备被扫描
filter = [ "a|^/dev/sd.*|", "r|.*|" ] # 仅扫描sd设备
# 自动激活
auto_activation_volume_list = [ "vg0", "vg1" ]
# PE大小影响
# 小PE(4MB): 精细分配,但元数据大
# 大PE(64MB): 元数据小,但浪费空间
LVM底层使用Device Mapper (dm)框架。每个LV对应一个dm设备。
# 查看dm设备
dmsetup ls
dmsetup info /dev/vg0/data
# 查看dm设备表(映射关系)
dmsetup table /dev/vg0/data
| 特性 | LVM | ZFS | btrfs | 传统分区 |
|---|---|---|---|---|
| 动态扩容 | ✅ | ✅ | ✅ | ❌ |
| 快照 | ✅(COW) | ✅(原生) | ✅(原生) | ❌ |
| 数据校验 | ❌ | ✅ | ✅ | ❌ |
| 压缩 | ❌ | ✅ | ✅ | ❌ |
| 去重 | ❌ | ✅ | 部分 | ❌ |
| RAID | 需mdadm | ✅(原生) | ✅(原生) | ❌ |
| 成熟度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |