LVM事故演练_PV掉线_partial激活与恢复
一、实验背景
在日常运维里,LVM 最有价值的地方不是扩容,而是面对磁盘故障时的可恢复性。
如果一个卷组里有多块 PV,而某个 LV 又跨在这些 PV 上,那么一旦其中一块盘掉线,就会进入一种很典型的事故状态:
- 卷组还能被识别
- 但卷组会提示
missing PV - 逻辑卷会进入
partial状态 - 这时系统通常不能再把它当成“完全正常”的卷来使用
这次演练的目标就是模拟这个过程,并验证:
- 如何确认故障范围
- 如何执行
partial activation - 如何在磁盘恢复后把卷组拉回正常状态
二、实验环境
实验机信息:
- 系统:Rocky Linux 9.7
- 卷组:
vg_demo - 逻辑卷:
lv_app - 挂载点:
/data/demo
实验前,vg_demo 已经有两块 PV:
/dev/sdb1/dev/sdc1
并且 lv_app 已经跨在两块 PV 上。
文件系统类型是 xfs,挂载在 /data/demo。
基线检查命令
vgcfgbackup vg_demo # 先备份卷组元数据,避免误操作后无法回滚
pvs -o+pv_uuid,pv_attr,vg_name,pv_size,pv_free # 记录 PV 状态和 UUID
vgs -o+vg_attr,vg_size,vg_free # 记录 VG 状态
lvs -a -o+devices,lv_attr,lv_size # 记录 LV 和设备映射关系
findmnt /data/demo # 确认挂载关系
df -hT /data/demo # 记录容量和文件系统类型
dmesg | tail -n 20 # 记录当前内核日志原始输出摘录
1. 先看一下当前会话环境
[root@localhost ~]# ll
总用量 4
-rw-------. 1 root root 1304 4月 22 15:56 anaconda-ks.cfg
[root@localhost ~]# ll -a
总用量 28
dr-xr-x---. 3 root root 147 4月 22 15:59 .
dr-xr-xr-x. 19 root root 247 4月 22 16:47 ..
-rw-------. 1 root root 1304 4月 22 15:56 anaconda-ks.cfg
-rw-------. 1 root root 943 4月 22 16:57 .bash_history
-rw-r--r--. 1 root root 18 11月 3 01:06 .bash_logout
-rw-r--r--. 1 root root 141 11月 3 01:06 .bash_profile
-rw-r--r--. 1 root root 429 11月 3 01:06 .bashrc
-rw-r--r--. 1 root root 100 11月 3 01:06 .cshrc
drwx------. 2 root root 6 4月 22 15:54 .ssh
-rw-r--r--. 1 root root 129 11月 3 01:06 .tcshrc这段和 LVM 本身没有直接关系,但它能说明:当时我是在同一个 root 会话里连续完成整套实验的。
2. 备份卷组元数据
[root@localhost ~]# vgcfgbackup vg_demo
Volume group "vg_demo" successfully backed up.3. 基线 LVM 状态
[root@localhost ~]# pvs -o+pv_uuid,pv_attr,vg_name,pv_size,pv_free
PV VG Fmt Attr PSize PFree PV UUID Attr VG PSize PFree
/dev/sda3 rlm lvm2 a-- 62.41g 0 SFgzi0-Uw5r-B9X4-gbcj-YPqg-Awvc-YN7cFf a-- rlm 62.41g 0
/dev/sdb1 vg_demo lvm2 a-- <5.00g 0 6fyO3k-efYe-36q3-cMqI-ysjn-ldv0-Abp1Sz a-- vg_demo <5.00g 0
/dev/sdc1 vg_demo lvm2 a-- <5.00g 0 mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi a-- vg_demo <5.00g 0
[root@localhost ~]# vgs -o+vg_attr,vg_size,vg_free
VG #PV #LV #SN Attr VSize VFree Attr VSize VFree
rlm 1 3 0 wz--n- 62.41g 0 wz--n- 62.41g 0
vg_demo 2 1 0 wz--n- 9.99g 0 wz--n- 9.99g 0
[root@localhost ~]# lvs -a -o+devices,lv_attr,lv_size
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Devices Attr LSize
home rlm -wi-ao---- 19.80g /dev/sda3(10386) -wi-ao---- 19.80g
root rlm -wi-ao---- 40.57g /dev/sda3(0) -wi-ao---- 40.57g
swap rlm -wi-ao---- <2.04g /dev/sda3(15456) -wi-ao---- <2.04g
lv_app vg_demo -wi-ao---- 9.99g /dev/sdb1(0) -wi-ao---- 9.99g
lv_app vg_demo -wi-ao---- 9.99g /dev/sdc1(0) -wi-ao---- 9.99g4. 挂载和容量
[root@localhost ~]# findmnt /data/demo
TARGET SOURCE FSTYPE OPTIONS
/data/demo /dev/mapper/vg_demo-lv_app xfs rw,relatime,seclabel,attr2,inode64,
[root@localhost ~]# df -hT /data/demo
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/vg_demo-lv_app xfs 10G 106M 9.9G 2% /data/demo5. 先看一眼相关内核日志
[root@localhost ~]# dmesg | tail -n 20
[ 15.891925] XFS (dm-2): Mounting V5 Filesystem 8d0ced08-930f-4f19-9f02-45959cefb158
[ 15.892228] XFS (dm-3): Mounting V5 Filesystem 7119dfab-c5fd-4f70-b8dd-93ad858f838a
[ 15.914886] XFS (dm-3): Ending clean mount
[ 15.925608] XFS (dm-2): Ending clean mount基线结果摘要
故障前,系统状态如下:
vg_demo正常lv_app同时落在/dev/sdb1和/dev/sdc1/data/demo正常挂载- 文件系统显示为
xfs - 容量约
10G
这一点非常重要,因为如果 LV 只在单块 PV 上,后面的 partial activation 演练价值就会大幅下降。
三、故障注入:模拟第二块盘掉线
真实生产里,磁盘掉线可能来自:
- 虚拟化平台热拔盘
- 存储链路异常
- 底层设备故障
- 主机重启后设备枚举变化
本次实验采用最直接的方式模拟掉盘:
echo 1 > /sys/block/sdc/device/delete # 让内核忘掉 /dev/sdc,模拟磁盘消失这个命令的作用是让当前内核认为这块磁盘已经不在了。
注意:这是实验命令,不要在生产环境随便执行。
原始故障输出摘录
1. 删除磁盘后先看设备变化
[root@localhost ~]# lsblk -d -o NAME,SIZE,TYPE,MODEL,TRAN
NAME SIZE TYPE MODEL TRAN
sda 64G disk Rocky Linux-0 SSD sata
sdb 5G disk Rocky Linux-1 SSD sata
sr0 1024M rom Virtual DVD-ROM [1] sata这时 sdc 已经不见了。
2. LVM 开始报 missing PV
[root@localhost ~]# pvs -o+pv_uuid,pv_attr,vg_name,pv_size,pv_free
WARNING: Couldn't find device with uuid mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi.
WARNING: VG vg_demo is missing PV mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi (last written to /dev/sdc1).
PV VG Fmt Attr PSize PFree PV UUID Attr VG PSize PFree
/dev/sda3 rlm lvm2 a-- 62.41g 0 SFgzi0-Uw5r-B9X4-gbcj-YPqg-Awvc-YN7cFf a-- rlm 62.41g 0
/dev/sdb1 vg_demo lvm2 a-- <5.00g 0 6fyO3k-efYe-36q3-cMqI-ysjn-ldv0-Abp1Sz a-- vg_demo <5.00g 0
[unknown] vg_demo lvm2 a-m <5.00g 0 mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi a-m vg_demo <5.00g 0
[root@localhost ~]# vgs -o+vg_attr,vg_size,vg_free
WARNING: Couldn't find device with uuid mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi.
WARNING: VG vg_demo is missing PV mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi (last written to /dev/sdc1).
VG #PV #LV #SN Attr VSize VFree Attr VSize VFree
rlm 1 3 0 wz--n- 62.41g 0 wz--n- 62.41g 0
vg_demo 2 1 0 wz-pn- 9.99g 0 wz-pn- 9.99g 0
[root@localhost ~]# lvs -a -o+devices,lv_attr,lv_size
WARNING: Couldn't find device with uuid mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi.
WARNING: VG vg_demo is missing PV mL8XcA-Q0gB-f4zj-DR3W-UiHv-ZPje-dLgxQi (last written to /dev/sdc1).
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Devices Attr LSize
home rlm -wi-ao---- 19.80g /dev/sda3(10386) -wi-ao---- 19.80g
root rlm -wi-ao---- 40.57g /dev/sda3(0) -wi-ao---- 40.57g
swap rlm -wi-ao---- <2.04g /dev/sda3(15456) -wi-ao---- <2.04g
lv_app vg_demo -wi-ao--p- 9.99g /dev/sdb1(0) -wi-ao--p- 9.99g
lv_app vg_demo -wi-ao--p- 9.99g [unknown](0) -wi-ao--p- 9.99g这里的 a-m、wz-pn-、-wi-ao--p- 都是信号,说明卷组已经不再完整。
四、故障现场现象
掉盘后,第一步是观察设备变化和 LVM 状态。
1. 设备消失
lsblk -d -o NAME,SIZE,TYPE,MODEL,TRAN # 看 /dev/sdc 是否消失结果里,sdc 不见了,只剩下:
sdasdbsr0
这说明故障注入已经生效。
2. LVM 报 missing PV
pvs -o+pv_uuid,pv_attr,vg_name,pv_size,pv_free
vgs -o+vg_attr,vg_size,vg_free
lvs -a -o+devices,lv_attr,lv_size现场表现非常典型:
pvs提示找不到sdc1对应的 PV UUIDvgs提示vg_demo缺失 PVlvs里的lv_app属性出现了p
这里的 p 就是关键:
它表示这个 LV 进入了 partial 状态,也就是“不完整状态”。
3. 挂载点表面上还在
mount | grep /data/demo
df -hT /data/demo实验里,/data/demo 仍然显示挂载中,容量也还是 10G。
这一步很容易误导人。
挂载还在,不等于卷健康。
真正要看的是 pvs / vgs / lvs 的状态,而不是只看 df。
五、部分激活:先把还能活的卷拉起来
当卷组缺少一块 PV 时,LVM 不会“自动帮你修复”。
你能做的是先尝试把可用部分激活起来,给后续排障争取时间。
1. 重新扫描卷组
vgscan # 重新扫描卷组系统仍然会提示:
- 找不到缺失 PV 的 UUID
vg_demo缺失sdc1
但卷组本身还能被识别出来。
2. 执行 partial activation
vgchange -ay --partial vg_demo # 只激活还能识别的部分这一步的输出里会看到:
PARTIAL MODEIncomplete logical volumes will be processed1 logical volume(s) in volume group "vg_demo" now active
这说明 LVM 已经尽量把幸存部分拉起来了。
但它不是“修复完成”,只是“先救活现场”。
3. 再次检查 LV 状态
lvs -a -o+devices,lv_attr,lv_size # 再看 LV 是否还是 partial这时 lv_app 仍然显示 p,说明它仍然处于缺盘状态。
这正是我们要演示的事故态。
六、恢复磁盘:重新扫描并让 LVM 认回 PV
磁盘掉线后,如果底层硬件或虚拟化平台恢复了,你要做的是重新扫描总线,让系统重新发现设备。
1. 重新扫描 SCSI 总线
for host in /sys/class/scsi_host/host*; do echo "- - -" > "$host/scan"; done # 扫描所有 host
udevadm settle # 等待设备节点稳定这一步的意义是:
- 让内核重新发现磁盘
- 让
/dev下的设备节点重新创建 - 避免设备还没稳定就继续执行 LVM 命令
原始恢复输出摘录
1. 重新扫描总线后,LVM 重新识别到新设备
[root@localhost ~]# for host in /sys/class/scsi_host/host*; do echo "- - -" > "$host/scan"; done
[root@localhost ~]# udevadm settle
[root@localhost ~]# pvscan --cache
pvscan[5667] PV /dev/sdb1 online.
pvscan[5667] PV /dev/sda3 online.
pvscan[5667] PV /dev/sdd1 online.这一次恢复后,设备名已经从 sdc 变成了 sdd。
这正好印证了前面那句话:设备名会变,PV UUID 才是关键。
2. 恢复卷组
[root@localhost ~]# vgchange -ay vg_demo
1 logical volume(s) in volume group "vg_demo" now active
[root@localhost ~]# lvs -a -o+devices,lv_attr,lv_size
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Devices Attr LSize
home rlm -wi-ao---- 19.80g /dev/sda3(10386) -wi-ao---- 19.80g
root rlm -wi-ao---- 40.57g /dev/sda3(0) -wi-ao---- 40.57g
swap rlm -wi-ao---- <2.04g /dev/sda3(15456) -wi-ao---- <2.04g
lv_app vg_demo -wi-ao---- 9.99g /dev/sdb1(0) -wi-ao---- 9.99g
lv_app vg_demo -wi-ao---- 9.99g /dev/sdd1(0) -wi-ao---- 9.99g
[root@localhost ~]# df -hT /data/demo
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/vg_demo-lv_app xfs 10G 106M 9.9G 2% /data/demo2. 刷新 LVM 缓存
pvscan --cache # 刷新 LVM 缓存,重新识别在线 PV这次实验里,系统重新识别到的磁盘名已经不是原来的 sdc,而是变成了 sdd。
这点很关键:
- 设备名会变
- PV UUID 才是 LVM 识别的核心
- 所以排障时不要死盯
/dev/sdc1
3. 正常激活卷组
vgchange -ay vg_demo # 正常激活卷组激活后,vg_demo 又回到了正常状态,lv_app 也恢复为完整卷。
七、恢复后验证
恢复完成后,检查三类信息:
1. LVM 状态
lvs -a -o+devices,lv_attr,lv_size # 确认 LV 已经恢复正常恢复后结果显示:
lv_app属性不再是partial- 设备映射重新完整
- 两块 PV 都能被识别
2. 挂载状态
findmnt /data/demo # 确认挂载还在
df -hT /data/demo # 确认容量和文件系统状态实验结果显示:
/data/demo仍然正常挂载- 文件系统是
xfs - 容量仍然是
10G
3. 内核日志
dmesg | tail -n 50 # 检查是否还有残留 I/O 错误在这次演练中,掉盘和恢复过程都被内核记录了下来。
恢复后没有继续出现新的 I/O 报错,说明实验闭环完成。
八、这次实验的核心结论
1. 先备份元数据
vgcfgbackup 很重要。
在事故演练或者真实故障里,先留元数据备份再操作,是很好的习惯。
2. 设备名不可靠,UUID 更可靠
掉盘恢复后,磁盘名可能从 sdc 变成 sdd。
如果你的排障思路还停留在固定设备名上,很容易误判。
3. partial activation 是救援手段,不是修复手段
vgchange -ay --partial 的作用是:
- 尽量把还能活的卷拉起来
- 给你保数据、保现场、保诊断时间
它不会自动修复缺失的 PV。
4. 挂载还在,不代表卷健康
这次实验里,即便 /data/demo 还在挂载,LVM 也已经进入了缺盘状态。
所以生产上不能只看 df,还要看:
pvsvgslvs
5. 故障恢复后要重新验证
不是 vgchange -ay 成功就结束了。
你还要继续确认:
- LV 是否恢复完整
- 挂载是否正常
- 内核是否还报错
九、适合直接复制的排障流程
如果你以后在生产里遇到类似情况,可以先按这个顺序查:
pvs -o+pv_uuid,pv_attr,vg_name,pv_size,pv_free # 看哪个 PV 掉了
vgs -o+vg_attr,vg_size,vg_free # 看 VG 是否 partial
lvs -a -o+devices,lv_attr,lv_size # 看 LV 是否跨缺失 PV
vgscan # 扫描卷组
vgchange -ay --partial <vg_name> # 尝试部分激活
dmesg | tail -n 50 # 看底层 I/O 错误如果设备恢复:
for host in /sys/class/scsi_host/host*; do echo "- - -" > "$host/scan"; done
udevadm settle
pvscan --cache
vgchange -ay <vg_name>十、总结
这次演练比单纯扩容更接近真实事故场景。
它告诉我们三件事:
- LVM 的故障判断要看元数据状态,不是只看挂载点
- 设备恢复后,设备名可能变化,排障不能依赖固定路径
partial activation的意义是“先救现场”,不是“自动修复”
如果你在生产上做 LVM 运维,这类演练非常值得做一遍。
因为真正出事时,最值钱的不是扩容命令,而是你能不能在缺盘状态下快速判断、快速止损、快速恢复。