1 摘要
随着计算机网络应用的发展,数据存储的安全性变的越来越重要。在常见的基于RAID和LVM的环境下面,当出现硬盘故障或者错误操作导致数据丢失的情况下,采用适当的数据恢复策略可以在很大程度上提供数据恢复的成功概率。本文研究了几种情况下的数据恢复技术和方法,为数据恢复和数据安全的预防提供了指导。
2 数据恢复需求
2.1 Linux IO存储栈
图(1)Linux IO 存储栈
Linux 的存储相关的栈包括如图1所示,最下方为各种硬件存储器,例如SATA,SAS,SSD等硬盘和磁带库等。
2.2 存储故障
2.2.1 介质故障
磁盘消失,例如由于线缆或者网络问题造成的磁盘丢失或者ISCSI磁盘链接失败
磁盘坏道
偶发的硬件错误
2.2.2 错误操作
包括误删除,格式化,重新分区等操作。
2.2.3 RAID故障
服务器上的硬盘比较多的应用了RAID(冗余磁盘阵列)来实现数据保护。以多块硬盘环境下常使用的RAID 5为例,当损坏一块硬盘时数据不会受到影响,而这种情况下如果第二块硬盘再损坏(或者更换硬盘时拔错)就会丢失数据。此时要注意硬盘掉线的先后顺序,如果将2块硬盘同时上线则会导致部分数据访问出错,正确的方法是先上线最后出问题的硬盘,看数据是不是我们想要的,再尝试之前掉线的硬盘进行比较。
有些RAID卡在插入掉线的硬盘时会自动尝试Rebuild(重建),这样就会损坏我们需要的数据,因此企业级数据恢复最好还是找专业的公司/人士来进行。有的RAID卡还会出现硬盘完好,而RAID信息丢失的问题。如果用户在运输服务器/磁盘阵列时,将硬盘拆出来单独运输,没有记录安装的顺序,也可能会导致数据无法访问。
2.2.4 文件或者文件系统故障
这部分属于高端的数据恢复技术,比如ext2、ext3、reiserfs、XFS…文件系统。Linux/Unix的数据恢复难度较大一方面是由于这些文件系统结构复杂,另一方面则是有些厂商的相关资料不公开,比如IBM的AIX系统。这样我们只能通过不断的摸索,积累经验来“破解”它们的结构,最终能够恢复上面的数据,或者提取出修改文件(属性)的访问记录等。
2.3 存储部署对数据丢失的考虑
通常需要引入冗余(REDUNDANT)和备份(BAKUP)两种机制。
RAID和MIRROR和最常见的存储冗余的实现方式,可以容忍介质故障等问题。
备份测试可以在错误操作或者文件系统故障时,很容易的恢复数据。
3 数据恢复策略
3.1 数据恢复基本步骤
由于存储故障是无法完全避免的,在出现故障的时候,需要考虑如下的几个基本策略和步骤:
分析故障,通过分析用户手册,分析系统LOG,检查系统状态等方式定位和分析问题
在问题没有定位之前,不可以对存储系统作更改操作
在分析问题之后,必须通过模拟系统测试恢复策略的可行性和风险
寻求专业帮助,通过mail list,BBS,付费支持等方式获取专业的指导
3.2 数据恢复方法
3.2.1 硬件故障处理
检查硬盘,数据线,连接部位,电源等问题
检查Fimware版本,分析对应的Changelog
磁盘坏扇区,使用二进制的操作执行备份,例如dd命令
3.2.2 磁盘分区故障
检查驱动和内核版本
通过fdisk ,diskpart, partprobe,gpart等工具分析分区信息
检查磁盘和分区大小,blockdev,fdisk,sysfs等工具
3.2.3 RAID故障
分析RAID中device,raidset和volume的信息
查看RAID的配置文件的信息
尽可能的分析RAID的元数据信息
3.2.4 元数据
元数据是指数据的组织结构。通常,有两种方式存储:
(1)在磁盘上,通常在硬盘的最前面或者最后面预留扇区用于存储元数据
(2)在配置文件中保存必要的信息
在执行数据恢复的时候,通常需要先修复元数据再修复数据。
4 LVM数据恢复
4.1 LVM基础
4.1.1 LVM的架构
图(2)LVM基础架构
如果所示为Linux Volume Management系统的基础架构,由PV,VG和LV组成。
4.1.2 LVM的on-disk PV结构
PV的基本结构如下:
(1)标签,占用一个sector,包括签名,UUID,元数据的位置指针
(2)元数据:占用多个sector
a) 真正元数据的指针
b) 循环缓存,文本格式
c) 原子更新操作
d) 序列号
e) 校验码,冗余信息,自动修复信息等
图(3)LVM的PV结构
4.1.3 LVM的文本元数据配置
如下为一个/etc/lvm/backup/pool的配置实例:
# Generated by LVM2 version 2.02.42 (2008-10-26): Sat Sep 25 17:36:30 2010 contents = "Text Format Volume Group" version = 1 description = "Created *after* executing 'lvcreate --name block --size 300G pool'" creation_host = "zhuweiR30" # Linux zhuweiR30 2.6.28-storix #1 SMP Thu Dec 24 17:25:02 CST 2009 i686 creation_time = 1285407390 # Sat Sep 25 17:36:30 2010 pool { id = "0Lm9dz-sIeu-t2Ho-qIBR-lD2P-dcbK-K1U4zW" seqno = 2 status = ["RESIZEABLE", "READ", "WRITE"] flags = [] extent_size = 8192 # 4 Megabytes max_lv = 0 max_pv = 0 physical_volumes { pv0 { id = "rewaTQ-vKaK-PzWs-H14L-a2Qz-hV62-CcIHqT" device = "/dev/sdb" # Hint only status = ["ALLOCATABLE"] flags = [] dev_size = 21484367872 # 10.0044 Terabytes pe_start = 384 pe_count = 2622603 # 10.0044 Terabytes } } logical_volumes { block { id = "ryg1Or-e1C3-ooKV-0XMM-jKSN-g0EM-dXky7G" status = ["READ", "WRITE", "VISIBLE"] flags = [] segment_count = 1 segment1 { start_extent = 0 extent_count = 76800 # 300 Gigabytes type = "striped" stripe_count = 1 # linear stripes = [ "pv0", 0 ] } } } }
|
4.1.4 LVM元数据备份
LVM元数据通过默认备份在/etc/lvm目录下,可以通过工具vgcfgbackup和vgcfgrestore命令备份和恢复元数据。
4.2 LVM PV故障的修复实例
4.2.1 部分修复
检查系统的所有的LVM的VG信息
# vgscan
Reading all physical volumes. This may take a while...
Couldn't find device with uuid 'DHmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp'.
Found volume group "vg_test" using metadata type lvm2
检查丢失的设备上的信息
#pvs -o +uuid
Couldn't find device with uuid 'DhmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp'.
PV VG Fmt Attr PSize PFree PV UUID
/dev/sdb vg_test lvm2 a- 200.00m 0 5KjGmZ-vhc6-u62q-YcSZ-aKX0-bCYP-EXtbzd
unknown device vg_test lvm2 a- 200.00m 0 DHmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp
# lvs -o +devices
Couldn't find device with uuid 'DHmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp'.
LV VG Attr LSize Devices
lv1 vg_test -wi--- 100.00m /dev/sdb(0)
lv2 vg_test -wi--- 100.00m unknown device(0)
lv3 vg_test -wi--- 200.00m /dev/sdb(25)
lv3 vg_test -wi--- 200.00m unknown device(25)
在这种情况下,lv1正常,lv2丢失,lv3部分丢失
激活
# vgchange -a y vg_test
Couldn't find device with uuid 'DHmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp'.
Refusing activation of partial LV lv2. Use --partial to override.
Refusing activation of partial LV lv3. Use --partial to override.
1 logical volume(s) in volume group "vg_test" now active
对应—partial 参数,丢失的部分使用配置/etc/lvm.conf中的Missing_stripe_filler=”error” 指定的设备来补充
尝试部分修复
准备zero设备
# dmsetup create zero_missing --table "0 10000000 zero"
修复配置文件
missing_stripe_filler = "/dev/mapper/zero_missing"
# vgchange -a y vg_test --partial
...
3 logical volume(s) in volume group "vg_test" now active
移除丢失硬盘上的所有的LV
# vgreduce --removemissing vg_test
Couldn't find device with uuid 'DHmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp'.
WARNING: Partial LV lv2 needs to be repaired or removed.
WARNING: Partial LV lv3 needs to be repaired or removed.
WARNING: There are still partial LVs in VG vg_test.
To remove them unconditionally use: vgreduce --removemissing --force.
Proceeding to remove empty missing PVs.
# vgreduce --removemissing vg_test --force
Couldn't find device with uuid 'DhmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp'.
...
Wrote out consistent volume group vg_test
完成数据修复
# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb vg_test lvm2 a- 200.00m 100.00m
# lvs -o +devices
LV VG Attr LSize Devices
lv1 vg_test -wi--- 100.00m /dev/sdb(0)
4.2.2 通过备份恢复
如果在某些情况下,
提示“操作错误”的情况
# vgscan
Reading all physical volumes. This may take a while...
WARNING: Inconsistent metadata found for VG vg_test - updating to use version 18
Removing PV /dev/sdc (DHmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp) that no longer belongs
to VG vg_test
Found volume group "vg_test" using metadata type lvm2
# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb vg_test lvm2 a- 200.00m 100.00m
/dev/sdc lvm2 -- 204.00m 204.00m
通过恢复配置还原
# vgcfgrestore -f /etc/lvm/archive/vg_test_01564.vg vg_test
Cannot restore Volume Group vg_test with 1 PVs marked as missing.
Restore failed.
手工修改配置
...
pv1 {
id = "DHmMDP-bqQy-TalG-2GLa-sh6o-fyVW-3XQ3gp"
device = "unknown device"
flags = ["MISSING"]
...
再次恢复
# vgcfgrestore -f vg_test_edited.vg vg_test
Restored volume group vg_test
5 小结
本文分析了存储故障参数的原因,提出了数据恢复的测试和实施步骤,并且针对常见的LVM的故障,分析了LVM的架构和元数据的组织结构,最后给出了LVM故障的常见修复方法和实例分析。
但是,数据恢复本身只是在出现存储故障之后的修补措施,修复成功的可能性也不是100%。因此,在部署存储系统的时候,考虑冗余和备份是提高数据安全性的更好的版本。