如何恢复崩溃的 Linux md RAID5 阵列?

str*_*ika 18 linux software-raid data-recovery raid5

前段时间我家里有一个RAID5系统。4 个磁盘中的一个出现故障,但在移除并放回后似乎没问题,所以我开始重新同步。当它完成时,我惊恐地意识到 4 个磁盘中有 3 个出现故障。但是我不相信这是可能的。磁盘上有多个分区,每个分区是不同 RAID 阵列的一部分。

  • md0 是由 sda1、sdb1、sdc1 和 sdd1 组成的 RAID1 阵列。
  • md1 是由 sda2、sdb2、sdc2 和 sdd2 组成的 RAID5 阵列。
  • md2 是由 sda3、sdb3、sdc3 和 sdd3 组成的 RAID0 阵列。

md0 和 md2 报告所有磁盘已启动,而 md1 报告 3 个失败(sdb2、sdc2、sdd2)。我的理解是,当硬盘驱动器出现故障时,所有分区都应该丢失,而不仅仅是中间的分区。

那时我关闭了计算机并拔掉了驱动器。从那时起,我使用那台计算机和一个较小的新磁盘。

有没有希望恢复数据?我能以某种方式说服 mdadm 我的磁盘实际上在工作吗?唯一可能真正有问题的磁盘是 sdc,但其他阵列也报告了该磁盘。

更新

我终于有机会连接旧磁盘并从 SystemRescueCd 启动这台机器。以上都是凭记忆写的。现在我有一些硬数据。这是输出mdadm --examine /dev/sd*2

/dev/sda2:
          Magic : a92b4efc
        Version : 0.90.00
           UUID : 53eb7711:5b290125:db4a62ac:7770c5ea
  Creation Time : Sun May 30 21:48:55 2010
     Raid Level : raid5
  Used Dev Size : 625064960 (596.11 GiB 640.07 GB)
     Array Size : 1875194880 (1788.33 GiB 1920.20 GB)
   Raid Devices : 4
  Total Devices : 4
Preferred Minor : 1

    Update Time : Mon Aug 23 11:40:48 2010
          State : clean
 Active Devices : 3
Working Devices : 4
 Failed Devices : 1
  Spare Devices : 1
       Checksum : 68b48835 - correct
         Events : 53204

         Layout : left-symmetric
     Chunk Size : 64K

      Number   Major   Minor   RaidDevice State
this     0       8        2        0      active sync   /dev/sda2

   0     0       8        2        0      active sync   /dev/sda2
   1     1       8       18        1      active sync   /dev/sdb2
   2     2       8       34        2      active sync   /dev/sdc2
   3     3       0        0        3      faulty removed
   4     4       8       50        4      spare   /dev/sdd2
/dev/sdb2:
          Magic : a92b4efc
        Version : 0.90.00
           UUID : 53eb7711:5b290125:db4a62ac:7770c5ea
  Creation Time : Sun May 30 21:48:55 2010
     Raid Level : raid5
  Used Dev Size : 625064960 (596.11 GiB 640.07 GB)
     Array Size : 1875194880 (1788.33 GiB 1920.20 GB)
   Raid Devices : 4
  Total Devices : 4
Preferred Minor : 1

    Update Time : Mon Aug 23 11:44:54 2010
          State : clean
 Active Devices : 2
Working Devices : 3
 Failed Devices : 1
  Spare Devices : 1
       Checksum : 68b4894a - correct
         Events : 53205

         Layout : left-symmetric
     Chunk Size : 64K

      Number   Major   Minor   RaidDevice State
this     1       8       18        1      active sync   /dev/sdb2

   0     0       0        0        0      removed
   1     1       8       18        1      active sync   /dev/sdb2
   2     2       8       34        2      active sync   /dev/sdc2
   3     3       0        0        3      faulty removed
   4     4       8       50        4      spare   /dev/sdd2
/dev/sdc2:
          Magic : a92b4efc
        Version : 0.90.00
           UUID : 53eb7711:5b290125:db4a62ac:7770c5ea
  Creation Time : Sun May 30 21:48:55 2010
     Raid Level : raid5
  Used Dev Size : 625064960 (596.11 GiB 640.07 GB)
     Array Size : 1875194880 (1788.33 GiB 1920.20 GB)
   Raid Devices : 4
  Total Devices : 4
