Linux逻辑卷管理:从“固定隔间”到“弹性存储池”的智慧

Linux逻辑卷管理:从"固定隔间"到"弹性存储池"的智慧

\^------云计算一阶段第22天 板块二:

引言:传统硬盘分区的"三宗罪"

想象一下传统硬盘分区就像一套固定大小的公寓隔间:

痛点1:空间僵化------"无法移动的墙壁"

bash 复制代码
# 传统分区:一旦划分,大小固定
/dev/sda1: 20G  # 就像20平米的房间,无法扩展
/dev/sda2: 30G  # 隔壁房间,中间是承重墙

# 问题:当sda1空间不足时,即使sda2有空余,也无法借用
# 要扩展sda1,必须重新划分整个硬盘,意味着数据搬迁

痛点2:容量限制------"无法突破的屋顶"

bash 复制代码
# 单个硬盘容量限制
/dev/sda: 2TB  # 最大容量受物理硬盘限制
# 要创建3TB的分区?不可能!
# 除非使用RAID,但配置复杂且不够灵活

痛点3:风险集中------"鸡蛋在一个篮子里"

bash 复制代码
# 硬盘故障意味着数据全失
/dev/sda1损坏 → /home目录数据全部丢失
# 没有冗余保护,没有快速恢复机制

LVM登场:存储管理的"革命性方案"

LVM核心思想:从"固定隔间"到"弹性存储池"

三大核心组件

bash 复制代码
物理卷(PV) → 存储设备(砖块)
卷组(VG) → 存储池(把所有砖块放进一个大池子)
逻辑卷(LV) → 逻辑分区(从池子里按需划分空间)

可视化比喻

bash 复制代码
传统分区:            LVM:
┌──────────┐          ┌──────────────────┐
│ /dev/sda1│ 20G      │  存储池(VG)     │
├──────────┤          │ ┌────┐ ┌────┐    │
│ /dev/sda2│ 30G      │ │PV1 │ │PV2 │    │→ 从中划分
├──────────┤          │ │20G │ │20G │    │   ┌────────┐
│ /dev/sda3│ 50G      │ └────┘ └────┘    │   │ LV1 10G│
└──────────┘          │     总容量40G     │   │ LV2 25G│
                      └──────────────────┘   └────────┘

LVM核心优势

四大杀手锏

  1. 动态扩展:空间不足时随时扩展,无需停机
  2. 跨磁盘管理:创建超过单个硬盘容量的逻辑卷
  3. 数据保护:支持RAID和快照,提升可靠性和可恢复性
  4. 在线迁移:数据可以在物理磁盘间移动,方便维护

环境准备:搭建LVM的"实验场"

实验环境说明

bash 复制代码
# 添加3块20G硬盘
[root@server ~ 19:01:35]# lsblk /dev/sd{b..d}
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb    8:16   0  20G  0 disk   # 第一块实验盘
sdc    8:32   0  20G  0 disk   # 第二块实验盘  
sdd    8:48   0  20G  0 disk   # 第三块实验盘

# 检查确认
[root@server ~ 19:01:46]# fdisk -l /dev/sd{b..d} |grep Disk
Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Disk /dev/sdc: 21.5 GB, 21474836480 bytes, 41943040 sectors
Disk /dev/sdd: 21.5 GB, 21474836480 bytes, 41943040 sectors

LVM基础操作:从零创建"弹性存储"

创建物理卷(PV):准备"建筑砖块"

物理卷概念:将物理存储设备(硬盘、分区等)初始化为LVM可管理的单元。

bash 复制代码
# 单块硬盘创建PV
[root@server ~ 19:04:53]# pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.
# 就像给一块砖块贴上"可用"标签

# 批量创建PV
[root@server ~ 19:05:43]# pvcreate /dev/sd{c,d}
  Physical volume "/dev/sdc" successfully created.
  Physical volume "/dev/sdd" successfully created.

# 查看PV状态
[root@server ~ 19:06:05]# pvs
  PV         VG     Fmt  Attr PSize    PFree 
  /dev/sda2  centos lvm2 a--  <199.00g  4.00m
  /dev/sdb          lvm2 ---    20.00g 20.00g
  /dev/sdc          lvm2 ---    20.00g 20.00g
  /dev/sdd          lvm2 ---    20.00g 20.00g

# 查看PV详情
[root@server ~ 23:09:07]# pvdisplay /dev/sdb
  "/dev/sdb" is a new physical volume of "20.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb    # 设备名称
  VG Name                          # 所属卷组(尚未分配)
  PV Size               20.00 GiB   # 总容量
  Allocatable           NO          # 是否可分配
  PE Size               0 MiB       # 物理扩展块大小
  Total PE              0           # 总PE数量
  Free PE               0           # 空闲PE数量
  Allocated PE          0           # 已分配PE数量
  PV UUID               8Lc8v6-NMES-y3VV-kQvB-lMD4-MCln-e2Bpe6

物理扩展块(PE)详解

bash 复制代码
PE是LVM的最小存储单元,就像建筑中的标准砖块:
- 默认大小:4MB(可配置)
- 作用:所有物理卷被划分为相同大小的PE
- 优势:实现不同物理设备的统一管理

创建卷组(VG):组建"存储池"

卷组概念:将多个物理卷组合成一个大的存储资源池。

bash 复制代码
# 创建单物理卷的卷组
[root@server ~ 23:09:17]# vgcreate webapp /dev/sdb
  Volume group "webapp" successfully created
# 创建名为webapp的存储池,初始包含/dev/sdb

# 创建多物理卷的卷组
[root@server ~ 23:11:18]# vgcreate dbapp /dev/sd{c,d}
  Volume group "dbapp" successfully created
