传统分区一旦划死,扩容就要动分区表,风险高还常常得停机。LVM(Logical Volume Manager,逻辑卷管理器)在物理磁盘和文件系统之间加了一层抽象,让存储空间可以像内存一样按需分配、在线扩容。这篇把 LVM 的核心概念、适用场景和从零建卷的完整流程一次讲清,建卷、扩容、缩容防呆均在 Rocky Linux 9.3 容器(lvm2 2.03.33)用两块 loop 盘实测。

三个核心概念

LVM 的存储虚拟化靠三层结构撑起来:

  • 物理卷(PV):最底层的基本单位,一块整盘或一个分区,初始化后即可交给 LVM 使用。
  • 卷组(VG):把多个物理卷攒成一个存储池,容量在池里统一调度。
  • 逻辑卷(LV):从卷组里切出来的可用空间,相当于增强版的分区——可以动态调整大小而不影响已有数据。

一句话串起来:盘初始化成 PV,PV 攒成 VG 池子,LV 是从池子里切出来直接格式化挂载的”分区”。池子不是无限细分的:空间按 PE(Physical Extent,物理扩展单元,默认 4MB)切分,LV 的容量只能是 PE 的整数倍——这解释了后面”要 30M 拿到 32M”的现象。

什么场景适合用 LVM

  1. 动态调整存储:业务涨了要扩容,不用中断服务,在线给逻辑卷加空间。
  2. 快照:对逻辑卷打快照做备份和恢复,升级前留一手。
  3. 磁盘镜像和条带化:提升数据可靠性或读写速度。

反例也明确:单机小盘、容量结构一眼望到头的机器,直接分区更简单,不必为一层抽象付学习成本。

安装就一条命令:Rocky 9/CentOS 用 dnf install lvm2,Debian/Ubuntu 用 apt install lvm2——主流发行版装系统时通常已默认带上。

实操:从两块盘到一个可用逻辑卷

假设有两块硬盘 /dev/sdb 和 /dev/sdc,目标是建出一个 30G 的逻辑卷并挂载使用(实测用 60M 的 loop 盘代替,尺寸等比缩小)。

步骤 1:创建物理卷

1
sudo pvcreate /dev/sdb /dev/sdc

步骤 2:创建卷组

两块盘组成一个叫 my_volume_group 的存储池:

1
sudo vgcreate my_volume_group /dev/sdb /dev/sdc

步骤 3:创建逻辑卷

从卷组里分配 30G:

1
sudo lvcreate -L 30G -n my_logical_volume my_volume_group

实测三步全链(loop 盘路径替代 sdb/sdc;容器内核无法清零新建 LV,lvcreate 加了 -Z n -W n 跳过清零,实机不需要这两个参数):

配图1

读实测输出有个细节:要 30M,lvs 显示 32.00m——LV 容量按 PE 边界向上取整。所以”要 30G 得到 30.0G”未必精确,规划容量时留意。

步骤 4:格式化

1
sudo mkfs.ext4 /dev/my_volume_group/my_logical_volume

步骤 5:挂载

1
2
sudo mkdir /mnt/my_storage
sudo mount /dev/my_volume_group/my_logical_volume /mnt/my_storage

验证点:df -h /mnt/my_storage 能看到新文件系统,lsblk 里该 LV 出现在卷组树下。

开机自动挂载写 /etc/fstab 时,设备名优先用 /dev/mapper/my_volume_group-my_logical_volume 或 UUID(blkid 查),不要用 /dev/sdb 这类裸盘名——盘序在重启后可能漂移,写错会卡开机。

实例:在线扩容(LVM 的招牌动作)

写入 10M 数据后把 LV 从 30M 扩到 50M,全程不卸载:

1
2
3
# 先扩逻辑卷,再扩文件系统,两步缺一不可
sudo lvextend -L 50G /dev/my_volume_group/my_logical_volume
sudo resize2fs /dev/my_volume_group/my_logical_volume # ext4 支持在线扩

实测(50M 目标实际落在 52M 的 PE 边界):

配图2