Preferred Minor : 1

    Update Time : Mon Aug 23 11:44:54 2010
          State : clean
 Active Devices : 1
Working Devices : 2
 Failed Devices : 2
  Spare Devices : 1
       Checksum : 68b48975 - correct
         Events : 53210

         Layout : left-symmetric
     Chunk Size : 64K

      Number   Major   Minor   RaidDevice State
this     2       8       34        2      active sync   /dev/sdc2

   0     0       0        0        0      removed
   1     1       0        0        1      faulty removed
   2     2       8       34        2      active sync   /dev/sdc2
   3     3       0        0        3      faulty removed
   4     4       8       50        4      spare   /dev/sdd2
/dev/sdd2:
          Magic : a92b4efc
        Version : 0.90.00
           UUID : 53eb7711:5b290125:db4a62ac:7770c5ea
  Creation Time : Sun May 30 21:48:55 2010
     Raid Level : raid5
  Used Dev Size : 625064960 (596.11 GiB 640.07 GB)
     Array Size : 1875194880 (1788.33 GiB 1920.20 GB)
   Raid Devices : 4
  Total Devices : 4
Preferred Minor : 1

    Update Time : Mon Aug 23 11:44:54 2010
          State : clean
 Active Devices : 1
Working Devices : 2
 Failed Devices : 2
  Spare Devices : 1
       Checksum : 68b48983 - correct
         Events : 53210

         Layout : left-symmetric
     Chunk Size : 64K

      Number   Major   Minor   RaidDevice State
this     4       8       50        4      spare   /dev/sdd2

   0     0       0        0        0      removed
   1     1       0        0        1      faulty removed
   2     2       8       34        2      active sync   /dev/sdc2
   3     3       0        0        3      faulty removed
   4     4       8       50        4      spare   /dev/sdd2
Run Code Online (Sandbox Code Playgroud)

自上次启动以来,情况似乎发生了变化。如果我正确阅读了 sda2,sdb2 和 sdc2 正在工作并包含同步数据,而 sdd2 是备用的。我清楚地记得看到 3 个失败的磁盘,但这是个好消息。然而数组仍然无法正常工作:

Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md125 : inactive sda2[0](S) sdb2[1](S) sdc2[2](S)
      1875194880 blocks

md126 : inactive sdd2[4](S)
      625064960 blocks

md127 : active raid1 sda1[0] sdd1[3] sdc1[2] sdb1[1]
      64128 blocks [4/4] [UUUU]

unused devices: <none>
Run Code Online (Sandbox Code Playgroud)

md0 似乎已重命名为 md127。md125 和 md126 很奇怪。它们应该是一个数组而不是两个。那曾经被称为md1。md2 完全消失了,但那是我的交换,所以我不在乎。

我可以理解不同的名称,这并不重要。但是为什么具有 3 个“主动同步”磁盘的阵列不可读?sdd2 在一个单独的数组中是怎么回事?

更新

备份超级块后,我尝试了以下操作:

root@sysresccd /root % mdadm --stop /dev/md125
mdadm: stopped /dev/md125
root@sysresccd /root % mdadm --stop /dev/md126
mdadm: stopped /dev/md126
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好。由于 sdd2 是空闲的,我还不想添加它。

root@sysresccd /root % mdadm --assemble /dev/md1 /dev/sd{a,b,c}2 missing 
mdadm: cannot open device missing: No such file or directory
mdadm: missing has no superblock - assembly aborted
Run Code Online (Sandbox Code Playgroud)

显然我不能这样做。

root@sysresccd /root % mdadm --assemble /dev/md1 /dev/sd{a,b,c}2        
mdadm: /dev/md1 assembled from 1 drive - not enough to start the array.
root@sysresccd /root % cat /proc/mdstat 
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md1 : inactive sdc2[2](S) sdb2[1](S) sda2[0](S)
      1875194880 blocks

md127 : active raid1 sda1[0] sdd1[3] sdc1[2] sdb1[1]
      64128 blocks [4/4] [UUUU]

