本文最后更新于8 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
一、故障概述
- 现象:
feixiang-database-97的/data无法挂载,LVM 看不到 VG/LV,df里没有/data。 - 影响:500G 数据盘上的数据库、docker、备份等目录全部不可见。
二、环境信息
| 项 | 内容 |
|---|---|
| 系统盘 | /dev/vda(vda2=/boot、vda3=SWAP、vda4=/) |
| 数据盘 | /dev/vdb(500G)→ vdb1(500G 分区) |
| 期望拓扑 | vdb1 → PV → VG vgdata → LV lvdata(xfs)→ 挂载 /data |
| 参照机 103 | 相同架构,vdb1 → vgdata-lvdata → /data,工作正常 |
三、故障现象(关键命令输出)
# lsblk:vdb1 下面没有 lvm 层
vdb 252:16 0 500G 0 disk
└─vdb1 252:17 0 500G 0 part
# pvdisplay:PV 头在,但被识别为"新 PV",无 VG 元数据
"/dev/vdb1" is a new physical volume of "<500.00 GiB"
PE Size 0 / Total PE 0 / Allocated PE 0
# vgscan / lvdisplay:无任何输出(VG/LV 元数据丢失)
# fstab 异常:有两行 /data,其中一行指向不存在的设备
/dev/vgdata/lvdata /data xfs defaults 0 0
/dev/mapper/vdc1_data /data xfs defaults 0 0 # ← vdc 盘早已移除,异常残留
# archive 里暴露操作历史
vgdata_00003: Created *before* executing 'vgimportclone --basevgname vgdata_clone /dev/vdc1'
四、根因分析
- 原始盘的 PV UUID 为
ZHbnYL-...(记录在/etc/lvm/backup/vgdata)。 - 后来数据盘被替换。新盘内容是从旧盘克隆/恢复出来的,但换盘过程把 PV label 重新初始化了,导致:
- 新盘 PV UUID 变成
8XDTZN-...(即pvscan当前显示值); - PV 不再属于任何 VG,VG/LV 元数据区被清空 → LVM 把它当成”新 PV”,
/data消失。
- 新盘 PV UUID 变成
- 附带历史:
vgimportclone /dev/vdc1曾把一块克隆盘导入为vgdata_clone,并在 fstab 留下/dev/mapper/vdc1_data异常行(vdc 盘后已移除)。 - 数据本身完好:XFS 超块在 PV 偏移 2048 扇区(=1MiB,即
pe_start)处,克隆时完整保留;丢的只是 LVM 元数据。
五、恢复步骤(已验证可用 — 情况 B:PV UUID 不一致)
核心判断:备份里 PV UUID
ZHbnYL≠ 当前8XDTZN,所以不能直接vgcfgrestore,必须先按原始 UUID 重建 PV 头。
# 0. 确保无服务写盘、/data 未挂载
umount /data 2>/dev/null
# 1. 只读旁路验证数据(零风险,先确认数据可读)
LOOP=$(losetup -r -o 1048576 -f --show /dev/vdb1) # 偏移 = pe_start*512 = 2048*512 = 1MiB
mount -o ro,norecovery "$LOOP" /mnt/check # 须加 norecovery(XFS 需重放日志,纯 ro 会被拒)
ls -l /mnt/check ; du -sh /mnt/check/*
umount /mnt/check ; losetup -d "$LOOP"
# 2. 按原始 UUID 重建 PV 头(只写前 1MiB 的 label+metadata,不碰 XFS 数据区)
pvcreate --uuid "ZHbnYL-pELj-hYzq-K6tL-TupF-EH0j-OFnoNh" \
--restorefile /etc/lvm/backup/vgdata /dev/vdb1
# ↑ 若报 already a PV,末尾加 -f(安全,只重写 label)
# 3. 恢复 VG/LV 元数据
vgcfgrestore -f /etc/lvm/backup/vgdata vgdata
# 4. 激活
vgchange -ay vgdata
lvs -a -o +devices # 应看到 lvdata → /dev/vdb1(0)
# 5. 读写挂载验证(让 XFS 正常重放日志到一致状态)
mount /dev/vgdata/lvdata /mnt/check
ls -l /mnt/check ; df -h /mnt/check
umount /mnt/check
# 6. 修正 fstab(删除 /dev/mapper/vdc1_data 那行),正式挂载
vi /etc/fstab # 仅保留 /dev/vgdata/lvdata /data xfs defaults 0 0
mount -a
# 7. 重新生成并备份元数据
vgcfgbackup
tar czf /root/lvm-metadata-$(date +%F).tgz -C / etc/lvm/backup etc/lvm/archive
六、验证结果
| 检查项 | 结果 |
|---|---|
lvs | lvdata → /dev/vdb1(0) ✅ |
lsblk | vgdata-lvdata 出现在 vdb1 下,挂载 /data ✅ |
df -h /data | 500G,已用 346G ✅ |
| 业务目录 | database(43G)、docker(292G)、backup、prometheus、redis 等齐全 ✅ |
mount -a | 无报错 ✅ |
七、残留清理
losetup -d /dev/loop6 # 清理旁路验证时残留的只读 loop 设备(如仍存在)
八、后续加固
- 数据库一致性:本次是”克隆自运行中的旧盘”的崩溃一致性副本。数据库首次启动会自行 crash recovery,请关注启动日志与数据一致性,必要时做一次逻辑备份/校验。
- fstab 改用 XFS UUID 挂载(更稳健,不依赖设备节点名):
blkid /dev/vgdata/lvdata # 取 XFS 的 UUID
# 在 fstab 改为:UUID=xxxx-xxxx /data xfs defaults 0 0 - 元数据异地保存:定期
vgcfgbackup,并把/etc/lvm/backup、/etc/lvm/archive纳入配置管理/备份。 - 换盘/克隆操作纳入 runbook:云盘替换或克隆后 PV UUID 会变,需主动
vgcfgrestore或重新导入,避免重复踩坑。 - 数据库逻辑备份常态化,与 LVM 元数据备份分开存放。
十、关键命令速查
# 诊断
lsblk ; pvdisplay /dev/vdb1 ; vgscan ; lvdisplay
grep -E 'id =|device =|pe_start' /etc/lvm/backup/vgdata
pvscan
# 只读旁路看数据
losetup -r -o 1048576 -f --show /dev/vdb1
mount -o ro,norecovery /dev/loopN /mnt/check
# 恢复(PV UUID 不一致时)
pvcreate --uuid "<备份里的 pv0 id>" --restorefile /etc/lvm/backup/vgdata /dev/vdb1
vgcfgrestore -f /etc/lvm/backup/vgdata vgdata
vgchange -ay vgdata
# 备份元数据
vgcfgbackup