# 创建名为dbapp的存储池,包含/dev/sdc和/dev/sdd

# 查看卷组状态
[root@server ~ 23:12:33]# vgs
  VG     #PV #LV #SN Attr   VSize    VFree  
  centos   1   3   0 wz--n- <199.00g   4.00m  
  dbapp    2   0   0 wz--n-   39.99g  39.99g  # 2个PV,39.99G总容量
  webapp   1   0   0 wz--n-  <20.00g <20.00g  # 1个PV,约20G容量

# 查看卷组详情
[root@server ~ 23:12:48]# vgdisplay dbapp
  --- Volume group ---
  VG Name               dbapp            # 卷组名
  System ID             
  Format                lvm2             # LVM版本
  Metadata Areas        2                # 包含的PV数量
  Metadata Sequence No  1                # 元数据序列号
  VG Access             read/write       # 访问权限
  VG Status             resizable        # 可调整大小
  MAX LV                0                # 最大逻辑卷数(0=无限制)
  Cur LV                0                # 当前逻辑卷数
  Open LV               0                # 打开的逻辑卷数
  Max PV                0                # 最大PV数(0=无限制)
  Cur PV                2                # 当前PV数
  Act PV                2                # 活跃PV数
  VG Size               39.99 GiB        # 总容量
  PE Size               4.00 MiB         # PE大小(默认4MB)
  Total PE              10238            # 总PE数(39.99G/4MB)
  Alloc PE / Size       0 / 0            # 已分配PE数/大小
  Free  PE / Size       10238 / 39.99 GiB # 空闲PE数/大小
  VG UUID               HGoV7a-GIgn-JUlM-4WGj-eQUV-cwpn-GIqQNK

卷组创建选项

复制代码
# 指定PE大小(创建时指定)
vgcreate -s 8M dbapp /dev/sd{c,d}  # 设置PE为8MB

# 卷组重命名
vgrename dbapp database

# 设置卷组属性
vgchange -a n dbapp  # 停用卷组
vgchange -a y dbapp  # 激活卷组

创建逻辑卷(LV):从池中"划分空间"

逻辑卷概念:从卷组中划分出的逻辑存储单元,可以像普通分区一样使用。

bash 复制代码
# 创建逻辑卷(指定名称和大小)
[root@server ~ 23:23:56]# lvcreate -n webapp01 -L 5G webapp
  Logical volume "webapp01" created.
# -n: 指定逻辑卷名称
# -L: 指定逻辑卷大小(绝对大小)
# webapp: 从哪个卷组划分

# 创建跨物理卷的逻辑卷(自动分布)
[root@server ~ 23:24:38]# lvcreate -n data01 -L 25G dbapp
  Logical volume "data01" created.
# 这个25G的逻辑卷会自动分布在/dev/sdc和/dev/sdd上

# 查看逻辑卷状态
[root@server ~ 23:24:55]# lvs
  LV     VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  data01   dbapp  -wi-a-----  25.00g                                               
  webapp01 webapp -wi-a-----   5.00g

# 查看逻辑卷详情
[root@server ~ 23:25:28]# lvdisplay /dev/dbapp/data01
  --- Logical volume ---
  LV Path                /dev/dbapp/data01      # 逻辑卷路径
  LV Name                data01                 # 逻辑卷名称
  VG Name                dbapp                  # 所属卷组
  LV UUID                W8UafB-A7RJ-dBjM-bsA2-8Obc-p8gE-bMZgmm
  LV Write Access        read/write             # 读写权限
  LV Creation host, time server.whisky.cloud, 2026-01-07 23:24:55 +0800
  LV Status              available              # 状态:可用
  # open                 0                      # 打开次数
  LV Size                25.00 GiB              # 逻辑卷大小
  Current LE             6400                   # 逻辑扩展块数量
  Segments               2                      # 分布段数(跨2个PV)
  Allocation             inherit                # 分配策略
  Read ahead sectors     auto                   # 预读扇区
  - currently set to     8192
  Block device           253:4                  # 对应的设备号

逻辑卷路径的三种形式

bash 复制代码
# 1. 卷组名/逻辑卷名(符号链接)
ls -l /dev/dbapp/data01
# /dev/dbapp/data01 -> ../dm-4

# 2. /dev/mapper/卷组名-逻辑卷名(符号链接)
ls -l /dev/mapper/dbapp-data01
# /dev/mapper/dbapp-data01 -> ../dm-4

# 3. /dev/dm-N(实际设备节点)
# 由设备映射器(Device Mapper)创建

查看存储分布

bash 复制代码
[root@server ~ 23:25:46]# pvs  # 查看物理卷使用情况
  PV         VG     Fmt  Attr PSize    PFree  
  /dev/sda2  centos lvm2 a--  <199.00g   4.00m
  /dev/sdb       webapp lvm2 a--   <20.00g <15.00g  # 使用了5G
  /dev/sdc       dbapp  lvm2 a--   <20.00g      0   # 20G全部使用
  /dev/sdd       dbapp  lvm2 a--   <20.00g  14.99g  # 使用了约5G

[root@server ~ 23:27:14]# lsblk /dev/sd{b..d}  # 树状图显示
NAME              MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb                 8:16   0  20G  0 disk 
└─webapp-webapp01 253:3    0   5G  0 lvm     # webapp01在sdb上
sdc                 8:32   0  20G  0 disk 
└─dbapp-data01    253:4    0  25G  0 lvm     # data01一部分在sdc
sdd                 8:48   0  20G  0 disk 
└─dbapp-data01    253:4    0  25G  0 lvm     # data01另一部分在sdd

创建逻辑卷的其他方式

