LVM 介绍
LVM 简介
LVM 是逻辑盘卷管理(Logical Volume Manager)的简称,最早是 IBM 为 AIX 研发的存储管理机制。LVM 通过在硬盘和分区之间建立一个逻辑层,可以让多个分区或者物理硬盘作为一个逻辑卷 ( 相当于一个逻辑硬盘 ),提高了磁盘分区管理的灵活性。1998 年,Heinz Mauelshagen 在 Linux 2.4 内核上提供了 Linux 的 LVM 实现。目前 Linux 2.6 内核支持 LVM2,Redhat 官方网站目前提供最新可下载版本为 2.2.02.77;如果需要最新或者其它版本,请参考网页。
LVM 早期多用于服务器,配合存储硬件的 Raid 技术,提供高可靠性,可灵活配置的磁盘分区管理;普通 PC 由于存储容量有限,很少使用这种技术。随着单个磁盘容量的不断扩大和硬盘价格的下降,普通 PC 拥有 TB 级的大容量存储空间逐渐普及,也带来对 PC 上存储管理的需要,LVM 无疑是很好的解决方案。只是普通 PC 用户由于缺少硬件冗余保护,在发生灾难时,通常会发生比较严重的数据损失。好在 LVM 提供了一系列灾难恢复的功能,可以帮助普通 PC 用户尽可能减少损失。
我们可以通过下面的命令检查系统中是否安装了 lvm 工具:
rpm -qa | grep lvm lvm2-2.02.56-8.el5_5.4 |
上例系统安装了 2.02.56 版本的 LVM。
LVM 的基本概念 pv/lv/vg/vgda
硬盘存储设备进行管理 , 相关的概念和命令相对多,下面我们对 LVM 的相关名词进行解释以方便读者更好理解。
物理卷 physical volumes(PV)
物理卷处于逻辑卷管理器中的底层,任何的逻辑卷和卷组都必需依靠物理卷来建立;物理卷可以是一个完整的硬盘,也可以是硬盘中的一个分区,并有一个名字 ( 如 hdisk0)。
逻辑卷 logical volumes (LV)
逻辑卷建立在卷组之上,卷组中的空间可以建立多个逻辑卷,并且逻辑卷可以随意在卷组的空闲空间中增减,逻辑卷可以属于一个卷组,也可以属于不同的多个卷组。LV 是位于 PV 上的信息的组合,在 LV 上的数据可以连续或者不连续地出现在 PV。
卷组 logical volume group(VG)
卷组是建立在物理卷之上,一个卷组中可以包含一个物理卷组或者多个物理卷。所有的物理卷属于一个称作 rootvg 的卷组。
卷组描述区域 Volume Group Descriptor Area (VGDA)
用于描述物理卷、卷组、逻辑卷分配的所由信息。和非 LVM 系统将包含分区信息的元数据保存在位于分区的起始位置的分区表中一样,逻辑卷以及卷组相关的元数据也是保存在位于物理卷起始处的 VGDA( 卷组描述符区域 ) 中。
LVM 灾难修复基本思路
灾难的类型
文件系统灾难一般可以分为两类——人为灾难和自然灾难。人为灾难主要是人为操作导致的数据丢失,分区损坏,分区表损坏等等,自然灾难主要是由于事故、意外事件或者自然损耗导致的磁盘坏道,磁盘损坏,相关硬件损坏导致的磁盘位置调整等等。
由于 LVM 和普通文件系统的硬件环境并没有什么区别,所以他们所面对的自然灾难类型也是一致的。但是对于 LVM 而言,通过虚拟化存储管理带来分区容量动态调整便利的同时,也带来了一些 LVM 特有的人为灾难。如第一章所说,LVM 将所有磁盘创建为物理卷置于卷组中统一管理,然后创建逻辑卷供操作系统调用,这也就导致可能出现卷组损坏,逻辑卷损坏,物理卷损坏等灾难。
修复的策略
对于企业用户而言,通常会制定严格的操作规章制度来和完备的备份策略来抵御人为灾难,还有完整的硬件冗余方案来对抗自然灾难;对于普通用户而言,一般都不具备这种客观条件来防范灾难。一旦发生灾难,我们所要做的是尽量减少灾难的影响,尽可能恢复灾难所造成的数据损失。
对于 LVM 的人为灾难恢复而言,LVM 本身提供了数据备份和配置信息备份的工具,可以充分利用这些工具进行备份,在发生人为灾难导致物理卷错误,逻辑卷错误和卷组错误的时候,利用备份进行恢复,尽可能恢复灾难所导致的数据损失。
由于 LVM 将所有磁盘进行统一管理,磁盘损坏会导致整个文件系统不可使用,因为自然恢复的主要目标是在灾难发生后恢复 LVM 的可用性,恢复正常磁盘上的可用数据。LVM 本身提供了一套工具,用户可以通过这套工具解决绝大多数由于硬件故障导致的 LVM 不可用的问题,在自然灾难发生后尽可能恢复 LVM 的可用性。在某些情况下,由于人为灾难造成 LVM 发生卷组、物理卷或者逻辑卷不一致的情况,进而导致部分逻辑卷、甚至整个卷组无法访问的情况,修复此类问题也可以通过上述工具来进行。
LVM 的灾难恢复
本节将结合具体灾难,演示如何进行 LVM 灾难恢复。为了便于演示,我们假设试验环境如下:基于 X86 架构的 PC,除硬盘外所有硬件均能正常稳定的工作,PC 上安装了 2 块磁盘 Disk-A 和 Disk-B。
逻辑卷损坏
硬盘的逻辑损坏的原因往往是多种多样的,可能是误操作,可能是不正常掉电,也可能是病毒甚至汇编语言的 diskkiller 直接造成。但这些损坏大都并非是不可逆的,下面我们就将在实验用 PC 上模拟一些常见的错误并进行恢复操作。
先来看看当前的磁盘及文件系统状况:
linux-c3k3:~ # pvs PV VG Fmt Attr PSize PFree /dev/sdb system lvm2 a- 2.00G 92.00M /dev/sdc system lvm2 a- 2.00G 0 linux-c3k3:~ # vgs VG #PV #LV #SN Attr VSize VFree system 2 1 0 wz--n- 4.00G 92.00M linux-c3k3:~ # lvs -o +devices LV VG Attr LSize Origin Snap% Move Log Copy% Devices alpha system -wi-ao 3.90G /dev/sdc(0) alpha system -wi-ao 3.90G /dev/sdb(0) linux-c3k3:~ # mount |grep '/dev/mapper' /dev/mapper/system-alpha on /alpha type reiserfs (rw,acl,user_xattr) |
接着我们将模拟一些错误情况:
情况 1: 文件系统正常,硬盘无物理故障的状况
在这之前我们先确认一些状况,请确认你的 root 分区不在 lvm 的管理范围内,否则一旦 lvm 系统出现故障,整个系统将无法启动,虽然通过光盘 rescure 模式启动可以进行一定的操作,但会造成很多不必要的麻烦。如果在平时的使用中你已经将 root 分区置于 lvm 管理之下,那么请定期备份 /etc/lve/backup/ 下的文件用以系统恢复,否则即使硬盘没有物理损坏,而只是 lvm 逻辑标签对应错误,你的数据也很有可能救不回来了。当然,即使 root 分区不在 lvm 的管理范围内,定期备份该目录也是一个很好的习惯
linux-c3k3:~ # pvcreate -ff /dev/sdb Really INITIALIZE physical volume "/dev/sdb" of volume group "system" [y/n]? y Can't open /dev/sdb exclusively. Mounted filesystem? |
可以看到 pvcreate 拒绝对那些上面有逻辑卷的 pv,如果要执行该操作的话需要把上面的逻辑卷删除,该命令后面将会用到。
现在我们用 dd 命令擦除 sdb 对应 lvm2 的标签但保留分区表(操作有一定风险,请谨慎尝试)
linux-c3k3:~ # dd if=/dev/zero f=/dev/sdb bs=512 count=1 seek=1 1+0 records in 1+0 records out 512 bytes (512 B) copied, 9.8e-05 seconds, 5.2 MB/s linux-c3k3:~ # pvs --partial Partial mode. Incomplete volume groups will be activated read-only. Couldn't find device with uuid '7m0QBR-3kNP-J0fq-GwAq-iv6u-LQkF-yhJh5R'. Couldn't find device with uuid '7m0QBR-3kNP-J0fq-GwAq-iv6u-LQkF-yhJh5R'. Couldn't find device with uuid '7m0QBR-3kNP-J0fq-GwAq-iv6u-LQkF-yhJh5R'. ...... PV VG Fmt Attr PSize PFree /dev/sdc system lvm2 a- 2.00G 0 unknown device system lvm2 a- 2.00G 92.00M linux-c3k3:~ # vgs --partial Partial mode. Incomplete volume groups will be activated read-only. Couldn't find device with uuid '7m0QBR-3kNP-J0fq-GwAq-iv6u-LQkF-yhJh5R'. ...... VG #PV #LV #SN Attr VSize VFree system 2 1 0 rz-pn- 4.00G 92.00M linux-c3k3:~ # lvs --partial Partial mode. Incomplete volume groups will be activated read-only. Couldn't find device with uuid '7m0QBR-3kNP-J0fq-GwAq-iv6u-LQkF-yhJh5R'. ...... LV VG Attr LSize Origin Snap% Move Log Copy% alpha system -wi-ao 3.90G |
从上面的情况我们不难看出 sdb 已经变成了未知设备,卷组的 metadata 变成只读的了,且是 partial 的状态,但 lv 的情况还是基本正常的。
其实,在这种情况下,还是可以挂载、访问故障的文件系统的,毕竟分区表本身并没有损坏。于是我们首先要做的无疑是备份(最好以只读方式挂载)
清单 5. 以只读方式挂载并备份
linux-c3k3:~ # mount -o remount -o ro /alpha
(备份操作略)
下面我们来尝试修复
* 如果出现 Can't open /dev/sdb exclusively. Mounted filesystem? 的情况请先 deactive 你的 vg linux-c3k3: ~ # pvcreate -ff --uuid 7m0QBR-3kNP-J0fq-GwAq-iv6u-LQkF-yhJh5R \n --restorefile /etc/lvm/backup/system /dev/sdb Couldn't find device with uuid '7m0QBR-3kNP-J0fq-GwAq-iv6u-LQkF-yhJh5R '. Physical volume "/dev/sbd" successfully created linux-c3k3:~ # pvs PV VG Fmt Attr PSize PFree /dev/sdb system lvm2 a- 2.00G 92.00M /dev/sdc system lvm2 a- 2.00G 0 * 恢复成功,然后我们继续对卷组进行恢复 linux-c3k3: ~ # vgcfgrestore -f /etc/lvm/backup/system system Restored volume system * 卷组完成恢复,然后激活后查看 linux-c3k3: ~ #vgchange – ay system 1 logical volume(s) in volume group "system" now active |
到此处为止,你会发现,一切正常了,数据也没有任何的损失,但为了保险起见还是应该尝试进行一下文件系统扫描以确保万无一失。
回头看我们前面提到的如果 root 分区在 lvm 管理下的情况,会出现系统无法启动的情况,这时候怎么办呢?
其实也不是无法解决的,是用操作系统盘引导,进入 Rescure 模式,利用你之前备份的 /etc/lve/backup/ 下的文件进行恢复即可,如果你需要先启动起原本的系统以取出备份文件,可以使用 vgreduce – removemissing system 命令去掉丢失标签的物理磁盘再启动,而后利用备份文件执行恢复操作,但是每次正常的 lvm 启动都会更改 /etc/lve/backup/ 下的内容,这也是为什么我们需要对其内容进行备份的原因。如果很不幸的你没有备份 /etc/lve/backup/ 下的内容,且 root 分区在 lvm 管理下的情况,那么很遗憾,即使你的硬盘没有物理损毁,你的数据也很难救回了,针对这种情况向系统的恢复方法,请参照 3.4 磁盘损坏 部分进行操作。
情况 2:PV 的损坏与替换
先看一下系统的情况
(none):/test # pvs PV VG Fmt Attr PSize PFree /dev/sda2 system lvm2 a- 7.93G 0 /dev/sdb test lvm2 a- 2.00G 0 /dev/sdc test lvm2 a- 2.00G 0 /dev/sdd lvm2 -- 2.00G 2.00G (none):/test # vgs VG #PV #LV #SN Attr VSize VFree system 1 2 0 wz--n- 7.93G 0 test 2 1 0 wz--n- 3.99G 0 (none):/test # lvs LV VG Attr LSize Origin Snap% Move Log Copy% root system -wi-ao 7.38G swap system -wi-ao 560.00M lv0 test -wi-ao 3.99G (none):/test # (none):/ # mount /dev/test/lv0 /test/ (none):/ # ls /test doc.txt (none):/ # umount /test |
我们在 lv0 下存储了一个文件
备份一下 /etc/lvm/backup 的文件
(none):/etc/lvm/backup # cp * /testback/ |
我们用 dd 命令把 /dev/sdc 的前 400 个扇区都清零(包括 LVM2 label、meta. data、分区表等)
(none):/ # dd if=/dev/zero f=/dev/sdc bs=512 count=400 400+0 records in 400+0 records out 204800 bytes (205 kB) copied, 0.046619 seconds, 4.4 MB/s (none):/ # pvs --partial Partial mode. Incomplete volume groups will be activated read-only. Couldn't find device with uuid 'noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO'. Couldn't find device with uuid 'noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO'. Couldn't find device with uuid 'noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO'. Couldn't find device with uuid 'noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO'. Couldn't find device with uuid 'noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO'. Couldn't find device with uuid 'noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO'. PV VG Fmt Attr PSize PFree /dev/sda2 system lvm2 a- 7.93G 0 /dev/sdb test lvm2 a- 2.00G 0 /dev/sdd lvm2 -- 2.00G 2.00G unknown device test lvm2 a- 2.00G 0 |
这种情况下想要完全恢复可能比较困难了,如果无意找回还可能存在的数据,请参照 3.4 磁盘损坏 部分进行操作。如想尽可能多的找回数据,请先尝试 mount,
(none):~ # mount /dev/test/lv0 /test mount: you must specify the filesystem type |
文件系统已经损坏 .
这里我们尝试进行替换,以 sdd 替换 sdc
(none):/ # pvcreate --restorefile /etc/lvm/backup/test \n --uuid noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO /dev/sdd Couldn't find device with uuid 'noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO'. Physical volume "/dev/sdd" successfully created. (none):/ # pvs -v Scanning for physical volume names Wiping cache of LVM-capable devices PV VG Fmt Attr PSize PFree DevSize PV UUID /dev/sda2 system lvm2 a- 7.93G 0 7.93G HsErSz-vuAD-rEe1-wE5m-Mnvr-T0Re-EwO7rD /dev/sdb test lvm2 a- 2.00G 0 2.00G OBb3qb-TW97-hKZ7-vmsr-RZ2v-fzuP-qK3wmN /dev/sdd test lvm2 a- 2.00G 0 2.00G noOzjf-8bk2-HJhC-92fl-2f6Q-DzNZ-XBqnBO |
我们可以看到 sdd 已经替换了 sdc
不过这时候 /etc/lvm/backup 下的文件并不会更新,同时会看到如下的情况
(none):/ # vgchange -an test Volume group test metadata is inconsistent Volume group for uuid not found: tcyuXvjcxCN7912qAJlEYzphncdWabTJ21OTTrG6DrMS8dPF5Wlh04GOHyO5ClbY 1 logical volume(s) in volume group "test" now active * 即报告 vg 的 metadata 不一致 * 重新启动系统 (none):~ # vgchange -an test 0 logical volume(s) in volume group "test" now active (none):~ # vgchange -ay test 1 logical volume(s) in volume group "test" now active |
之后尝试 mount
(none):~ # mount /dev/test/lv0 /test mount: you must specify the filesystem type |
我们开始尝试修复文件系统
经过
reiserfsck /dev/test/lv0 --check reiserfsck /dev/test/lv0 --rebuild-sb reiserfsck /dev/test/lv0 --check reiserfsck /dev/test/lv0 --rebuild-tree reiserfsck /dev/test/lv0 - – check |
命令之后(实际需要执行的情况依据硬盘受损情况可能有所不同)
(none):~ # mount /dev/test/lv0 /test (none):~ # cd /test (none):/test # ls doc.txt .doc.txt.swp lost+found (none):/test # |
很幸运,我们的文件还在。
磁盘坏道
硬盘长时间的使用,非正常操作或电源管理失误都可能造成磁盘坏道的产生。最典型的症状就是一旦对硬盘的某一部分进行操作,就会出现整个硬盘停止工作,如果操作系统也在该硬盘上,那么系统立即崩溃也就成为了必然。这还不是最可怕的,因为坏道一旦产生就有扩散的可能,每次触及,导致的 crash 都比一次系统非正常掉电造成的伤害更为严重,除了坏道的扩散外还很有可能破坏整块硬盘的动平衡,从而导致整个硬盘不可恢复的物理性损坏。可见,及时发现硬盘坏道,并尽早处理是十分必要的。
LVM 自己本身其实有一套对坏道的处理机制:
- 硬盘内部的数据重定位:最底层的重定位,发生在磁盘内部,出现的时候不会通知用户。
- 由 LVM 产生的硬件重定位:更高层次的重定位,LVM 将有问题的物理地址 A 上的数据拷贝到物理地址 B,LVM 会继续读地址 A 上的数据,但是硬盘已经将真实的 IO 转向物理地址 B。
- 软件重定位:最高层次的重定位,也由 LVM 设备产生。LVM 生成一个坏道表,当读物理地址 A 上的数据时,先检查坏道表,如果 A 在坏道表中,就转向物理地址 B。
但以上这些,其实对用户都是透明的,用户可以在创建 lv 时通过 lvcreate – r n 参数关闭这样,系统将不创建坏块重定位区域(BBRA),引导、根和主交换逻辑卷必须使用此参数。当用户觉得 LVM 有问题的时候,首先要做的事情就是备份,尽可能地保存卷组中的数据。卷组发生问题后进行的备份需要和发生问题前进行的备份进行对比。针对存在坏道的情况,fsck 一定要慎用,尤其对于重定位已经无法处理的应尽快将硬盘导出(操作见 3.3 磁盘位置更改部分)LVM 以防坏道扩散,如在导出过程中出现问题,请比照 3.4 磁盘损坏处理。
磁盘位置更改
主板端口损坏、更欢 PC 主板、添加新的设备都可能导致磁盘位置更改的发生。由于 Linux 的主引导记录(MBR)一般记录在第一块磁盘的第一个扇区上,如果第一块磁盘的顺序发生改变,会导致系统无法启动。对于这种情况,只需要调整磁盘顺序就可以解决(只需要保证有 MBR 的磁盘排在第一顺位就可以,不一定是总线的第一个端口)。这里讨论两种比较常见的情况,磁盘在系统内位置更改和磁盘在系统间移动。
磁盘在系统内移动
对于单一卷组的 LVM 文件系统而言,LVM 能够自动识别出磁盘位置的更改。磁盘位置更改后,正常启动系统就可以正常访问了。当系统中存在单独的卷组,或者系统中存在多个卷组是,更改磁盘位置前需要停用卷组,在完成磁盘移动后需要重新激活卷组,执行操作如下: