LVM:我应该如何尝试从 PV 和可能的 LV 损坏中恢复?

LVM:我应该如何尝试从 PV 和可能的 LV 损坏中恢复?

这是我的家庭文件存储设置。它没有备份,因为 RAID 设置旨在实现冗余。我没有考虑到发生了什么,并为此付出了代价。设置:

  • Ubuntu 16.04
  • 使用 mdadm 的四磁盘 RAID 5 阵列(4x2TB):/dev/md0
  • 在阵列上,由 LVM 管理的 PV 和 LV。
  • 在名为 vg0 的逻辑卷上,有一个 XFS 文件系统。

请注意,Linux 主机(包括 /etc 和 /boot)安装在不同的磁盘上,并且完全可访问(因此我可以访问 /etc/lvm/archive)。RAID 阵列纯粹是文件存储,除了 /etc/fstab 中的条目外,启动过程完全不依赖于它。

不管出于什么原因,我从一个令我费解的 FreeDOS 安装程序启动。我想我可能告诉它重新分区这个卷,尽管我不记得这样做过。无论如何,当我重新启动进入 Linux(Ubuntu 16.04)时,我以 root 用户身份进入恢复模式提示。它无法挂载 /etc/fstab 中定义的卷组的 UUID。

自从我最初设置这个 RAID 阵列以来,已经过去了很长时间,我完全忘记了 LVM 是如何工作的,或者我甚至使用 LVM 来创建卷。(10-12 年,在此期间偶尔更换硬盘并调整阵列大小。)所以,我首先尝试使用 testdisk [1] 来查找和恢复分区信息。这从来没有奏效,分区的大小总是不正确(524Gb 而不是 4.5TB),而且从来都不是“物理扇区边界”。我尝试了各种几何图形,认为有一个神奇的组合可以完美地恢复分区。以下是根据 fdisk 显示的磁盘的当前状态:

$ sudo fdisk -l /dev/md0
GPT PMBR size mismatch (1098853631 != 200894463) will be corrected by w(rite).
Disk /dev/md0: 4.1 TiB, 4500904476672 bytes, 8790829056 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 1048576 bytes / 3145728 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start        End    Sectors  Size Id Type
/dev/md0p1          1 1098853631 1098853631  524G ee GPT

Partition 1 does not start on physical sector boundary.

然后分开了:

(parted) print list                                                       
Error: /dev/md0: unrecognised disk label
Model: Linux Software RAID Array (md)                                     
Disk /dev/md0: 4501GB
Sector size (logical/physical): 512B/4096B
Partition Table: unknown
Disk Flags: 

在 testdisk 论坛上发帖提问时 [2],我意识到我使用 LVM 来管理 RAID 阵列,并且这些阵列可能根本不使用传统的分区工具。研究“恢复 lvm 物理卷”发现了http://blog.adamsbros.org/2009/05/30/recover-lvm-volume-groups-and-logical-volumes-without-backups/.pvck 告诉我以下内容:

$ sudo pvck /dev/md0
  Incorrect metadata area header checksum on /dev/md0 at offset 4096
  Found label on /dev/md0, sector 1, type=LVM2 001
  Found text metadata area: offset=4096, size=192512
  Incorrect metadata area header checksum on /dev/md0 at offset 4096

我还在 /etc/lvm/archives 中保存了多个 LVM 卷的备份,最新的备份如下:

crw@bilby:~$ sudo cat /etc/lvm/archive/vg0_00002-935168089.vg
# Generated by LVM2 version 2.02.98(2) (2012-10-15): Sun Jul 19 12:00:04 2015

contents = "Text Format Volume Group"
version = 1

description = "Created *before* executing 'lvextend /dev/vg0/lv0 /dev/md0'"

creation_host = "bilby" # Linux bilby 3.16.0-43-generic #58~14.04.1-Ubuntu SMP Mon Jun 22 10:21:20 UTC 2015 x86_64
creation_time = 1437332404  # Sun Jul 19 12:00:04 2015

