Linux LVM 完全指南:动态磁盘空间动态管理
概述
在 Linux 系统中,传统磁盘分区存在一个致命局限:一旦格式化文件系统,后续想要扩展存储空间只能局限于同一物理硬盘的剩余空间。如果硬盘满了,就必须手动将数据迁移到更大的硬盘 —— 这个过程耗时且易出错的操作。
而 LVM(逻辑卷管理器,Logical Volume Manager) 恰好解决了这一痛点。它能将多个物理硬盘的分区(或整个硬盘)“整合” 成一个统一的存储池,再从中划分出 “逻辑卷” 供系统使用。无论是需要扩容(添加新硬盘到存储池)、缩容(释放空间给其他逻辑卷),还是更换物理硬盘,都无需重建文件系统或迁移数据,实现了磁盘空间的动态、灵活管理。
LVM 的核心由三部分组成,理解这三层结构是掌握 LVM 的关键:
- 物理卷(PV,Physical Volume):LVM 的 “最小存储单元”,可以是磁盘分区(如 /dev/sdb1)或整个物理硬盘(如 /dev/sdc),需通过 LVM 命令初始化(添加 LVM 元数据);
- 卷组(VG,Volume Group):LVM 的 “存储池”,由一个或多个 PV 组成。系统中可以创建多个 VG(如 “系统存储池”“数据存储池”),PV 只能属于一个 VG;
- 逻辑卷(LV,Logical Volume):LVM 的 “最终使用单元”,从 VG 中划分出来,可格式化(如 ext4、xfs)并挂载到系统目录(如 /data),使用体验与传统分区完全一致,但支持动态扩容 / 缩容。
一、LVM 基础操作:从 0 到 1 搭建逻辑卷
首次使用 LVM 需遵循 “创建 PV → 创建 VG → 创建 LV → 格式化 → 挂载” 的流程,每一步都有明确的命令和验证方式,以下以实际场景为例(假设已有三块空闲磁盘分区 /dev/sdb1、/dev/sdc1、/dev/sdd1)。
1. 第一步:准备工作(检查磁盘与分区)
在操作前,需确认目标磁盘 / 分区未被使用(无挂载点、无文件系统),避免数据覆盖。常用命令:
# 查看所有磁盘与分区的状态(含挂载点、文件系统)
lsblk
# 查看分区的详细信息(确认是否已初始化)
fdisk -l /dev/sdb # 替换为目标磁盘
- 关键验证点:目标分区(如 /dev/sdb1)的 “MOUNTPOINT” 列为空,“TYPE” 为 “part”(而非 “lvm”),说明未被使用。
2. 第二步:创建物理卷(PV)
使用 pvcreate 命令初始化分区,将其标记为 LVM 可用的 PV(会添加 LVM 元数据,不破坏原有数据,但建议对新分区操作):
# 初始化多个分区为 PV(需 root 权限,sudo 或切换至 root)
sudo pvcreate /dev/sdb1 /dev/sdc1 /dev/sdd1
# 验证 PV 创建结果(查看 PV 列表、状态、容量)
sudo pvdisplay # 详细信息(含 PV 路径、所属 VG、剩余空间)
sudo pvs # 简洁列表(快速查看所有 PV 状态)
成功标志:pvdisplay 中目标分区的 “Status” 为 “available”(未加入 VG),“PV Size” 与分区容量一致。
3. 第三步:创建卷组(VG)
使用 vgcreate 命令将多个 PV 整合为 VG(存储池),需指定 VG 名称(建议按用途命名,如 vg_data 用于数据存储,vg_system 用于系统):
# 1. 先检查系统已存在的 VG(避免重名,部分发行版默认创建 VG 用于根分区)
sudo vgdisplay
# 2. 创建 VG(名称为 vg_data,包含 /dev/sdb1 和 /dev/sdc1 两个 PV)
sudo vgcreate vg_data /dev/sdb1 /dev/sdc1
# 3. 验证 VG 创建结果
sudo vgdisplay vg_data # 查看指定 VG 的详细信息
sudo vgs # 简洁列表(查看所有 VG 的容量、PV 数量)
关键信息:vgdisplay 中 “Total PE”(物理扩展单元总数,LVM 最小分配单位)、“Free PE”(空闲空间)与 PV 总容量一致,说明 VG 创建成功。
4. 第四步:创建逻辑卷(LV)
使用 lvcreate 命令从 VG 中划分 LV,需指定 LV 大小和所属 VG,LV 名称默认以 lvol 开头(可自定义):
# 创建 LV:从 vg_data 中划分 10GB 空间,LV 名称为 lv_data(-n 指定名称,-L 指定大小)
sudo lvcreate -L 10G -n lv_data vg_data
# 验证 LV 创建结果
sudo lvdisplay /dev/vg_data/lv_data # 详细信息(含 LV 路径、大小、所属 VG)
sudo lvs # 简洁列表(查看所有 LV 的状态、容量)
LV 路径规则:/dev/[VG 名称]/[LV 名称](如 /dev/vg_data/lv_data),后续格式化和挂载均使用此路径。
5. 第五步:格式化 LV(创建文件系统)
LV 本质是 “虚拟分区”,需像传统分区一样格式化(指定文件系统,如 ext4、xfs)才能使用:
# 格式化为 ext4 文件系统(适用于大多数 Linux 场景,-F 强制覆盖,避免交互提示)
sudo mkfs.ext4 -F /dev/vg_data/lv_data
# (可选)若需使用 xfs 文件系统(CentOS/RHEL 常用,支持更大容量)
# sudo mkfs.xfs -f /dev/vg_data/lv_data
验证格式化:执行 lsblk -f /dev/vg_data/lv_data,“FSTYPE” 列显示对应的文件系统(如 ext4),说明格式化成功。
6. 第六步:挂载 LV(接入系统目录)
将格式化后的 LV 挂载到指定目录(如 /data),并配置开机自动挂载(避免重启后失效):
# 1. 创建挂载点目录(若不存在)
sudo mkdir -p /data
# 2. 临时挂载(重启后失效,用于测试)
sudo mount /dev/vg_data/lv_data /data
# 3. 验证挂载:查看挂载状态,确认 LV 已挂载到 /data
df -h /data # 显示 /data 的容量、已用空间等信息
lsblk -f /dev/vg_data/lv_data # 查看挂载点(MOUNTPOINT 列显示 /data)
# 4. 配置开机自动挂载(编辑 /etc/fstab 文件)
# 先获取 LV 的 UUID(避免设备路径变化导致挂载失败)
sudo blkid /dev/vg_data/lv_data # 输出类似:/dev/vg_data/lv_data: UUID="xxx" TYPE="ext4"
# 将 UUID 写入 /etc/fstab(替换 xxx 为实际 UUID,ext4 替换为实际文件系统)
echo 'UUID=xxx /data ext4 defaults 0 0' | sudo tee -a /etc/fstab
# 5. 验证开机挂载配置(测试是否能正常挂载,无报错则成功)
sudo mount -a
至此,LV 已完全可用,可像使用普通目录一样在 /data 中存储数据,后续扩容 / 缩容无需卸载(部分文件系统需在线操作)。
二、LVM 进阶操作:动态调整存储(扩容 / 缩容 / 更换硬盘)
LVM 的核心优势是 “动态管理”,以下是日常运维中最常用的操作:扩容 / 缩容 VG、扩容 / 缩容 LV,以及更换故障物理硬盘。
1. 卷组(VG)的调整:添加 / 移除 PV
VG 作为 “存储池”,可随时添加新 PV(扩容存储池)或移除空闲 PV(释放物理硬盘)。
(1)扩容 VG(添加新 PV)
当 VG 空间不足时,可将新的物理分区(如 /dev/sdd1)初始化为 PV 并加入 VG:
# 1. 先将新分区初始化为 PV(若未初始化)
sudo pvcreate /dev/sdd1
# 2. 将 PV 加入已有的 VG(vg_data)
sudo vgextend vg_data /dev/sdd1
# 3. 验证 VG 扩容结果(查看 Free PE 是否增加)
sudo vgdisplay vg_data
(2)缩容 VG(移除空闲 PV)
若需移除 VG 中的某个 PV(如更换硬盘),需先确保该 PV 上的空间已 “迁移” 到其他 PV(无数据占用):
# 1. 查看 VG 中各 PV 的使用情况(确认目标 PV 无数据,Free PE 等于 PV 总容量)
sudo pvdisplay /dev/sdc1 # 假设要移除 /dev/sdc1
# 2. (可选)若目标 PV 有数据,先迁移数据到其他 PV(pvmove 命令)
sudo pvmove /dev/sdc1 # 自动将 /dev/sdc1 的数据迁移到 VG 中其他空闲 PV
# 3. 从 VG 中移除 PV
sudo vgreduce vg_data /dev/sdc1
# 4. (可选)若不再使用该 PV,可删除其 LVM 标记(恢复为普通分区)
sudo pvremove /dev/sdc1
# 5. 验证 VG 缩容结果
sudo vgdisplay vg_data
2. 逻辑卷(LV)的调整:扩容 / 缩容
LV 的调整需分两步:调整 LV 本身的容量 → 调整 LV 上的文件系统容量(两者必须匹配,否则会导致数据损坏)。
(1)扩容 LV(最常用,在线操作,无需卸载)
以 ext4 文件系统为例,将 /dev/vg_data/lv_data 从 10GB 扩容到 20GB:
# 1. 先确认 VG 有足够空闲空间(Free PE 需满足扩容需求)
sudo vgdisplay vg_data
# 2. 扩容 LV:增加 10GB 空间(-L +10G 表示增加 10GB,也可直接指定最终大小 -L 20G)
sudo lvextend -L +10G /dev/vg_data/lv_data
# 3. 扩容文件系统(ext4 使用 resize2fs,xfs 使用 xfs_growfs,必须与文件系统匹配)
sudo resize2fs /dev/vg_data/lv_data
# 4. 验证扩容结果(查看 LV 容量和文件系统容量是否一致)
sudo lvdisplay /dev/vg_data/lv_data # LV 容量应为 20GB
df -h /data # 文件系统容量也应为 20GB
- 关键注意:xfs 文件系统只支持扩容,不支持缩容,若使用 xfs,需谨慎规划容量。
(2)缩容 LV(需离线操作,先卸载,风险较高)
缩容可能导致数据损坏,必须先备份数据,且仅支持 ext4 等支持缩容的文件系统。以将 /dev/vg_data/lv_data 从 20GB 缩容到 15GB 为例:
# 1. 先卸载 LV(必须离线操作,确保无进程使用该目录)
sudo umount /data
# 2. 检查文件系统完整性(避免缩容时损坏数据,ext4 使用 e2fsck)
sudo e2fsck -f /dev/vg_data/lv_data # -f 强制检查,即使文件系统看起来正常
# 3. 缩容文件系统(先缩文件系统,再缩 LV,顺序不能反!)
sudo resize2fs /dev/vg_data/lv_data 15G # 指定缩容后的文件系统大小
# 4. 缩容 LV(指定缩容后的 LV 大小,需与文件系统大小一致)
sudo lvreduce -L 15G /dev/vg_data/lv_data
# 5. 重新挂载 LV
sudo mount /dev/vg_data/lv_data /data
# 6. 验证缩容结果
df -h /data # 文件系统容量应为 15GB
sudo lvdisplay /dev/vg_data/lv_data # LV 容量也应为 15GB
3. 故障处理:更换损坏的 PV
若 VG 中的某个 PV(物理硬盘)损坏,可通过以下步骤更换(前提是 VG 有其他 PV,数据未完全丢失):
# 1. 标记损坏的 PV 为“故障”(假设 /dev/sdb1 损坏)
sudo pvchange -x n /dev/sdb1 # -x n 表示禁止写入该 PV
# 2. 迁移损坏 PV 上的可用数据(若仍有可读取的数据)
sudo pvmove --replace /dev/sdb1 # 将 /dev/sdb1 的数据迁移到其他 PV
# 3. 从 VG 中移除损坏的 PV
sudo vgreduce --removemissing vg_data # 自动移除 VG 中“丢失”的 PV
# 4. 添加新的 PV 到 VG(替换损坏的硬盘)
sudo pvcreate /dev/sde1 # 新硬盘分区
sudo vgextend vg_data /dev/sde1
# 5. 验证 VG 状态(确认无故障 PV,空闲空间恢复)
sudo vgdisplay vg_data
三、LVM 常用命令汇总
为方便日常使用,整理 LVM 各层级的核心命令,按 “PV → VG → LV” 分类:
操作目标 | 命令 | 功能说明 |
---|---|---|
物理卷(PV) | pvcreate /dev/sdb1 | 初始化分区为 PV |
pvdisplay /dev/sdb1 | 查看 PV 详细信息 | |
pvs | 查看所有 PV 简洁列表 | |
pvmove /dev/sdb1 | 迁移 PV 上的数据到其他 PV | |
pvremove /dev/sdb1 | 删除 PV 的 LVM 标记(恢复为普通分区) | |
卷组(VG) | vgcreate vg_data /dev/sdb1 | 创建 VG 并加入 PV |
vgdisplay vg_data | 查看 VG 详细信息 | |
vgs | 查看所有 VG 简洁列表 | |
vgextend vg_data /dev/sdc1 | 向 VG 中添加新 PV(扩容 VG) | |
vgreduce vg_data /dev/sdc1 | 从 VG 中移除空闲 PV(缩容 VG) | |
逻辑卷(LV) | lvcreate -L 10G -n lv_data vg_data | 从 VG 中创建 LV |
lvdisplay /dev/vg_data/lv_data | 查看 LV 详细信息 | |
lvs | 查看所有 LV 简洁列表 | |
lvextend -L +10G /dev/vg_data/lv_data | 扩容 LV | |
lvreduce -L 15G /dev/vg_data/lv_data | 缩容 LV | |
文件系统 | resize2fs /dev/vg_data/lv_data | 扩容 / 缩容 ext4 文件系统 |
xfs_growfs /data | 扩容 xfs 文件系统(需指定挂载点) |
四、注意事项与最佳实践
- 数据备份优先:缩容、移除 PV、更换故障硬盘前,务必备份 LV 中的重要数据,避免操作失误导致数据丢失;
- 文件系统适配:xfs 只支持扩容,不支持缩容,若需灵活缩容,建议选择 ext4;
- VG 命名规范:按用途命名 VG(如 vg_system 用于系统分区,vg_data 用于数据存储),避免后续混淆;
- PV 选择建议:优先使用磁盘分区(如 /dev/sdb1)作为 PV,而非整个硬盘(/dev/sdb),便于后续管理其他分区;
- 监控 LVM 状态:定期使用 vgs、lvs 查看 VG 空闲空间和 LV 使用情况,提前规划扩容,避免空间耗尽。
五、总结
LVM 是 Linux 系统中磁盘管理的 “瑞士军刀”,通过 “物理卷 → 卷组 → 逻辑卷” 的三层结构,打破了传统分区的空间限制,实现了磁盘空间的动态、灵活管理。无论是个人服务器的存储扩展,还是企业级环境的硬盘更换,LVM 都能大幅简化操作流程,降低运维成本。
掌握本文中的 “基础搭建流程” 和 “进阶调整操作”,即可应对 90% 以上的 LVM 使用场景。后续可结合实际需求(如创建快照、配置条带化 LV 提升性能)深入学习 LVM 高级功能,进一步发挥其优势。