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配置和变更操作