bash 复制代码
# 使用百分比创建
lvcreate -n lv1 -l 50%VG dbapp  # 使用卷组50%的空间

# 使用PE数量创建
lvcreate -n lv2 -l 1000 dbapp  # 使用1000个PE(4MB×1000=4G)

# 指定在哪个PV上创建
lvcreate -n lv3 -L 10G dbapp /dev/sdc  # 只在sdc上创建

# 创建精简配置逻辑卷(按需分配空间)
lvcreate -n thin_lv -V 100G --thin dbapp/thin_pool

创建文件系统:让逻辑卷"投入使用"

bash 复制代码
# 1. 创建文件系统
[root@server ~ 23:27:52]# mkfs.xfs /dev/webapp/webapp01
meta-data=/dev/webapp/webapp01   isize=512    agcount=4, agsize=327680 blks
...

# 2. 创建挂载点
[root@server ~ 23:31:25]# mkdir -p /var/www/html

# 3. 挂载使用
[root@server ~ 23:31:38]# mount /dev/webapp/webapp01 /var/www/html

# 4. 验证
[root@server ~ 23:32:22]# df -h /var/www/html
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/webapp-webapp01  5.0G   33M  5.0G   1% /var/www/html

# 5. 持久化挂载(添加至/etc/fstab)
echo "/dev/webapp/webapp01 /var/www/html xfs defaults 0 0" >> /etc/fstab
# 或使用UUID(推荐,更稳定)
echo "UUID=$(blkid -s UUID -o value /dev/webapp/webapp01) /var/www/html xfs defaults 0 0" >> /etc/fstab

清理

为确保后续实验能顺利进行,做完后需要及时卸载并删除不需要的逻辑卷(LV)、卷组(VG)和物理卷(PV).

bash 复制代码
# 卸载文件系统
[root@server ~ 23:36:29]# umount /dev/webapp/webapp01

# 删除LV
[root@server ~ 23:42:21]# lvremove /dev/webapp/webapp01 /dev/dbapp/data01
Do you really want to remove active logical volume webapp/webapp01? [y/n]: Y
  Logical volume "webapp01" successfully removed
Do you really want to remove active logical volume dbapp/data01? [y/n]: Y
  Logical volume "data01" successfully removed

# 删除VG
[root@server ~ 23:42:39]# vgremove webapp dbapp
  Volume group "webapp" successfully removed
  Volume group "dbapp" successfully removed
  
# 删除PV
[root@server ~ 23:43:12]# pvremove /dev/sd{b..d}
  Labels on physical volume "/dev/sdb" successfully wiped.
  Labels on physical volume "/dev/sdc" successfully wiped.
  Labels on physical volume "/dev/sdd" successfully wiped.

动态调整:LVM的"魔法"所在

环境准备

bash 复制代码
# 创建测试环境
[root@server ~ 23:43:34]# vgcreate webapp /dev/sdb
  Physical volume "/dev/sdb" successfully created.
  Volume group "webapp" successfully created
[root@server ~ 23:48:57]# lvcreate -n webapp01 -L 10G webapp
WARNING: xfs signature detected on /dev/webapp/webapp01 at offset 0. Wipe it? [y/n]: y
  Wiping xfs signature on /dev/webapp/webapp01.
  Logical volume "webapp01" created.

扩展卷组:增加"存储池"容量

场景:当卷组空间不足时,可以添加新的物理卷来扩展容量。

bash 复制代码
# 扩展卷组(添加新物理卷)
[root@server ~ 23:49:15]# vgextend webapp /dev/sd{c,d}
  Physical volume "/dev/sdc" successfully created.
  Physical volume "/dev/sdd" successfully created.
  Volume group "webapp" successfully extended
# 注意:如果设备不是PV,vgextend会自动执行pvcreate

# 验证扩展结果
[root@server ~ 23:49:45]# vgs webapp
  VG     #PV #LV #SN Attr   VSize   VFree  
  webapp   3   1   0 wz--n- <59.99g <49.99g  # 从20G扩展到约60G

# 另一种扩展方式:先创建PV再扩展
pvcreate /dev/sde
vgextend webapp /dev/sde

缩减卷组:移除"闲置砖块"

场景:当需要更换硬盘或回收闲置存储资源时。

bash 复制代码
# 查看当前PV使用情况
[root@server ~ 23:50:10]# pvs
  PV         VG     Fmt  Attr PSize    PFree  
  /dev/sda2  centos lvm2 a--  <199.00g   4.00m  
  /dev/sdb   webapp   lvm2 a--  <20.00g <10.00g  # 正在使用(有10G空闲)
  /dev/sdc   webapp   lvm2 a--  <20.00g <20.00g  # 完全空闲
  /dev/sdd   webapp   lvm2 a--  <20.00g <20.00g  # 完全空闲

# 尝试移除正在使用的PV(会失败)
[root@server ~ 23:58:13]# vgreduce webapp /dev/sdb
  Physical volume "/dev/sdb" still in use

# 解决方案:迁移数据到其他PV
[root@server ~ 23:58:46]# pvmove /dev/sdb
  /dev/sdb: Moved: 0.23%
  /dev/sdb: Moved: 100.00%
  # 迁移sdb上的所有数据
# 或指定目标PV
[root@centos7 ~]# pvmove /dev/sdb /dev/sdd  # 迁移到sdd

# 查看迁移进度(另一个终端)
watch pvs

# 迁移完成后移除PV
[root@server ~ 23:59:52]# vgreduce webapp /dev/sdb
  Removed "/dev/sdb" from volume group "webapp"

