三虎
作者三虎联盟成员·2023-07-28 15:41
系统运维工程师·中国邮政储蓄银行

基于LVM的数据恢复技术研究(场景1:lvm信息丢失;场景2:LUN盘无法识别)

字数 11615阅读 1233评论 1赞 5

LVM是 Logical Volume Manager(逻辑卷管理)的简写。LVM将一个或多个硬盘的分区在逻辑上集合,相当于一个大硬盘来使用,当硬盘的空间不够使用的时候,可以继续将其它的硬盘的分区加入其中,这样可以实现磁盘空间的动态管理,相对于普通的磁盘分区有很大的灵活性。 ( 详见附件二 红帽官网 LOGICAL VOLUME MANAGER ADMINISTRATION (RedHat 7 ) )

在实际使用中,可能因LVM信息或数据区域丢失,导致文件系统启动、初始化、识别等过程失败,造成文件系统不可用,故针对此,研究四种常见的故障场景,以应用数据丢失风险。

场景1:磁盘头部的lvm信息不慎丢掉

一、 故障描述:

某个LUN盘上的lvm信息突然丢失,可能是磁盘拷贝等原因,导致盘头信息的丢失,仅有少量数据丢失,大部分数据仍存在。

二、 测试方式:

初始化环境,使用一块盘创建了一个 vg_cs 的vg组,和一个l v_cs 的lvm卷,并挂载到/ cs 下,创建了一个testfile的临时文件,其中内容为1到1 0 万的连续数字。

[root@std76 ~]# pvs                                      
  PV         VG    Fmt  Attr PSize    PFree
  /dev/sda2  vg00  lvm2 a--    14.00g 4.00m
  /dev/sdb   vg_cs lvm2 a--  1000.00m    0 
[root@std76 ~]# lvs
  LV      VG    Attr       LSize    Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_root vg00  -wi-ao----   10.00g                                                    
  lv_swap vg00  -wi-ao----    4.00g                                                    
  lv_cs   vg_cs -wi-ao---- 1000.00m                                                    
[root@std76 ~]# vgs
  VG    #PV #LV #SN Attr   VSize    VFree
  vg00    1   2   0 wz--n-   14.00g 4.00m
  vg_cs   1   1   0 wz--n- 1000.00m    0 

三、 故障模拟:

这里使用dd方式抹掉了1KB的数据,导致lvm全体信息丢失。

[root@std76 ~]# dd if=/dev/zero of=/dev/sdb count=1 bs=1K        
1+0 records in
1+0 records out
1024 bytes (1.0 kB) copied, 0.000156226 s, 6.6 MB/s

dd后lv,vg,pv信息都看不到了:

[root@std76 ~]# pvs
  PV         VG   Fmt  Attr PSize  PFree
  /dev/sda2  vg00 lvm2 a--  14.00g 4.00m
[root@std76 ~]# lvs
  LV      VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_root vg00 -wi-ao---- 10.00g                                                    
  lv_swap vg00 -wi-ao----  4.00g                                                    
[root@std76 ~]# vgs
  VG   #PV #LV #SN Attr   VSize  VFree
  vg00   1   2   0 wz--n- 14.00g 4.00m

特别提示:

LVM标签,在磁盘的第二个扇区位置,占5 12 字节空间。紧随其后的是lvm原数据(metadata)。

四、 恢复过程:

直接使用 vgcfgrestore 来恢复盘头的lvm信息,失败:

[root@std76 ~]# vgcfgrestore vg_cs
  Volume group vg_cs has active volume: lv_cs.
  WARNING: Found 1 active volume(s) in volume group "vg_cs".
  Restoring VG with active LVs, may cause mismatch with its metadata.
Do you really want to proceed with restore of volume group "vg_cs", while 1 volume(s) are active? [y/n]: y
  Couldn't find device with uuid B6OFzx-wvmF-rzIQ-wosr-cfEW-NXvq-OccY1m.
  Cannot restore Volume Group vg_cs with 1 PVs marked as missing.
  Restore failed.

提示中,很明显,显示原来sdb设备的uuid找不到了,无法恢复,提示vg _cs 的一个pv被标记为丢失,恢复失败。

这时候需要考虑恢复的必要条件:

1、 肯定是盘面上的大部分数据存在;
2、 恢复lvm信息,让操作系统能识别到这块盘

