Skip to content

一、生产故障场景与 LVM 概念 ​

在 Linux 服务器日常运维中,最令人紧张的高频告警之一就是:根分区 / 磁盘使用率达到 100%。

一旦根分区写满,系统将无法写入临时缓存(/tmp)、服务进程无法落盘日志,导致 Docker 容器批量退出、SSH 无法写入会话甚至系统彻底卡死。

如果服务器在初始装机时采用了 LVM(Logical Volume Manager) 逻辑卷管理,我们可以在**无需重启服务器、无需停服卸载(Umount)**的前提下,直接在线完成跨硬盘的根目录动态热扩容。

LVM 核心四层抽象概念: ​

text
物理硬盘或新挂载云盘 (/dev/sdb)
             │ fdisk 分区
             ▼
1. 物理卷 PV (Physical Volume)   ──► pvcreate /dev/sdb1
             │ 加入资源池
             ▼
2. 卷组 VG (Volume Group)         ──► vgextend vg_name /dev/sdb1 (聚合多个物理卷)
             │ 划分虚拟分区
             ▼
3. 逻辑卷 LV (Logical Volume)     ──► lvextend -L +100G /dev/vg_name/lv_name
             │ 格式化文件系统
             ▼
4. 文件系统 (ext4 / xfs)          ──► resize2fs / xfs_growfs 在线拉伸
  • PE(Physical Extent):LVM 可指派分配的最小物理单元(通常为 4MB)。

二、热扩容排查与实战流程 ​

步骤 1:排查当前磁盘与挂载拓扑(lsblk 与 df -hT) ​

bash
df -hT
# 查看当前根目录挂载点与文件系统类型
# 示例:/dev/mapper/ubuntu--vg-ubuntu--lv   ext4   98G   98G    0G  100% /

lsblk
# 发现新接入了一块尚未分区的 100GB 硬盘 sdb:
# sda      8:0    0  100G  0 disk 
# └─sda3   8:3    0   99G  0 part 
#   └─ubuntu--vg-ubuntu--lv 253:0 0 98.5G 0 lvm  /
# sdb      8:16   0  100G  0 disk   <-- 新硬盘待利用

步骤 2:对新硬盘进行分区打标(fdisk) ​

对新磁盘 /dev/sdb 建立新分区:

bash
fdisk /dev/sdb

在交互提示中依次输入:

  • n:新建分区;
  • 默认主分区编号(1),起始与结束扇区回车选默认值(占满 100G);
  • t:更改分区类型代码,输入 8e(Linux LVM)或 GPT 格式下的对应类型;
  • w:保存分区表并写入磁盘。

此时执行 lsblk,可以看到新分区 /dev/sdb1 已成功生成。


步骤 3:创建物理卷 PV(pvcreate) ​

将裸分区转化为 LVM 能够管理的物理卷:

bash
pvcreate /dev/sdb1
# 输出:Physical volume "/dev/sdb1" successfully created.

# 查看已创建的物理卷信息
pvdisplay

步骤 4:将新物理卷扩充至已有卷组 VG(vgextend) ​

查看当前根目录所属的卷组名称(如 ubuntu-vg):

bash
vgdisplay
# 记录 VG Name: ubuntu-vg

# 将 /dev/sdb1 纳入该卷组的存储池中
vgextend ubuntu-vg /dev/sdb1
# 输出:Volume group "ubuntu-vg" successfully extended

再次执行 vgdisplay,可以看到 Free PE / Size 已经新增了近 100GB 的可用空闲空间。


步骤 5:在线伸展逻辑卷 LV(lvextend) ​

将卷组中新增的可用空间全部扩充到根目录逻辑卷上:

bash
# 将 /dev/sdb1 的所有可用空间全部追加进逻辑卷
lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

# 或者指定扩容具体的容量大小
# lvextend -L +99G /dev/ubuntu-vg/ubuntu-lv

输出反馈:

text
Size of logical volume ubuntu-vg/ubuntu-lv changed from 98.50 GiB to 198.50 GiB.
Logical volume ubuntu-vg/ubuntu-lv successfully resized.

步骤 6:在线刷新文件系统容量(关键一步) ​

很多工程师做完 lvextend 后发现 df -h 查出来的根目录大小依然没变。这是因为底层逻辑卷的边界虽然拉大了,但上层操作系统文件系统的元数据尚未更新。

根据 df -hT 查出的文件系统类型,选用对应的拉伸命令:

情况 A:对于 EXT4 文件系统(使用 resize2fs) ​

bash
resize2fs /dev/ubuntu-vg/ubuntu-lv
# 输出:The filesystem on /dev/ubuntu-vg/ubuntu-lv is now 52034560 (4k) blocks long.

情况 B:对于 XFS 文件系统(CentOS / RHEL 默认,使用 xfs_growfs) ​

bash
# 注意:xfs_growfs 后面跟的是挂载点目录路径,而不是设备路径!
xfs_growfs /

三、成果验证与安全防范 ​

再次执行 df -hT:

bash
df -hT /
# Filesystem                         Type  Size  Used Avail Use% Mounted on
# /dev/mapper/ubuntu--vg-ubuntu--lv  ext4  196G   31G  156G  17% /

根分区可用空间瞬间扩容至近 200GB,使用率从 100% 骤降至 17%,整个过程零停机、零业务重启。

生产注意事项: ​

  1. 只能扩容不能轻易缩容:LVM 扩容是安全的,但如果尝试对逻辑卷进行缩小(lvreduce),极易导致文件系统超级块损坏和数据丢失,生产环境严禁随意线上缩容;
  2. 提前做重要配置备份:在操作磁盘分区(fdisk)前,务必仔细核对盘符名称(/dev/sdb vs /dev/sda),防止手误误删正在运行的系统主盘分区。

测试开发工程师 · 专注自动化与系统架构 | 邮箱: hansblog@atumsoul.win