# 验证结果
[root@server ~ 00:00:33]# pvs
  PV         VG     Fmt  Attr PSize    PFree  
  /dev/sda2  centos lvm2 a--  <199.00g   4.00m  
  /dev/sdb          lvm2 ---   20.00g  20.00g  # 已从卷组移除
  /dev/sdc   webapp   lvm2 a--  <20.00g <20.00g
  /dev/sdd   webapp   lvm2 a--  <20.00g <10.00g  # 现在数据在sdd上

pvmove高级用法

bash 复制代码
# 迁移特定逻辑卷
pvmove -n webapp01 /dev/sdb  # 只迁移webapp01逻辑卷

# 迁移特定PE范围
pvmove --alloc anywhere /dev/sdb:0-100  # 迁移PE 0-100

# 后台迁移(大容量时使用)
pvmove -b /dev/sdb

# 查看迁移状态
pvmove -i 5  # 每5秒显示一次进度

扩展逻辑卷:增加"房间面积"

场景:应用程序数据增长,需要更多存储空间。

bash 复制代码
# 扩展逻辑卷(增加2G)
[root@centos7 ~]# lvextend -L +2G /dev/webapp/webapp01
  Size of logical volume webapp/webapp01 changed from 10.00 GiB (2560 extents) to 12.00 GiB (3072 extents).
  Logical volume webapp/webapp01 successfully resized.

# 验证扩展
[root@centos7 ~]# lvs /dev/webapp/webapp01
  LV       VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  webapp01 webapp -wi-a----- 12.00g

# 扩展逻辑卷的其他方式
lvextend -L 15G /dev/webapp/webapp01     # 扩展到15G(绝对大小)
lvextend -l +100%FREE /dev/webapp/webapp01  # 使用全部剩余空间
lvextend -l +500 /dev/webapp/webapp01    # 增加500个PE(约2G)

缩减逻辑卷:回收"闲置面积"

场景:逻辑卷分配过大,需要回收空间给其他逻辑卷使用。

bash 复制代码
# 缩减逻辑卷(减少2G)
[root@centos7 ~]# lvreduce -L -2G /dev/webapp/webapp01
  WARNING: Reducing active logical volume to 10.00 GiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce webapp/webapp01? [y/n]: y
  Size of logical volume webapp/webapp01 changed from 12.00 GiB (3072 extents) to 10.00 GiB (2560 extents).
  Logical volume webapp/webapp01 successfully resized.

# 注意:缩减前必须确保文件系统已缩减,否则会丢失数据!

# 安全缩减流程
# 1. 备份数据
# 2. 卸载文件系统
# 3. 检查文件系统
# 4. 缩减文件系统
# 5. 缩减逻辑卷
# 6. 重新挂载

文件系统调整:让"房间"与"面积"匹配

XFS文件系统:只扩不缩的"单向阀"

特点:XFS支持在线扩展,但不支持缩减。

环境准备

bash 复制代码
[root@centos7 ~]# mkfs.xfs /dev/webapp/webapp01
[root@centos7 ~]# mkdir /var/www/html
[root@centos7 ~]# mount /dev/webapp/webapp01 /var/www/html
[root@centos7 ~]# cp /etc/host* /var/www/html
[root@centos7 ~]# ls /var/www/html
host.conf  hostname  hosts  hosts.allow  hosts.deny
扩展XFS文件系统
bash 复制代码
# 方法1:分步操作
# 步骤1:扩展逻辑卷
[root@centos7 ~]# lvextend -L 15G /dev/webapp/webapp01
[root@centos7 ~]# lvs /dev/webapp/webapp01
  LV       VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  webapp01 webapp -wi-ao---- 15.00g

# 步骤2:扩展文件系统(在线扩展,无需卸载)
[root@centos7 ~]# xfs_growfs /var/www/html
meta-data=/dev/mapper/webapp-webapp01 isize=512    agcount=4, agsize=327680 blks
...
data blocks changed from 2621440 to 3932160

# 验证扩展结果
[root@centos7 ~]# df -h /var/www/html
文件系统                     容量  已用  可用 已用% 挂载点
/dev/mapper/webapp-webapp01   15G  140M   15G    1% /var/www/html

# 方法2:一步到位(带-r参数自动扩展文件系统)
[root@centos7 ~]# lvextend -rL 20G /dev/webapp/webapp01
  Size of logical volume webapp/webapp01 changed from 15.00 GiB (3840 extents) to 20.00 GiB (5120 extents).
  Logical volume webapp/webapp01 successfully resized.
  meta-data=/dev/mapper/webapp-webapp01 isize=512    agcount=5, agsize=327680 blks
  ...
  data blocks changed from 3932160 to 5242880

# 验证结果
[root@centos7 ~]# lvs /dev/webapp/webapp01
  LV       VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  webapp01 webapp -wi-ao---- 20.00g                                                    
[root@centos7 ~]# df -h /var/www/html
文件系统                     容量  已用  可用 已用% 挂载点
/dev/mapper/webapp-webapp01   20G  176M   20G    1% /var/www/html
XFS文件系统扩展注意事项
  1. 必须在线扩展:无需卸载文件系统
  2. 不能缩减:XFS设计不支持缩减,需要缩减时只能备份→重建→恢复
  3. 扩展粒度:XFS以分配组(AG)为单位扩展,扩展大小必须是AG大小的整数倍

EXT4文件系统:能扩能缩的"双向门"

特点:EXT4支持扩展和缩减,但缩减需要卸载文件系统。

环境准备

bash 复制代码
[root@centos7 ~]# umount /var/www/html
[root@centos7 ~]# mkfs.ext4 /dev/webapp/webapp01
[root@centos7 ~]# mount /dev/webapp/webapp01 /var/www/html
[root@centos7 ~]# cp /etc/host* /var/www/html
[root@centos7 ~]# df -h /var/www/html
文件系统                     容量  已用  可用 已用% 挂载点
/dev/mapper/webapp-webapp01   20G   24K   19G    1% /var/www/html
扩展EXT4文件系统
bash 复制代码
# 方法1:分步操作
# 步骤1:扩展逻辑卷
[root@centos7 ~]# lvextend -L 25G /dev/webapp/webapp01
[root@centos7 ~]# lvs /dev/webapp/webapp01
  LV       VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  webapp01 webapp -wi-ao---- 25.00g 

# 步骤2:扩展文件系统(可在线操作)
[root@centos7 ~]# resize2fs /dev/webapp/webapp01
resize2fs 1.45.6 (20-Mar-2020)
Filesystem at /dev/webapp/webapp01 is mounted on /var/www/html; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 4
The filesystem on /dev/webapp/webapp01 is now 6553600 (4k) blocks long.

# 验证扩展结果
[root@centos7 ~]# df -h /var/www/html
文件系统                     容量  已用  可用 已用% 挂载点
/dev/mapper/webapp-webapp01   25G   36K   24G    1% /var/www/html

# 方法2:一步到位
[root@centos7 ~]# lvextend -rL 30G /dev/webapp/webapp01
[root@centos7 ~]# df -h /var/www/html
文件系统                     容量  已用  可用 已用% 挂载点
/dev/mapper/webapp-webapp01   30G   36K   28G    1% /var/www/html
缩减EXT4文件系统

重要警告:缩减有风险,操作前务必备份!

bash 复制代码
# EXT4缩减流程(五步法)
# 第1步:卸载文件系统
[root@centos7 ~]# umount /var/www/html 

# 第2步:强制检查文件系统
[root@centos7 ~]# e2fsck -f /dev/webapp/webapp01
e2fsck 1.42.9 (28-Dec-2013)
第一步: 检查inode,块,和大小
第二步: 检查目录结构
第3步: 检查目录连接性
Pass 4: Checking reference counts
第5步: 检查簇概要信息
/dev/webapp/webapp01:14/1966080 文件(0.0% 为非连续的), 167445/7864320 块

# 第3步:缩减文件系统(到10G)
[root@centos7 ~]# resize2fs /dev/webapp/webapp01 10G
resize2fs 1.45.6 (20-Mar-2020)
将 /dev/webapp/webapp01 上的文件系统调整为 2621440 个块(每块 4k)。
/dev/webapp/webapp01 上的文件系统现在为 2621440 个块(每块 4k)。

# 第4步:缩减逻辑卷(匹配文件系统大小)
[root@centos7 ~]# lvreduce -L 10G /dev/webapp/webapp01
  WARNING: Reducing active logical volume to 10.00 GiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce webapp/webapp01? [y/n]: y
  Size of logical volume webapp/webapp01 changed from 30.00 GiB (7680 extents) to 10.00 GiB (2560 extents).
  Logical volume webapp/webapp01 successfully resized.

# 第5步:重新挂载并验证
[root@centos7 ~]# mount /dev/webapp/webapp01 /var/www/html
[root@centos7 ~]# df -h /var/www/html
文件系统                     容量  已用  可用 已用% 挂载点
/dev/mapper/webapp-webapp01  9.7G   36K  9.3G    1% /var/www/html
[root@centos7 ~]# ls /var/www/html
host.conf  hostname  hosts  lost+found  # 数据完好
EXT4文件系统调整注意事项
  1. 缩减前必须卸载:无法在线缩减
  2. 必须按顺序操作:先缩减文件系统,再缩减逻辑卷
  3. 预留安全空间:建议文件系统不要完全占满逻辑卷
  4. 检查是必须的:e2fsck -f 确保文件系统健康

高级功能:LVM的"进阶技巧"

逻辑卷快照:数据的"时光机"

快照原理:创建逻辑卷在某个时间点的只读副本,使用写时复制(Copy-On-Write)技术。

bash 复制代码
# 创建快照(记录webapp01当前状态)
[root@centos7 ~]# lvcreate -s -n webapp01-snap1 -L 10G /dev/webapp/webapp01
  Logical volume "webapp01-snap1" created.
# -s: 创建快照
# -n: 快照名称
# -L: 快照空间大小(建议不小于原逻辑卷大小)

# 挂载快照查看数据
[root@centos7 ~]# mkdir /webapp/webapp01
[root@centos7 ~]# mount /dev/webapp/webapp01-snap1 /webapp/webapp01/
[root@centos7 ~]# ls /webapp/webapp01/
host.conf  hostname  hosts  hosts.allow  hosts.deny  # 原始数据

# 在原卷上创建新数据
[root@centos7 ~]# echo "hello world" > /var/www/html/hello.txt

# 快照卷保持不变(还是原始数据)
[root@centos7 ~]# ls /webapp/webapp01/
host.conf  hostname  hosts  hosts.allow  hosts.deny  # 没有hello.txt

# 使用快照恢复数据
[root@centos7 ~]# umount /var/www/html
[root@centos7 ~]# lvconvert --merge /dev/webapp/webapp01-snap1
  Merging of volume webapp/webapp01-snap1 started.
  webapp/webapp01: Merged: 100.00%
[root@centos7 ~]# mount /dev/webapp/webapp01 /var/www/html
[root@centos7 ~]# ls /var/www/html/
host.conf  hostname  hosts  hosts.allow  hosts.deny  # hello.txt消失了

# 快照管理
lvremove /dev/webapp/webapp01-snap1  # 删除快照
lvs -a  # 查看所有逻辑卷(包括快照)