结果:容量 26M→44M,挂载没断、先写入的 data.bin md5 前后一致。注意 lvextend 只扩了”容器”,文件系统必须 resize2fs 跟上——只跑 lvextend 时 df 不会变,这是新手最常见的”扩了个寂寞”。XFS 文件系统的对应命令是 xfs_growfs 挂载点,且 XFS 只能扩不能缩。

VG 池子本身也能长大:lvextend 报 Insufficient free space 时,说明该给池子进货了——加一块新盘,初始化成 PV 再并入 VG,两步:

1
2
sudo pvcreate /dev/sdd
sudo vgextend my_volume_group /dev/sdd

并入后 VG 空间变大,lvextend 就有料可切。整套扩容全在线,这正是”池子”结构的价值:盘、池、卷各扩各的,互不停机。

对比项 传统分区 LVM
扩容 动分区表,常需停机 在线 lvextend + resize2fs
跨盘聚合 不支持 VG 天然聚合多块盘
快照 需文件系统层支持 LV 级原生快照
缩容 同样危险 同样危险(先缩 fs 再缩 LV)

实例:快照

升级/改配置前留一手:

1
sudo lvcreate -s -L 5G -n my_snap /dev/my_volume_group/my_logical_volume

快照是某一瞬间的只读副本(COW 机制:改动写往原卷,旧数据冻结进快照卷),挂载后直接拷数据出来即可。恢复则反向用 dd 或还原工具。快照卷别建太小——原卷改动越多,快照消耗的空间越大,撑满后快照失效。

注:此命令未实跑——实验容器的内核缺少 dm-snapshot 目标(实测报 “Required device-mapper target(s) not detected in your kernel”),真实服务器内核自带该模块。

错误写法对比:lvreduce 直接缩

扩容安全、缩容危险。实测对已格式化的 LV 直接 lvreduce -L 10M,工具的防呆闸门弹了出来:

配图3

它检测到里面有 ext4,拒绝缩,并要求先 resize2fs 缩文件系统(或显式 --resizefs)。绕过这层闸门的方式——换设备名、加强转参数——就是丢数据的开始:LV 切掉的部分如果还有文件系统数据,直接损坏。缩容铁律:先缩文件系统,再缩逻辑卷,顺序不可反。

常用命令速查

命令 作用
pvs / vgs / lvs 一行摘要看 PV/VG/LV
pvdisplay / vgdisplay / lvdisplay 对象详情
lvextend -L +10G 给 LV 增加 10G(配合 resize2fs)
lvextend -l +100%FREE 把 VG 剩余空间全给某个 LV
lvcreate -s 创建快照卷
lvremove / vgremove / pvremove 逐层拆除(先卸载、按 LV→VG→PV 顺序)

注意事项

  • 执行任何 LVM 操作前备份重要数据,扩容安全、缩容危险,lvreduce 用错参数会直接毁数据。
  • 灵活不等于不用规划,VG 的容量还是要按业务预估。
  • 快照和镜像有额外性能开销,生产上开启前评估影响。
  • LV 容量按 PE 边界取整(实测 30M 落在 32M),精确容量规划要考虑 PE 粒度。
  • 拆除顺序不可乱:先 umount,再 lvremove、vgremove、pvremove,跳层操作会被拒绝或留残留。
  • 报错 “Device /dev/sdb not found” 先核对盘名与多路径别名;报 “No free physical extents” 多半是这块盘已被别的 VG 占用。

优缺点小结

优点:调整逻辑卷和卷组大小很轻松(实测扩容全程在线、缩容防呆闸门可靠);有快照功能支撑备份恢复;存储设备的管理效率比裸分区高。

缺点:对新手有学习曲线;引入额外的元数据和处理开销,极端场景影响性能;VG/LV 的管理需要一定配置经验。

总体来说,需要动态扩容或高可用存储的系统,LVM 值得作为默认选择;单机小盘、结构固定的场景,直接分区反而更简单。回到开场的”分区划死”:LVM 的答案是把”分区”变成池子里的一勺水,lvextend + resize2fs 两步、不中断服务——这就是它多付出一层抽象换来的东西。


本文由作者 2020-2024 年间的 CSDN 博客文章重构而来,原发布于 CSDN。