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

基于LVM的数据恢复技术研究(场景3:LV信息被误删除;场景4:云平台磁盘迁移中磁盘缩容)

字数 9411阅读 1106评论 1赞 6

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

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

场景3:LV信息被误删除

一、 故障描述:

lv(logical volume )信息可能因管理员误操作,导致被误删除了,此时数据依旧完整。

二、 测试方式:

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

三、 故障模拟:

此时我们手工删除lv _cs ,以模拟误删除场景。

[root@std76 backup]# lvremove /dev/vg_cs/lv_cs 
Do you really want to remove active logical volume vg_cs/lv_cs? [y/n]: y
  Logical volume "lv_cs" successfully removed
[root@std76 backup]# 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 

四、 恢复过程:

首先还是直接使用vgcfgrestore来恢复尝试恢复:

[root@std76 /]# vgcfgrestore vg_cs
  Restored volume group vg_cs
  Scan of VG vg_cs from /dev/sdb found metadata seqno 6 vs previous 5.
  Scan of VG vg_cs from /dev/sdc found metadata seqno 6 vs previous 5.
  Scan of VG vg_cs from /dev/sdd found metadata seqno 6 vs previous 5.
  Scan of VG vg_cs from /dev/sde found metadata seqno 6 vs previous 5.

提示中,显示每个逻辑卷块设备的seqno序号增加了1,与之前不一致了。

[root@std76 /]# vgchange -ay vg_cs
  0 logical volume(s) in volume group "vg_cs" now active
