RAID0 数据恢复和恢复策略验证

RAID0 数据恢复和恢复策略验证

我有一个 Synology 扩展 (DX213) 连接到我的 NAS。它装有 2 个 2TB 的磁盘,它们处于 RAID0 配置中(糟糕的想法,我知道,我不需要提醒 ;) )。上周末,阵列发生故障,我无法再启动 RAID 阵列。

我开始相信问题出在背板(DX213)而不是磁盘上,因为它们看起来没问题。它们肯定还没有坏掉(目前还没有)。我将它们连接到 Linux 机器上,我可以清楚地看到它们:

$ sudo fdisk -l /dev/sdb
Disk /dev/sdb: 1.8 TiB, 2000396746752 bytes, 3907024896 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x000a85dd

Device     Boot   Start        End    Sectors  Size Id Type
/dev/sdb1           256    4980735    4980480  2.4G 83 Linux
/dev/sdb2       4980736    9175039    4194304    2G 82 Linux swap / Solaris
/dev/sdb3       9437184 3907024064 3897586881  1.8T 83 Linux

$ sudo fdisk -l /dev/sdc
Disk /dev/sdc: 1.8 TiB, 2000396746752 bytes, 3907024896 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0004dd4e

Device     Boot   Start        End    Sectors  Size Id Type
/dev/sdc1           256    4980735    4980480  2.4G 83 Linux
/dev/sdc2       4980736    9175039    4194304    2G 82 Linux swap / Solaris
/dev/sdc3       9437184 3907024064 3897586881  1.8T 83 Linux

检查磁盘时,mdadm仍然可以识别 raid 阵列,并且两个磁盘似乎都处于干净状态,但两个磁盘上的超级块明显不同步。

$ sudo mdadm --examine /dev/sd[bc]3 
/dev/sdb3:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 1d7dd58f:dd7dd3d2:b646173b:afd51417
           Name : mist-nas:2
  Creation Time : Tue Nov 26 19:47:24 2013
     Raid Level : raid0
   Raid Devices : 2

 Avail Dev Size : 3897584833 (1858.51 GiB 1995.56 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
   Unused Space : before=1968 sectors, after=0 sectors
          State : clean
    Device UUID : 46933df7:36901a5b:7a1239fe:e999c419

    Update Time : Sat Aug 27 20:14:12 2016
       Checksum : 42117b5b - correct
         Events : 8

     Chunk Size : 64K

   Device Role : Active device 0
   Array State : A. ('A' == active, '.' == missing, 'R' == replacing)

/dev/sdc3:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 1d7dd58f:dd7dd3d2:b646173b:afd51417
           Name : mist-nas:2
  Creation Time : Tue Nov 26 19:47:24 2013
     Raid Level : raid0
   Raid Devices : 2

 Avail Dev Size : 3897584833 (1858.51 GiB 1995.56 GB)
    Data Offset : 2048 sectors
   Super Offset : 8 sectors
   Unused Space : before=1968 sectors, after=0 sectors
          State : clean
    Device UUID : e4b60f4c:604b2e27:359cb71b:24453937

    Update Time : Tue Nov 26 19:47:24 2013
       Checksum : 997fa41a - correct
         Events : 4

     Chunk Size : 64K

   Device Role : Active device 1
   Array State : AA ('A' == active, '.' == missing, 'R' == replacing)

唯一的区别是最后更新时间戳和事件计数。我知道阵列发生故障时没有正在进行写入操作,并且两个磁盘都处于干净状态,因此我非常有信心我仍然可以访问我的数据。但是要恢复,我必须重新创建阵列或摆弄有故障的超级块,这至少让我感到毛骨悚然……

我已经将两个驱动器克隆到dd新驱动器上,以便在我做傻事时有备份。新驱动器的扇区大小为 4096(它们是 3 和 4TB 磁盘),而旧驱动器的扇区大小为 512。sd[bc]3 分区的大小不是 4096 个扇区的倍数,所以我不得不将分区的大小四舍五入到下一个扇区。我希望这不是问题?

我正在考虑运行的命令是:

$ sudo mdadm --create --readonly --assume-clean --level=0 -n2 /dev/md2 /dev/sdb3 /dev/sdc3

此命令可能会覆盖当前的超级块,因此我想绝对确保这不会破坏我恢复数据的机会。此命令的结果是什么?

在真正行动之前,我还想验证一下我的策略。我在 USB 密钥上创建了 2 个 4GB 分区,用它们创建了一个 RAID0 阵列,在阵列上创建了一个 EXT4 文件系统,挂载了它并在其中复制了一些文件。问题是我如何操作其中一个分区的超级块来重现我在 4TB 阵列中遇到的情况。

我考虑使用十六进制编辑器手动操作超级块,但这样可能还需要重新计算校验和。我该怎么做?

答案1

您应该从阵列中移除驱动器,将其从系统中移除,重新探测磁盘,然后将驱动器重新添加到阵列中。

使用以下命令从阵列中删除故障驱动器

mdadm --manage --set-faulty

物理地从系统中移除/重新插入驱动器(或使用设备删除和 scsi 主机重新扫描)。

现在检查是否再次找到驱动器,并检查它是否正常工作。您可以查看 dmesg 输出或查看 /proc/partitions。pv <在设备上运行。

然后使用 将驱动器重新添加到阵列mdadm

然后进行最后检查,cat /proc/mdstat看看是否成功。

答案2

我设法找回了我的数据,尽管方法并不简单(剧透:它包括十六进制编辑器和一些逆向工程)。我只是发布我的方法以供将来参考。

因此,我的 RAID0 阵列因超级块不匹配而损坏。由于 RAID0 中没有冗余,因此mdadm除非所有超级块都匹配,否则无法启动 RAID0 阵列。我的磁盘看起来不错,但超级块不同步。

解决方案:使超级块再次匹配。

第一个想法:运行上述命令,将完全按照之前的方式重新创建 RAID 阵列,但会覆盖当前的超级块。

评估的第一个想法:有风险。无法保证mdadm会以与以前完全相同的方式重新创建阵列。也许我会忘记一些参数,也许mdadm会写入我想要的其他地方,从而破坏我的底层文件系统和数据,甚至其他东西。

结论:坏主意。

第二个想法。使用十六进制编辑器自己操作超级块。

优点:

  • 我能控制一切,除非我犯了愚蠢的错误,否则不会对无关紧要的字节进行任何更改。
  • 只有超级块的不匹配值才会被修改,因此数组的布局不会受到影响。

挑战:

  • 超级块写在磁盘的什么位置?
  • 它看起来怎样?
  • mdadm --examine我能否识别正确的字节并通过读取十六进制值重建输出?
  • 更改属性将使超级块校验和无效,如何获得有效的校验和?

事实证明,这些挑战很容易克服。linux-raid wiki 上有一个很棒的页面:https://raid.wiki.kernel.org/index.php/RAID_superblock_formats。它记录了 v1 超级块以及在磁盘上找到它的位置。对于 v1.2 超级块,它位于磁盘开头 4K 处,并写入下一个 4K(因为它是扇区对齐的,新磁盘使用 4K 扇区,即使使用它的磁盘有 512 字节扇区)。

您还可以参考 v1 超级块的源代码,它并不太难阅读:https://github.com/neilbrown/mdadm/blob/master/super1.c

经过仔细的分析,我确定了这个计划:

  1. 首先,备份每个磁盘的前 8K。这样我就可以随时恢复到原始状态。

    dd if=/dev/sdXY of=sdXY.backup bs=1 count=8K

  2. 提取每个磁盘的超级块。这很容易做到

    dd if=/dev/sdXY of=sdXY.superblock bs=1 count=4K skip=4K

  3. 在十六进制编辑器中读取超级块。我发现基于网络的http://hexed.it非常好。

  4. 修改必要的属性,保留校验和。修改时间戳时要小心。Linux 时间戳占用 32 位或 4 个字节,Linuxmdadm时间戳占用 64 位或 8 个字节。不要忘记复制其他 4 个。超级块为 256 个字节 + 数组每个成员的 2 个字节。这些最后的字节是成员 ID 或角色的序列。

  5. 将超级块写入磁盘。

    dd if=sdXY.superblock of=/dev/sdXY bs=1 count=4K seek=4K

  6. 使用 检查超级块mdadm --examine /dev/sdXY。它将向您显示校验和无效,但也会向您显示预期的校验和。

  7. 将校验和修改为正确的值。在十六进制编辑器中,字节被反转,因此becomes十六进制编辑器中为“99 7F A4 1A 1A A4 7F 99”。

  8. 使用与步骤5相同的命令将新的超级块写入磁盘。

  9. 对每个磁盘重复此操作。

当两个超级块匹配时,我就可以再次启动阵列了。我检查了文件系统,发现它看起来是干净的。挂载文件系统并将所有内容复制到 RAID5 阵列,我很快也会用 UPS 保护它。

我很幸运,不会忘记这些非常可怕的时刻。我一直保持冷静,不断思考如何重新组装阵列。

我强烈建议在彻底分析问题之前不要摆弄损坏的阵列。另外,我在开始之前写下了我的计划,这样我就不会跳过任何一步,导致数据丢失的风险。

相关内容