所以现在需要想办法实现第二点,即恢复lvm信息。思路是,创建新的pv,用新的pv信息代替老的,再恢复lvm信息,这种方式是否能恢复不确定,我们只是尝试,如果能恢复出lvm信息让系统识别,即有很大希望恢复数据了。

[root@std76 ~]# pvcreate /dev/sdb
  Can't open /dev/sdb exclusively.  Mounted filesystem?
  Can't open /dev/sdb exclusively.  Mounted filesystem?

重建pv,发现失败,提示sdb已挂载?
再看下挂载点信息:

[root@std76 ~]# df -h
Filesystem                Size  Used Avail Use% Mounted on
/dev/mapper/vg00-lv_root   10G  8.3G  1.8G  83% /
devtmpfs                  959M     0  959M   0% /dev
tmpfs                     976M     0  976M   0% /dev/shm
tmpfs                     976M  9.0M  967M   1% /run
tmpfs                     976M     0  976M   0% /sys/fs/cgroup
/dev/sda1                 473M  160M  314M  34% /boot
tmpfs                     196M     0  196M   0% /run/user/0
tmpfs                     196M     0  196M   0% /run/user/501
tmpfs                     196M     0  196M   0% /run/user/1000
[root@std76 ~]# umount /cs
umount: /cs: not mounted

没有挂载
尝试强制重建:

[root@std76 ~]# pvcreate /dev/sdb --force
  Can't open /dev/sdb exclusively.  Mounted filesystem?
  Can't open /dev/sdb exclusively.  Mounted filesystem?

也没有起到作用。
继续排查。

[root@std76 ~]# ls -lrt /dev/mapper/
total 0
crw------- 1 root root 10, 236 Nov  5 22:57 control
lrwxrwxrwx 1 root root       7 Nov  5 22:57 vg00-lv_root -> ../dm-0
lrwxrwxrwx 1 root root       7 Nov  5 22:57 vg00-lv_swap -> ../dm-1
lrwxrwxrwx 1 root root       7 Nov  5 23:06 vg_cs-lv_cs -> ../dm-2
[root@std76 ~]# dmsetup remove /dev/vg_cs/lv_cs

发现lv仍以块设备形式存在,这种情况在主机突然丢失物理盘导致,重启应该就不会有这个问题了。此时,使用逻辑卷管理dm set up强制移除v g_cs-lv_cs 。

移除完成后,再创建卷。

[root@std76 /]# pvcreate --test --uuid sFTqbA-LAMf-Pam2-B2Uy-dnfj-cAXR-fIFKx8 --restorefile /etc/lvm/backup/vg_cs /dev/sdb
  TEST MODE: Metadata will NOT be updated and volumes will not be (de)activated.
  Couldn't find device with uuid sFTqbA-LAMf-Pam2-B2Uy-dnfj-cAXR-fIFKx8.
  Physical volume "/dev/sdb" successfully created.

[root@std76 /]# pvcreate --uuid sFTqbA-LAMf-Pam2-B2Uy-dnfj-cAXR-fIFKx8 --restorefile /etc/lvm/backup/vg_cs /dev/sdb
  Physical volume "/dev/sdb" successfully created.

特别提示:
1、上面使用了原磁盘sdb的uuid来重新创建sdb的pv信息, pvcreate命令,只是会重写(overwrite)sdb盘面上lvm的元数据,而不会影响sdb上存在的数据区域!!

2、测试模式(- -test ),只会验证性检查这步操作是否会成功,而不会直接更新该盘的lvm元数据信息,是一种实际操作前的保护机制。这步验证没问题,我们继续操作。

好了,再尝试恢复:

[root@std76 ~]# vgcfgrestore vg_cs        
  Restored volume group vg_cs

恢复成功!心情激动!

[root@std76 ~]# vgdisplay 
  --- Volume group ---
  VG Name               vg_cs
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               1000.00 MiB
  PE Size               4.00 MiB
  Total PE              250
  Alloc PE / Size       250 / 1000.00 MiB
  Free  PE / Size       0 / 0   
  VG UUID               XYc47w-IDI4-rNga-27xB-7LEk-wJPs-BHdOMJ
   
[root@std76 ~]# vgs       
  VG    #PV #LV #SN Attr   VSize    VFree
  vg00    1   2   0 wz--n-   14.00g 4.00m
  vg_cs   1   1   0 wz--n- 1000.00m    0 
[root@std76 ~]# vgchange -ay vg_cs

信息也都回来了。