[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                                                    

使用vgchange来激活vg _cs 里的lv,提示没有可以激活的对象。同时,lvs信息里也没有lv _cs 。说明目前的恢复是失败的。

从前面的seqno序号提示错,去检查下lvm最后一次备份信息:

[root@std76 /]# cd /etc/lvm/backup/
[root@std76 backup]# vi vg_cs   
# Generated by LVM2 version 2.02.180(2)-RHEL7 (2018-07-20): Sun Nov  7 19:25:07 2021

contents = "Text Format Volume Group"
version = 1

description = "Created *after* executing 'lvremove /dev/vg_cs/lv_cs'"

creation_host = "std76" # Linux std76 3.10.0-957.axs7.x86_64 #1 SMP Thu May 9 10:22:45 UTC 2019 x86_64
creation_time = 1636284307      # Sun Nov  7 19:25:07 2021

vg_cs {
        id = "si4zqx-hJtz-XpcZ-yWaJ-Hinp-7gXA-7gsvNp"
        seqno = 10
        format = "lvm2"                 # informational
        status = ["RESIZEABLE", "READ", "WRITE"]
        flags = []
        extent_size = 8192              # 4 Megabytes
        max_lv = 0
        max_pv = 0
        metadata_copies = 0

从文件的description部分,文件在执行lvremove后被创建,所以这个最新的,存在在/ etc/lvm/backup 目录下的文件,里面已经没有lv_ cs 的卷信息了!

从这里不难发现,每次我们对lvm操作,操作系统都会自动的做一次备份,这在归档目录,也就是/ etc/lvm/archive 中,可以确认的到:

[root@std76 archive]# vgcfgrestore --list vg_cs 
  File:         /etc/lvm/archive/vg_cs_00094-1199622984.vg
  VG name:      vg_cs
  Description:  Created *before* executing 'vgextend vg_cs /dev/sde'
  Backup Time:  Sun Nov  7 19:23:18 2021

   
  File:         /etc/lvm/archive/vg_cs_00095-2071738031.vg
  VG name:      vg_cs
  Description:  Created *before* executing 'lvcreate -L 1G -n lv_cs vg_cs'
  Backup Time:  Sun Nov  7 19:23:31 2021

   
  File:         /etc/lvm/archive/vg_cs_00096-1271921693.vg
  VG name:      vg_cs
  Description:  Created *before* executing 'lvremove /dev/vg_cs/lv_cs'
  Backup Time:  Sun Nov  7 19:25:07 2021

   
  File:         /etc/lvm/backup/vg_cs
  VG name:      vg_cs
  Description:  Created *after* executing 'lvremove /dev/vg_cs/lv_cs'
  Backup Time:  Sun Nov  7 19:25:07 2021

关于archive和backup的保留策略,可以在l vm.conf 中配置,例如:

        # Configuration option backup/retain_min.
        # Minimum number of archives to keep.
        retain_min = 10

        # Configuration option backup/retain_days.
        # Minimum number of days to keep archive files.
        retain_days = 30

到这里已经很明确了,我们要利用lvremove之前的归档文件去恢复,所以即archive目录下的最后一个文件进行恢复:

[root@std76 archive]# vgcfgrestore --file /etc/lvm/archive/vg_cs_00096-1271921693.vg vg_cs
  Restored volume group vg_cs
  Scan of VG vg_cs from /dev/sdb found mda_checksum 1afde46b mda_size 1594 vs previous b869eaca 1182
  Scan of VG vg_cs from /dev/sdc found mda_checksum 1afde46b mda_size 1594 vs previous b869eaca 1182
  Scan of VG vg_cs from /dev/sdd found mda_checksum 1afde46b mda_size 1594 vs previous b869eaca 1182
  Scan of VG vg_cs from /dev/sde found mda_checksum 1afde46b mda_size 1594 vs previous b869eaca 1182
[root@std76 archive]# 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.00g                                                    
[root@std76 archive]# vgchange -ay vg_cs
  1 logical volume(s) in volume group "vg_cs" now active
[root@std76 archive]# 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-a-----  1.00g                                                    
[root@std76 archive]# mount /dev/vg_cs/lv_cs /cs
[root@std76 archive]# vi /cs/testfile 
1
2
3
4
5

激活lv后,可看到数据恢复了。这里因为数据本身没有改动,所以也没做文件系统的检查或恢复了。不过建议还是做一下比较好。

五、 总结:

/ etc/lvm/ back up 文件始终是最新的lvm备份文件,每次lvm相关的操作都会将这个文件移到 archive 下,并再生成最新的backup文件。

所以,在之前的场景下,磁盘本身出现故障,lvm信息并未改动,则使用backup文件做恢复(直接使用vg cfgrestore 命令时,默认使用该文件);如果lvm做了操作后,做恢复,则需要用archive下的历史文件进行恢复,需注意!

场景4:云平台磁盘迁移中磁盘缩容

一、 故障描述:

云平台在做磁盘迁移(retype)过程中,可能会因云平台存储驱动等参数配置问题,导致在初始创建磁盘时,比实际需求略大。如建1000G磁盘,实际创建了1000.11G的磁盘大小。

这可能会造成后续retype过程中,新建的磁盘(标准1000G)略小于原磁盘大小(1000.11G) 。 迁移完后,文件系统挂载时,校验扇区个数时少于lvm配置文件中的扇区数,导致挂载失败,文件系统打开失败。

这种情况极少见,恢复难度五颗星!

二、 故障模拟环境 :

模拟存储超分,进行虚机的数据盘迁移。在使用云平台retype命令迁移结束后,发现文件系统出现异常,执行lvm相关命令均出现如下提示:

WARNING: Device /dev/vdb has size of 209715200 sectors which is smaller than corresponding PV size of 2097379328 sectors. Was device resized?
One or more devices used as PVs in VG vg_app have changed sizes.
Physical extends end beyond end of device /dev/vdb.
Format-specific initialisation of physical volume /dev/vdb failed.
Failed to setup physical volume "/dev/vdb".

从提示中可以看到,vdb这块磁盘现在的扇区个数(209715200 )小于lvm信息中pv记录的扇区数(2097379328),加载/dev/vdb失败。

此时,操作系统层面,能看到vdb,但找不到对应的vg和lv。

三、 恢复过程:

接下来是个较为复杂的恢复过程......

从操作系统的提示,问该磁盘是否进行过resize( Was device resized? ),也验证了磁盘大小发生了改变。

先看下backup中lvm相关信息:

原LVM信息中,/dev/vdb扇区数:209737328

原厂提供的支持过程:

首先使用pvcreate尝试恢复lvm信息

pv丢失修复
pvcreate    -ff   --uuid <from backup/vg_app> --restorefile /etc/lvm/backup/vg_app  /dev/sdb
修复卷组
vgcfgrestore -f /etc/lvm/backup/vg_app  vg_app 
完事之后激活一下VG卷
 vgcfgrestore vg_app


特别提示:

从上图中可以看到,尝试重新初始化vdb这个pv,但仍失败,后我们分析,这里存在了lvm数据恢复的另一个因素,即在初始化设备时,会校验底层pv的扇区大小,来保证数据的一致性!

继续后面的步骤,尝试用lvm备份文件恢复lvm盘头信息,提示mda信息不一致

#vgcfgrestore vg_app
Restored volume group vg_app
Scan of VG vg_app from /dev/vdb found mda_checksum 30827968 mda_size 1300 vs previous 268231f7
Scan of VG vg_app from /dev/vdc found mda_checksum 30827968 mda_size 1300 vs previous 268231f7

#vgchange -ay vg_app
device-mapper: reload ioctl on (253:5) failed:无效的参数
0 logical volume(s) in volume group "vg_app" now active

lv激活失败,lv信息未正常识别到。

WARNING: Device /dev/vdb has size of 209715200 sectors which is smaller than corresponding PV size of 2097379328 sectors. Was device resized?
WARNING: Device /dev/vdc has size of 209715200 sectors which is smaller than corresponding PV size of 2097379328 sectors. Was device resized?
One or more devices used as PVs in VG vg_app have changed sizes.
LV      VG        Attr          LSize
lv_app vg_app     -wi-------     1.95t

此时,有一些地方介绍使用pvresize --setphysicalvolumesize,这将可能导致盘上数据丢失,谨慎操作!!

随后操作系统原厂又多次使用pvcreate搭配不同的参数、lvscan、vgscan等操作来尝试恢复,但仍因扇区数不一致,没法正常初始化lv_app设备。

再尝试用archive下的备份文件来恢复lvm信息,虽然vg和lv均能看到,但无法激活。

最终献出pvresize操作:

#pvresize /dev/vdb
Physical volume "/dev/vdb" changed
1 physical volume(s) resized / 0 physical volume(s) note resized

执行完后,lv_app仍无法激活, 推测pv上数据已丢失 。vg信息中显示没有已分配的空间:

#vgs
VG     #PV #LV #SN   Attr     VSzie      VFree
vg_app  1   0   0    wz--n-  300.00g    300.00g

从 <附件二 lvm扩容后逻辑卷为suspended状态无法挂载 > 案例中,pvresize后重新将pv再扩容到vg池中,pv等于是做了清空处理。

最终结论:“系统层面是无法恢复了。

事后尝试恢复数据:

在经过应用恢复数据,恢复了业务后,我们利用保留的“事故现场”再尝试恢复数据。

从上述恢复过程来看,操作系统一直在恢复出lvm信息后,仍会不断检查pv的扇区数,如果不一致,则无法激活对应的lvm。

所以,我们的思路是使用一个大于原先扇区数的新盘来恢复出数据。

第一步,我们挂载新的vdd块设备,其扇区数比原先的PV(2897379328)还要多。

第二步,我们使用dd命令,将vdb(无法打开的块设备)上数据完整的拷贝到vdd上。

第三步,此时,直接使用vdb的uuid号,来恢复lvm信息到vdd上,会提示uuid号重复已存在,且vg_app信息存在两个相同的vg信息。

此时,我们用了一招 “偷梁换柱”:

用vgimportclone 命令,创建vg_app 的快照 :

vgimportclone -n vg_app_snapshot /dev/vdb

将原vdb上的vg信息,重命名为vg_app_snapshot了。消除了两个相同的vg_app。

紧接着,尝试激活vg_app_snapshot,但可想而知,vdb小于预期(2897379328),所以激活失败。

此时vgcfgrestore直接来恢复vg_app,恢复前确认/etc/lvm/backup/vg_app中的PV信息(uuid和块设备名)是否和vdd的保持一致。


此时新划的vdd上的lvm信息,包括PV、VG、LV信息均可用!

文件系统激活、挂载均正常,数据可用!

恢复成功

四、 总结

本次恢复过程,我们发现,除了满足:

vdd磁盘上lvm信息正确,完整;

vdd上数据可用;

以外,还需要满足:

vdd磁盘上可用扇区数大于或等于lvm信息中的扇区数,校验通过!

当然同一主机上的vg信息是唯一的,不可重复!

附件一:

VG Attr

LV Attr(第 2 - 6 字段)

PV Attr

       The pv_attr bits are:
       1  (d)uplicate, (a)llocatable, (u)sed
       2  e(x)ported
       3  (m)issing

附件二:

红帽官网 LOGICAL VOLUME MANAGER ADMINISTRATION (RedHat 7 )

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/logical_volume_manager_administration/index#mdatarecover

lvm扩容后逻辑卷为suspended状态无法挂载

https://developer.aliyun.com/ask/250921?spm=a2c6h.13524658&;

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

6

添加新评论1 条评论

yulu4314yulu4314技术支持长春
2023-07-29 12:54
内容分享的很详细!
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广