vg0 {
    id = "Q4ZRRc-1l0h-FEgu-jrxA-EfW1-tAis-vv0jyL"
    seqno = 5
    format = "lvm2" # informational
    status = ["RESIZEABLE", "READ", "WRITE"]
    flags = []
    extent_size = 262144        # 128 Megabytes
    max_lv = 0
    max_pv = 0
    metadata_copies = 0

    physical_volumes {

        pv0 {
            id = "bKQs0l-zNhs-X4vw-NDfz-IMFs-cJxs-y0k6yG"
            device = "/dev/md0" # Hint only

            status = ["ALLOCATABLE"]
            flags = []
            dev_size = 8790828672   # 4.09355 Terabytes
            pe_start = 384
            pe_count = 33534    # 4.09351 Terabytes
        }
    }

    logical_volumes {

        lv0 {
            id = "pqInOe-ZLpV-t9oK-GQE1-AoIt-mB3M-4ImaV1"
            status = ["READ", "WRITE", "VISIBLE"]
            flags = []
            segment_count = 1

            segment1 {
                start_extent = 0
                extent_count = 22356    # 2.729 Terabytes

                type = "striped"
                stripe_count = 1    # linear

                stripes = [
                    "pv0", 0
                ]
            }
        }
    }
}

如果有帮助的话,以下是有关 RAID 阵列的详细信息:

$ sudo mdadm --detail /dev/md0
/dev/md0:
        Version : 0.90
  Creation Time : Sun Oct 11 13:34:16 2009
     Raid Level : raid5
     Array Size : 4395414528 (4191.79 GiB 4500.90 GB)
  Used Dev Size : 1465138176 (1397.26 GiB 1500.30 GB)
   Raid Devices : 4
  Total Devices : 4
Preferred Minor : 0
    Persistence : Superblock is persistent

    Update Time : Mon Oct  3 13:12:51 2016
          State : clean 
 Active Devices : 4
Working Devices : 4
 Failed Devices : 0
  Spare Devices : 0

         Layout : left-symmetric
     Chunk Size : 1024K

           UUID : 9be3b2f7:102e373a:822b5a8f:216da2f7 (local to host bilby)
         Events : 0.103373

    Number   Major   Minor   RaidDevice State
       0       8       64        0      active sync   /dev/sde
       1       8       48        1      active sync   /dev/sdd
       2       8       16        2      active sync   /dev/sdb
       3       8       32        3      active sync   /dev/sdc

最后,这是我留下的testdisk.log的悲伤痕迹:https://dl.dropboxusercontent.com/u/2776730/testdisk.log

编辑: lsblk 的输出:

crw@bilby:~$ sudo lsblk
NAME                 MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                    8:0    0 59.6G  0 disk  
├─sda1                 8:1    0  243M  0 part  /boot
├─sda2                 8:2    0    1K  0 part  
└─sda5                 8:5    0 59.4G  0 part  
  ├─bilby--vg-root   252:0    0 43.4G  0 lvm   /
  └─bilby--vg-swap_1 252:1    0   16G  0 lvm   [SWAP]
sdb                    8:16   0  1.8T  0 disk  
└─md0                  9:0    0  4.1T  0 raid5 
sdc                    8:32   0  1.8T  0 disk  
└─md0                  9:0    0  4.1T  0 raid5 
sdd                    8:48   0  1.8T  0 disk  
└─md0                  9:0    0  4.1T  0 raid5 
sde                    8:64   0  1.8T  0 disk  
└─md0                  9:0    0  4.1T  0 raid5 

我完全不知所措,怀疑自己把事情弄得更糟了。我的问题是:

在处理 LVM 问题之前,我需要“修复”分区信息吗?我应该尝试“pvcreate --uuid xxx --restorefile yyy”吗?然后我是否需要扩展磁盘,并运行类似于 xfs 的 fsck 之类的程序?或者此时我的数据已经丢失了?:'(