快照使用场景

  1. 数据备份:在不停止服务的情况下备份数据
  2. 测试验证:在生产数据上测试应用,不影响原数据
  3. 版本恢复:恢复到某个时间点的数据状态
  4. 快速克隆:基于快卷创建新的逻辑卷

RAID逻辑卷:数据的"保险柜"

环境准备

bash 复制代码
# 清理环境
[root@centos7 ~]# umount /webapp/webapp01
[root@centos7 ~]# umount /var/www/html
[root@centos7 ~]# lvremove /dev/webapp/webapp01*
创建RAID1逻辑卷(镜像)
bash 复制代码
# 创建RAID1逻辑卷
[root@centos7 ~]# lvcreate --type raid1 -n webapp01 -L 15G webapp
  Logical volume "webapp01" created.

# 创建文件系统并挂载
[root@centos7 ~]# mkfs.xfs /dev/webapp/webapp01
[root@centos7 ~]# mount /dev/webapp/webapp01 /var/www/html/
[root@centos7 ~]# cp /etc/ho* /var/www/html/

# 查看RAID状态
[root@centos7 ~]# lvs -o name,attr,size,segtype,data_percent,metadata_percent
  LV       Attr       LSize  Type   Data%  Meta%  
  webapp01 rwi-a-r--- 15.00g raid1  0.00

# 查看详细RAID信息
[root@centos7 ~]# lvdisplay -m /dev/webapp/webapp01
  --- Logical volume ---
  ...
  --- Segments ---
  Logical extents 0 to 3839:
    Type                raid1
    Raid Data LV 0      webapp01_rimage_0
    Raid Data LV 1      webapp01_rimage_1
    Raid Metadata LV    webapp01_rmeta_0
    Raid Metadata LV    webapp01_rmeta_1
模拟故障与恢复
bash 复制代码
# 模拟磁盘故障(损坏/dev/sdd)
[root@centos7 ~]# dd if=/dev/zero of=/dev/sdd bs=1M count=256
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 0.398988 s, 673 MB/s

# 文件系统仍然可用(RAID1镜像保护)
[root@centos7 ~]# ls /var/www/html/
host.conf  hostname  hosts  hosts.allow  hosts.deny
[root@centos7 ~]# umount /var/www/html
[root@centos7 ~]# mount /dev/webapp/webapp01 /var/www/html/

# 修复RAID逻辑卷
# 步骤1:删除丢失的物理卷
[root@centos7 ~]# vgreduce --removemissing webapp --force

# 步骤2:添加新磁盘(假设已更换)
[root@centos7 ~]# vgextend webapp /dev/sdd

# 步骤3:修复RAID1逻辑卷
[root@centos7 ~]# lvconvert --repair /dev/webapp/webapp01
  WARNING: Not using device /dev/sdd for allocation of hidden LV webapp01_rimage_1.
  WARNING: Using previously failed PV /dev/sdd.
  Attempt to replace failed RAID images (requires full device resync)? [y/n]: y
  Faulty devices in webapp/webapp01 successfully replaced.

# 步骤4:扫描物理卷变化
[root@centos7 ~]# pvscan

# 验证修复结果
[root@centos7 ~]# pvs|grep webap
  /dev/sdb   webapp lvm2 a--  <20.00g   4.99g
  /dev/sdc   webapp lvm2 a--  <20.00g   4.99g
  /dev/sdd   webapp lvm2 a--  <20.00g <20.00g
创建RAID5逻辑卷(带奇偶校验)
bash 复制代码
# 创建RAID5逻辑卷(4个设备,3个数据条带+1个奇偶校验)
[root@centos7 ~]# lvcreate --type raid5 -L 5G -i 3 -I 64 -n mylv webapp
  Logical volume "mylv" created.
# --type raid5: 创建RAID5
# -L 5G: 逻辑卷大小(可用空间)
# -i 3: 条带数(数据磁盘数)
# -I 64: 条带大小(64KB)
# 实际需要4个设备:3个数据+1个奇偶校验

# RAID5容量计算:总容量 = (N-1) × 单个磁盘容量
# 3个20G磁盘做RAID5:可用空间 = (3-1) × 20G = 40G

支持的RAID级别

  • RAID0:条带化,提升性能,无冗余
  • RAID1:镜像,提供冗余,性能较好
  • RAID5:条带化+分布式奇偶校验,平衡性能与冗余
  • RAID6:双分布式奇偶校验,更高冗余
  • RAID10:先镜像再条带,高性能高冗余

企业级LVM管理实践

LVM监控与维护脚本

bash 复制代码
#!/bin/bash
# lvm_monitor.sh - LVM健康监控脚本

# 配置参数
ALERT_THRESHOLD=80  # 空间使用率告警阈值
EMAIL="admin@example.com"
LOG_FILE="/var/log/lvm_monitor.log"

# 监控函数
monitor_lvm() {
    local vg_name=$1
    
    # 检查卷组空间
    local vg_free=$(vgs --noheadings -o vg_free $vg_name | awk '{print $1}')
    local vg_size=$(vgs --noheadings -o vg_size $vg_name | awk '{print $1}')
    
    # 计算使用率
    local usage=$(echo "scale=2; ($vg_size - $vg_free) / $vg_size * 100" | bc)
    
    if (( $(echo "$usage > $ALERT_THRESHOLD" | bc -l) )); then
        log_alert "卷组空间告警" "$vg_name" "$usage%"
    fi
    
    # 检查物理卷健康
    pvs --noheadings | while read pv vg fmt attr psize pfree; do
        if [[ "$attr" =~ "m" ]]; then
            log_alert "物理卷丢失" "$pv" "在卷组 $vg 中"
        fi
    done
    
    # 检查逻辑卷健康
    lvs --noheadings | while read lv vg attr lsize pool origin data meta move log copy sync convert; do
        if [[ "$attr" =~ "p" ]]; then
            log_alert "逻辑卷部分" "$lv" "在卷组 $vg 中"
        fi
    done
}

# 日志记录
log_alert() {
    local type=$1
    local target=$2
    local message=$3
    
    local log_msg="[$(date)] [$type] $target: $message"
    echo "$log_msg" >> "$LOG_FILE"
    
    # 发送邮件告警
    if [[ "$type" == *"告警"* ]]; then
        echo "$log_msg" | mail -s "LVM告警: $type" "$EMAIL"
    fi
}

# 自动扩展逻辑卷
auto_extend_lv() {
    local lv_path=$1
    local extend_size=$2
    
    # 检查挂载点
    local mount_point=$(findmnt -n -o TARGET "$lv_path" 2>/dev/null)
    
    if [ -n "$mount_point" ]; then
        # 在线扩展
        lvextend -r -L "+${extend_size}G" "$lv_path"
        log_alert "自动扩展" "$lv_path" "扩展 ${extend_size}G 成功"
    else
        # 离线扩展
        lvextend -L "+${extend_size}G" "$lv_path"
        # 需要根据文件系统类型扩展
        local fs_type=$(blkid -s TYPE -o value "$lv_path")
        case $fs_type in
            xfs) xfs_growfs "$lv_path" ;;
            ext*) resize2fs "$lv_path" ;;
        esac
        log_alert "自动扩展" "$lv_path" "离线扩展 ${extend_size}G 成功"
    fi
}

# 主监控循环
main() {
    while true; do
        # 监控所有卷组
        vgs --noheadings -o vg_name | while read vg; do
            monitor_lvm "$vg"
        done
        
        # 检查是否需要自动扩展
        # 这里可以添加业务逻辑,如特定目录使用率超过阈值时自动扩展
        
        sleep 300  # 5分钟检查一次
    done
}

# 执行主函数
main

LVM备份与恢复策略

bash 复制代码
#!/bin/bash
# lvm_backup.sh - LVM配置备份脚本

# 备份目录
BACKUP_DIR="/backup/lvm"
DATE=$(date +%Y%m%d_%H%M%S)

# 创建备份目录
mkdir -p "$BACKUP_DIR/$DATE"

# 备份物理卷信息
pvdisplay > "$BACKUP_DIR/$DATE/pvdisplay.txt"
pvs --all > "$BACKUP_DIR/$DATE/pvs_all.txt"

# 备份卷组信息
vgdisplay > "$BACKUP_DIR/$DATE/vgdisplay.txt"
vgs --all > "$BACKUP_DIR/$DATE/vgs_all.txt"
vgcfgbackup -f "$BACKUP_DIR/$DATE/vg_backup.conf"

# 备份逻辑卷信息
lvdisplay > "$BACKUP_DIR/$DATE/lvdisplay.txt"
lvs --all > "$BACKUP_DIR/$DATE/lvs_all.txt"

# 备份fstab中LVM挂载配置
grep -E '(mapper|/dev/[a-zA-Z]+/[a-zA-Z]+)' /etc/fstab > "$BACKUP_DIR/$DATE/fstab_lvm.txt"