unused devices: <none>
Run Code Online (Sandbox Code Playgroud)

那也没有用。让我们尝试使用所有磁盘。

mdadm --stop /dev/md1
mdadm: stopped /dev/md1
root@sysresccd /root % mdadm --assemble /dev/md1 /dev/sd{a,b,c,d}2
mdadm: /dev/md1 assembled from 1 drive and 1 spare - not enough to start the array.
root@sysresccd /root % cat /proc/mdstat                           
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 
md1 : inactive sdc2[2](S) sdd2[4](S) sdb2[1](S) sda2[0](S)
      2500259840 blocks

md127 : active raid1 sda1[0] sdd1[3] sdc1[2] sdb1[1]
      64128 blocks [4/4] [UUUU]

unused devices: <none>
Run Code Online (Sandbox Code Playgroud)

没运气。基于这个答案,我打算尝试:

mdadm --create /dev/md1 --assume-clean --metadata=0.90 --bitmap=/root/bitmapfile --level=5 --raid-devices=4 /dev/sd{a,b,c}2 missing
mdadm --add /dev/md1 /dev/sdd2
Run Code Online (Sandbox Code Playgroud)

安全吗?

更新

我在我的评论中发布了我用来制作该表的超级块解析器脚本。也许有人会发现它很有用。感谢你的帮助。

for*_*sck 13

首先检查磁盘,尝试运行智能自检

for i in a b c d; do
    smartctl -s on -t long /dev/sd$i
done
Run Code Online (Sandbox Code Playgroud)

完成可能需要几个小时,但每隔几分钟检查每个驱动器的测试状态,即

smartctl -l selftest /dev/sda
Run Code Online (Sandbox Code Playgroud)

如果由于读取错误导致磁盘状态报告未完成,则应认为该磁盘对于 md1 重组是不安全的。自检完成后,您可以开始尝试重新组装您的阵列。或者,如果您想格外小心,请在继续之前将磁盘移到另一台机器上(以防内存/控制器/等损坏)。

最近,我遇到了一个与此一模一样的案例。一个驱动器出现故障,我重新添加到阵列中,但在重建过程中,4 个驱动器中有 3 个完全失败。/proc/mdadm 的内容与您的相同(可能顺序不同)

md1 : inactive sdc2[2](S) sdd2[4](S) sdb2[1](S) sda2[0](S)
Run Code Online (Sandbox Code Playgroud)

但我很幸运,用这个重新组装了阵列

mdadm --assemble /dev/md1 --scan --force
Run Code Online (Sandbox Code Playgroud)

通过查看您提供的 --examine 输出,我可以判断发生了以下情况:sdd2 失败,您将其删除并重新添加,因此它成为尝试重建的备用驱动器。但是在重建 sda2 失败,然后 sdb2 失败。所以事件计数器在 sdc2 和 sdd2 中更大,它们是阵列中最后一个活动驱动器(尽管 sdd 没有机会重建,所以它是最过时的)。由于事件计数器的差异, --force 将是必要的。所以你也可以试试这个

mdadm --assemble /dev/md1 /dev/sd[abc]2 --force
Run Code Online (Sandbox Code Playgroud)

总而言之,我认为如果上述命令失败,您应该尝试像这样重新创建数组:

mdadm --create /dev/md1 --assume-clean -l5 -n4 -c64 /dev/sd[abc]2 missing
Run Code Online (Sandbox Code Playgroud)

如果您这样做--create,这missing部分很重要,请不要尝试在阵列中添加第四个驱动器,因为这样会开始构建,您将丢失数据。使用丢失的驱动器创建阵列不会更改其内容,您将有机会在其他地方获得副本(raid5 与 raid1 的工作方式不同)。

如果无法启动数组,请在此处尝试此解决方案(perl 脚本)重新创建数组

如果您最终设法启动阵列,则文件系统将不干净并且可能已损坏。如果一个磁盘在重建期间出现故障,预计阵列将停止并冻结,而不对其他磁盘进行任何写入。在这种情况下,两个磁盘出现故障,可能系统正在执行无法完成的写入请求,因此您丢失一些数据的可能性很小,但也有可能您永远不会注意到它:-)

编辑:添加了一些说明。