如果我可以添加任何内容来简化此问题的调试,请告诉我。谢谢!

答案1

如果其中任何一项开始不起作用或不再有意义,请停止并咨询主题专家。这是不安全的工作。对通过“dd”复制到大型存储介质上的文件或直接复制到大小相等或更大的新磁盘的磁盘映像进行操作,以保护您的原始数据集免受愚蠢行为的侵害。您可以在单个实时集上执行这些操作,但如果您搞砸了,您的数据就可能完蛋了。

好的。首先,我们需要从基础磁盘级别开始,有条不紊地修复此存储堆栈。您运行了 FreeDOS 安装程序,它(可能)在其中一个磁盘上创建了分区表,从而弄乱了您的磁盘。

您的磁盘直接参与 MD 阵列,无需分区表。这是相当典型的。但是,这也是该阵列上的 0.90 修订版元数据结构,因此直接将分区表放在这些磁盘中的任何一个上都会扰乱阵列。

检查是否有磁盘(从 sdb 到 sde 的任何磁盘)上有分区表,例如 /dev/sdb1 格式。如果有这样的磁盘,则需要将其视为脏磁盘并将其从阵列中取出,在删除该表后再将其放回阵列中。

即使我们在其中一个磁盘上看不到分区,也需要在 /dev/md0 上运行完整性检查。执行此操作的命令很简单:

# /usr/share/mdadm/checkarray -a /dev/mdX

如果返回的不匹配计数大于零,则必须修复该阵列。如果需要,我们会检查该问题,因为目前看来这不是问题所在。

再说说更具体的问题,testdisk 在 /dev/md0 上放置了一个 GPT,并在该磁盘上放置了一个分区 (/dev/md0p1)。这本来不应该存在,而且会破坏您的 LVM 元数据。您的卷组应该直接位于 /dev/md0 上,因为您最初就是这么创建的。

首先,我们必须处理 /dev/md0 上的错误 GPT。它需要被“清除”。清除 GPT 将清空所有 GPT 结构,将其返回到没有表的磁盘,正如本例中应该的那样。这篇文章对此进行了详尽的说明:“http://www.rodsbooks.com/gdisk/wipegpt.html”。如果您不清除它,那么该磁盘上的 GPT 结构将损坏,分区实用程序将尝试“纠正”,从而再次给您带来问题。

完成此操作后,您现在可以使用问题中发布的存档文件重新创建所有 LVM 元数据。谢天谢地,您已经给了我足够的信息,只需向您提供一条可用的命令即可。如果您想了解有关此过程的更多信息,这是一个很好的资源:“https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Logical_Volume_Manager_Administration/mdatarecover.html”。

使用其所有原始元数据重新创建物理卷的命令:

# pvcreate --uuid "bKQs0l-zNhs-X4vw-NDfz-IMFs-cJxs-y0k6yG" --restorefile /etc/lvm/archive/vg0_00002-935168089.vg

此存档文件将 /dev/md0 描述为构成卷组的磁盘,并将按预期使用该磁盘。如果您的 LVM 存档目录中有较新的存档文件,请使用该文件。目标是使卷组处于其最新的有效状态。

恢复 PV 后,接下来恢复 VG 和 LV(在 PV 上):

# vgcfgrestore vg0

在此之后,检查 PV、VG 和 LV 的完整性是关键。您已经尝试过此操作,但这次应该提高工作效率。这里应该使用命令pvck和。vgck

首先执行pvck:

# pvck /dev/md0

验证后,运行 vgck:

# vgck vg0

验证所有元数据后,就该激活您的 LV 了(如果尚未激活):

# vgchange -ay vg0

最后,检查 /dev/mapper/vg0-lv0 上的文件系统(在您的情况下是 XFS)是否存在潜在错误:

# xfs_check /dev/mapper/vg0-lv0

如果没有错误,则不会返回任何内容。如果出现问题,则需要 xfs_repair(请勿在安装时执行此操作):

# xfs_repair /dev/mapper/vg0-lv0

相关内容