[root@std76 ~]# vgchange -ay vg_cs
  1 logical volume(s) in volume group "vg_cs" now active
[root@std76 ~]# mount /dev/vg_cs/lv_cs /cs
[root@std76 ~]# ls -lrt /cs
total 592
drwx------ 2 root root  16384 Nov  5 23:01 lost+found
-rw-r--r-- 1 root root 588895 Nov  5 23:02 testfile

激活,挂载吧!

[root@std76 cs]# vi testfile 
1
2
3
4
5
6
7
8
……

数据都在 恢复成功!

五、 总结:

1、 虽然盘的数据不完整了,不要轻易重新格式化;

2、 想一切办法去恢复盘头上的lvm信息

3、 如果盘头信息丢失不多,比如几个扇区大小的数据,因超级块系统本身会备份,所以这时用文件系统的修复(x fs_repair 或者e 2fsck 等)或者直接用v gcfgrestore 一般可以解决问题的。

场景2:逻辑卷池中某个LUN盘无法识别

一、 故障描述:

在vg组中,存在多块LUN盘,其中一块LUN盘因某个原因,导致系统无法再识别到,需要利用剩余的LUN盘来恢复数据。这种情况下,因整个vg组不完整,导致vg或者lv无法挂载、识别、读写。

需要强调的是,丢失的LUN盘上要么是没有数据,或者丢失少量数据。如果上面丢失的数据较多,且是关键性的数据,那么这个问题,将转变为物理磁盘介质的数据恢复,需要转由硬件设备厂商或其他数据恢复专家来解决。

二、 测试方式:

初始化环境,使用一块盘创建了一个 vg_cs 的vg组,和一个l v_cs 的lvm卷,并挂载到/ cs 下,创建了一个testfile的临时文件,其中内容为1到1 0 万的连续数字。

其中vg _cs 中含有 sdb 和sdc盘。

lv使用默认的顺序读写,故测试数据目前存在在s db 上,使用:

s trings /dev/sdb | more

可以看到,盘头除了lvm相关的文件系统信息外,后面是文件名和文件内容信息。

三、 故障模拟:

此时我们模拟sdc这块磁盘丢失的情况,方法有两种,一是使用dd方式抹掉所有盘数据;二是从存储端拿掉s dc 盘的映射关系。

操作完后,重启主机,可以看到lv中出现unknown状态的卷:

[root@std76 ~]# pvs
  WARNING: Device for PV UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG not found or rejected by a filter.
  Couldn't find device with uuid UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG.
  WARNING: Couldn't find all devices for LV vg_cs/lv_cs while checking used and assumed devices.
  PV         VG    Fmt  Attr PSize    PFree
  /dev/sda2  vg00  lvm2 a--    14.00g 4.00m
  /dev/sdb   vg_cs lvm2 a--  1000.00m    0 
  [unknown]  vg_cs lvm2 a-m   996.00m    0

uuid= UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG 的卷,就是刚才的sdc卷,在/ etc /lvm/backup 中,也可以找到对应的关系。

特别提示:

关于pvs,l vs 和vgs中Attr各个字节对应的含义,最准确快速查找的方法是:

man 对应的命令,然后搜索pv_attr 、lv _attr 或者vg _attr ,就有当前版本最准确的解释了。这里为了方便大家快速浏览,三条命令的属性解释见附件一。

四、 恢复过程:

直接使用vgcfgrestore来恢复盘头的lvm信息,失败:

[root@std76 ~]# vgcfgrestore vg_cs
  Couldn't find device with uuid UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG.
  Cannot restore Volume Group vg_cs with 1 PVs marked as missing.
  Restore failed.

提示中,很明显,显示原来sdb设备的uuid找不到了,无法恢复,提示vg _cs的一个p被标记为丢失,恢复失败。

提示:

如何获取丢失盘的uuid?

1、 执行lvm相关操作后,会如上所示,直接提示出来;

2、 pvscan执行时

3、 lvm的备份信息中,即/ etc/lvm/backup/vg_cs 中也可以找到

这时候要用一个新的空盘来恢复,这里我们已经重新映射一个sdd到主机上,使用这个sdd来重建uuid= UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG 的pv。

[root@std76 ~]# pvcreate --uuid  UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG --restorefile /etc/lvm/backup/vg_cs /dev/sdd
  Couldn't find device with uuid UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG.
  WARNING: Device for PV UMpJuh-6cVh-3Hyc-MrTK-GDwo-TPeC-Wjb4NG not found or rejected by a filter.
  Physical volume "/dev/sdd" successfully created.