# 备份LVM配置文件
cp /etc/lvm/{lvm.conf,archive/*} "$BACKUP_DIR/$DATE/" 2>/dev/null

# 创建恢复脚本
cat > "$BACKUP_DIR/$DATE/restore_lvm.sh" << 'EOF'
#!/bin/bash
# LVM恢复脚本

echo "=== LVM配置恢复 ==="

# 恢复卷组配置
if [ -f "vg_backup.conf" ]; then
    echo "恢复卷组配置..."
    vgcfgrestore -f vg_backup.conf
fi

# 激活卷组
echo "激活卷组..."
vgs --noheadings -o vg_name | while read vg; do
    vgchange -ay "$vg"
done

echo "恢复完成。请检查:"
echo "1. pvs - 查看物理卷"
echo "2. vgs - 查看卷组"
echo "3. lvs - 查看逻辑卷"
EOF

chmod +x "$BACKUP_DIR/$DATE/restore_lvm.sh"

# 压缩备份
tar -czf "$BACKUP_DIR/lvm_backup_$DATE.tar.gz" -C "$BACKUP_DIR" "$DATE"

# 清理旧备份(保留最近7天)
find "$BACKUP_DIR" -name "lvm_backup_*.tar.gz" -mtime +7 -delete

echo "LVM配置备份完成: $BACKUP_DIR/lvm_backup_$DATE.tar.gz"

知识点速查手册

核心概念速查

1. LVM三组件关系

text

复制代码
物理卷(PV) → 卷组(VG) → 逻辑卷(LV)
    ↓             ↓             ↓
硬盘/分区       存储池         逻辑分区
    ↓             ↓             ↓
/dev/sda1     webapp       /dev/webapp/lv1
/dev/sdb      (60G)        /dev/webapp/lv2
2. 文件系统调整方法对比
操作 XFS EXT4 说明
在线扩展 支持 支持 无需卸载
在线缩减 不支持 不支持 必须卸载
离线扩展 支持 支持 需要卸载
离线缩减 不支持 支持 有风险
命令 xfs_growfs resize2fs 文件系统调整

命令速查手册

1. 物理卷管理
任务 命令 示例
创建PV pvcreate pvcreate /dev/sdb
查看PV pvs pvdisplay pvs pvdisplay /dev/sdb
删除PV pvremove pvremove /dev/sdb
迁移数据 pvmove pvmove /dev/sdb /dev/sdc
2. 卷组管理
任务 命令 示例
创建VG vgcreate vgcreate webapp /dev/sdb
查看VG vgs vgdisplay vgs vgdisplay webapp
扩展VG vgextend vgextend webapp /dev/sdc
缩减VG vgreduce vgreduce webapp /dev/sdb
删除VG vgremove vgremove webapp
激活VG vgchange vgchange -ay webapp
3. 逻辑卷管理
任务 命令 示例
创建LV lvcreate lvcreate -n lv1 -L 10G webapp
查看LV lvs lvdisplay lvs lvdisplay /dev/webapp/lv1
扩展LV lvextend lvextend -L +5G /dev/webapp/lv1
缩减LV lvreduce lvreduce -L -5G /dev/webapp/lv1
删除LV lvremove lvremove /dev/webapp/lv1
创建快照 lvcreate -s lvcreate -s -n snap1 -L 10G /dev/webapp/lv1
创建RAID lvcreate --type lvcreate --type raid1 -n lv1 -L 10G webapp
4. 文件系统调整
任务 XFS命令 EXT4命令
扩展文件系统 xfs_growfs resize2fs
缩减文件系统 不支持 resize2fs
检查文件系统 xfs_repair -n e2fsck -f
一步扩展 lvextend -r lvextend -r

常见问题诊断表

问题1:无法创建/扩展逻辑卷
可能原因 检查方法 解决方案
卷组空间不足 vgs vgextend 扩展卷组
PE大小不匹配 vgdisplay 创建时指定相同PE大小
权限不足 id 使用root或sudo
卷组未激活 vgs -o vg_attr vgchange -ay 卷组名
问题2:文件系统调整失败
可能原因 检查方法 解决方案
未卸载文件系统 `mount grep`
空间不足扩展 df -h 先扩展逻辑卷
文件系统损坏 fsck 修复文件系统
XFS尝试缩减 确认文件系统类型 XFS不支持缩减
问题3:数据迁移失败
可能原因 检查方法 解决方案
目标空间不足 pvs 确保目标PV有足够空间
逻辑卷正在使用 lsof /dev/mapper/... 确保无人使用
迁移过程中断 pvmove -i 5 重新执行或恢复

最佳实践检查清单

规划阶段
  • 根据业务需求设计LVM结构
  • 确定合适的PE大小(默认4MB,大存储可用16MB+)
  • 规划卷组和逻辑卷的命名规范
  • 预留足够的扩展空间(建议20-30%)
实施阶段
  • 使用UUID而非设备名挂载(避免设备名变化)
  • 为重要数据启用RAID保护
  • 定期创建快照用于备份
  • 记录LVM配置和变更历史
维护阶段
  • 监控存储使用率,设置告警阈值
  • 定期检查LVM健康状态
  • 备份LVM元数据配置
  • 测试恢复流程确保可用性
安全阶段
  • 限制对LVM命令的访问权限
  • 定期审计LVM配置变更
  • 为生产环境启用写保护快照
  • 实施访问控制策略

性能优化建议

1. PE大小优化
bash 复制代码
# 大文件场景(视频、数据库):使用大PE
vgcreate -s 16M bigdata /dev/sdb

# 小文件场景(邮件、网页):使用小PE
vgcreate -s 1M smalldata /dev/sdc
2. 条带化优化(RAID0/LVM条带)
bash 复制代码
# 创建条带化逻辑卷(提升IO性能)
lvcreate -n fast_lv -L 100G -i 4 -I 64 webapp
# -i: 条带数(跨几个PV)
# -I: 条带大小(KB)
3. 读写策略优化
bash 复制代码
# 更改逻辑卷的预读策略
lvchange --readahead 512 /dev/webapp/lv1  # 设置512扇区预读

# 更改逻辑卷的缓存策略
lvchange --cachepolicy smq /dev/webapp/lv1  # 使用多队列缓存

文档版本 :v2.1
最后更新 :Jan 7th, 2026
适用系统 :RHEL/CentOS/Rocky Linux 7/8/9
作者:Origin by Laoma , Rewrite by Whisky

重要提醒

  1. 生产环境操作前务必备份重要数据
  2. LVM缩减操作具有风险,务必在测试环境验证
  3. 定期监控存储使用趋势,提前规划扩容
  4. 文档化所有LVM配置和变更操作
相关推荐
半部论语4 分钟前
openEuler 安装 LibreOffice 技术指南
linux
r-t-H4 分钟前
Docker进阶与容器编排实践-第二章
运维·docker·容器·dockerfile·docker compose·docker网络
爱装代码的小瓶子9 分钟前
muduo库 --socket的封装
服务器·开发语言·php
凡人叶枫10 分钟前
Effective C++ 条款13:以对象管理资源(RAII)
java·linux·开发语言·c++·嵌入式开发
爱喝水的鱼丶14 分钟前
SAP-ABAP:SAP多表连接视图实战:内连接/外连接配置逻辑与性能优化技巧
运维·开发语言·学习·性能优化·sap·abap
cgsthtm16 分钟前
Jenkins添加用户和角色并分配相应Job权限
运维·jenkins·jenkins用户·jenkins角色·jenkins权限·jenkins job
mnasd18 分钟前
Gitlab + Jenkins 实现 CICD
运维·gitlab·jenkins
m0_7373025821 分钟前
OpenClaw:不止于对话,能真正动手的开源 AI 智能体
服务器
難釋懷25 分钟前
Nginx测试工具charles
运维·nginx·php
云飞云共享云桌面28 分钟前
东莞制造业研发降本方案:1 台云主机承载 10 人 SolidWorks,钣金操作秒响应
linux·运维·服务器·安全·电脑