提示成功了,这时vg _cs 是完整的了。

验证lvm相关的信息:

[root@std76 ~]# pvs
  PV         VG    Fmt  Attr PSize    PFree
  /dev/sda2  vg00  lvm2 a--    14.00g 4.00m
  /dev/sdb   vg_cs lvm2 a--  1000.00m    0 
  /dev/sdd   vg_cs lvm2 a--   996.00m    0  
[root@std76 ~]# vgs
  VG    #PV #LV #SN Attr   VSize  VFree
  vg00    1   2   0 wz--n- 14.00g 4.00m
  vg_cs   2   1   0 wz--n- <1.95g    0 
[root@std76 ~]# lvs
  LV      VG    Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_root vg00  -wi-ao---- 10.00g                                                    
  lv_swap vg00  -wi-ao----  4.00g                                                    
  lv_cs   vg_cs -wi------- <1.95g       

这时,lv _cs 处于非激活状态,激活

[root@std76 ~]# vgchange -ay vg_cs     
  1 logical volume(s) in volume group "vg_cs" now active

因为少了一部分数据,所以这时候一定要做文件系统修复:

[root@std76 ~]# xfs_repair -L /dev/vg_cs/lv_cs 
Phase 1 - find and verify superblock...
Phase 2 - using internal log
        - zero log...
Invalid block length (0x0) for buffer
Log inconsistent (didn't find previous header)
empty log check failed
zero_log: cannot find log head/tail (xlog_find_tail=5)
        - scan filesystem freespace and inode maps...
bad magic number
Metadata CRC error detected at xfs_agf block 0x2ec801/0x200
Metadata CRC error detected at xfs_agi block 0x2ec802/0x200
bad on-disk superblock 3 - bad magic number
primary/secondary superblock 3 conflict - AG superblock geometry info conflicts with filesystem geometry
bad magic # 0x0 for agf 3
bad version # 0 for agf 3
bad sequence # 0 for agf 3
bad length 0 for agf 3, should be 127744
bad uuid 00000000-0000-0000-0000-000000000000 for agf 3
bad magic # 0x0 for agi 3
bad version # 0 for agi 3
bad sequence # 0 for agi 3
bad length # 0 for agi 3, should be 127744
bad uuid 00000000-0000-0000-0000-000000000000 for agi 3
reset bad sb for ag 3
reset bad agf for ag 3
reset bad agi for ag 3
bad agbno 0 for btbno root, agno 3
bad agbno 0 for btbcnt root, agno 3
bad agbno 0 for inobt root, agno 3
agi unlinked bucket 0 is 0 in ag 3 (inode=3145728)
……
……
agi unlinked bucket 63 is 0 in ag 3 (inode=3145728)
sb_fdblocks 508248, counted 380508
        - found root inode chunk
Phase 3 - for each AG...
        - scan and clear agi unlinked lists...
        - process known inodes and perform inode discovery...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - process newly discovered inodes...
Phase 4 - check for duplicate blocks...
        - setting up duplicate extent list...
        - check for inodes claiming duplicate blocks...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
Phase 5 - rebuild AG headers and trees...
        - reset superblock...
Phase 6 - check inode connectivity...
        - resetting contents of realtime bitmap and summary inodes
        - traversing filesystem ...
        - traversal finished ...
        - moving disconnected inodes to lost+found ...
Phase 7 - verify and correct link counts...
Maximum metadata LSN (1:15) is ahead of log (1:2).
Format log to cycle 4.
done

从修复的过程看,丢失的信息其实还是不少的,sdc上的数据肯定都没有了。

最后挂载,验证:

[root@std76 ~]# mount /dev/vg_cs/lv_cs /cs
[root@std76 ~]# ls -lrt /cs
total 576
-rw-r--r-- 1 root root 588895 Nov  7 11:54 testfile
[root@std76 ~]#    

再看看相关数据,都恢复上了。

五、 总结:

和场景1类似,如果要恢复一个lvm上剩余的数据,也需要给操作系统一个完整的lvm信息,这个才能作为一个完整的文件系统进行挂载,虽然此时数据已经不完整。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

5

添加新评论1 条评论

yulu4314yulu4314技术支持长春
2023-07-29 12:55
已读,文章很有帮助
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广