![软件 raid mdadm 未添加备用](https://linux22.com/image/524185/%E8%BD%AF%E4%BB%B6%20raid%20mdadm%20%E6%9C%AA%E6%B7%BB%E5%8A%A0%E5%A4%87%E7%94%A8.png)
我刚刚在大约 9 个月前安装的两台全新且完全相同的服务器上发现了同样的问题。我无法在这两台服务器上写入磁盘,因为系统已将其标记为只读。日志表明两台服务器上都存在某种磁盘错误。
请注意,我在每台服务器上都运行 KVM 和多个客户机。客户机都运行良好,但问题出在 KVM 主机上。这可能无关紧要,但也许它很重要。两个系统都只有两个驱动器顶部有软件 raid1 和 LVM。每个 KVM 客户机也都有自己的 LVM 分区。
从表面上看,两个系统均显示出性能下降的 RAID1 阵列/proc/mdstat
。
于是我重启了其中一个系统,系统提示我需要手动运行fsck
。于是我就照做了。问题似乎解决了,重启后系统恢复正常。同样的过程也适用于第二台服务器。
接下来,我运行mdadm --manage /dev/md0 --add /dev/sdb1
将故障驱动器重新添加到阵列中。这在两台服务器上都运行良好。在接下来的一个小时左右,查看/proc/mdstat
显示驱动器同步的进度。大约一个小时后,一个系统完成,并/proc/mdstat
显示一切运行良好[UU]
。
然而,在另一个系统上,大约 1.5 小时后,系统负载猛增,没有任何响应。几分钟后,一切恢复正常。但现在显示/proc/mdstat
以下内容:
root@bond:/etc# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 sda1[2] sdb1[1]
293033536 blocks [2/1] [_U]
unused devices: <none>
如您所见,它似乎不再同步。已完成的百分比、剩余时间等不再显示。但是,运行时mdadm --detail /dev/md0
会显示以下内容:
root@bond:/etc# mdadm --detail /dev/md0
/dev/md0:
Version : 00.90
Creation Time : Mon Nov 30 20:04:44 2009
Raid Level : raid1
Array Size : 293033536 (279.46 GiB 300.07 GB)
Used Dev Size : 293033536 (279.46 GiB 300.07 GB)
Raid Devices : 2
Total Devices : 2
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Fri Sep 10 23:38:33 2010
State : clean, degraded
Active Devices : 1
Working Devices : 2
Failed Devices : 0
Spare Devices : 1
UUID : 4fb7b768:16c7d5b3:2e7b5ffd:55e4b71d
Events : 0.5104310
Number Major Minor RaidDevice State
2 8 1 0 spare rebuilding /dev/sda1
1 8 17 1 active sync /dev/sdb1
底线似乎表明备用设备正在重建。为什么它是备用设备?系统报告两个设备都干净。这种情况已经持续了几个小时。驱动器很小而且速度很快,是 300GB 10K RPM VelociRaptors,所以我认为现在应该已经同步了。尝试重新添加时显示设备正忙:
root@bond:/etc# mdadm /dev/md0 --re-add /dev/sda
mdadm: Cannot open /dev/sda: Device or resource busy
在“良好”服务器上运行 dmesg 最后显示以下内容:
[ 4084.439822] md: md0: recovery done.
[ 4084.487756] RAID1 conf printout:
[ 4084.487759] --- wd:2 rd:2
[ 4084.487763] disk 0, wo:0, o:1, dev:sda1
[ 4084.487765] disk 1, wo:0, o:1, dev:sdb1
在“坏”服务器上,最后四行重复了数百次。在“好”服务器上,它们只显示一次。
驱动器仍在同步吗?“重建”会完成吗?我只需要更耐心一点吗?如果不是,我现在应该做什么?
更新:
我刚刚重新启动,驱动器又开始同步了。将近 2 小时后,发生了与上述相同的事情(仍然得到 [_U])。但是,在 RAID1 conf 打印输出块消耗掉所有数据之前,我能够看到 dmesg 日志:
[ 6348.303685] sd 1:0:0:0: [sdb] Unhandled sense code
[ 6348.303688] sd 1:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 6348.303692] sd 1:0:0:0: [sdb] Sense Key : Medium Error [current] [descriptor]
[ 6348.303697] Descriptor sense data with sense descriptors (in hex):
[ 6348.303699] 72 03 11 04 00 00 00 0c 00 0a 80 00 00 00 00 00
[ 6348.303707] 22 ee a4 c7
[ 6348.303711] sd 1:0:0:0: [sdb] Add. Sense: Unrecovered read error - auto reallocate failed
[ 6348.303716] end_request: I/O error, dev sdb, sector 586065095
[ 6348.303753] ata2: EH complete
[ 6348.303776] raid1: sdb: unrecoverable I/O read error for block 586065024
[ 6348.305625] md: md0: recovery done.
所以也许我应该问的问题是“如何在 raid 组中的备用磁盘上运行 fsck?”
答案1
我不清楚您是否真的更换了故障驱动器?因为如果您重新添加了故障驱动器,您的症状对我来说是有意义的,在这种情况下,驱动器很可能已锁定。如果您确实重新添加了故障驱动器,/var/log/messages 或 dmesg 中是否有后续错误?
(顺便说一句,我强烈建议不要将有故障的驱动器重新添加到 RAID 阵列中。如果故障损坏了盘片上的数据,您可能会发现,当您将其添加回阵列时,重新同步会将损坏的文件留在磁盘上,下次您读取文件时,您将无法确定是获得好数据还是坏数据,这取决于哪个磁盘先响应;我曾在野外看到过这种情况。)
答案2
使用 mdadm --details 将在重建期间将驱动器列为备用驱动器。重建完成后,它将不再显示为备用驱动器。
[ 6348.303711] sd 1:0:0:0: [sdb] Add. Sense: Unrecovered read error - auto reallocate failed
[ 6348.303716] end_request: I/O error, dev sdb, sector 586065095
[ 6348.303753] ata2: EH complete
[ 6348.303776] raid1: sdb: unrecoverable I/O read error for block 586065024
[ 6348.305625] md: md0: recovery done.
第一行,说明重新分配失败,无法读取数据。接下来的三行指出无法读取数据,并列出了无法读取的扇区。
正如 Rodger 指出的那样,驱动器坏了,不要重新添加它。重新添加发生故障的驱动器永远不是一个好主意。拔出驱动器并更换它。如果您愿意,请在发生故障的驱动器上运行诊断程序,但只能在拔出并更换驱动器后运行。
答案3
首先,是的,删除所有抛出读取错误并最终记录在日志文件中的磁盘。这意味着坏块重定位失败和/或驱动器即将报废。
我建议你使用 Linux 救援 CD 来拯救你的数据,例如http://ubuntu-rescue-remix.org/使用 ddrescue。这可以将映像复制到新磁盘的分区,并将进行大量重试等以尝试恢复您的分区。安装 USB 驱动器或其他分区
mkdir /tmp/x && mount /dev/sdd1 /tmp/x
保存 ddrescue 日志文件 - 然后您可以停止 ddrescue(ctrl-C)并稍后从同一点重新启动它。
在新磁盘上创建一个比旧磁盘稍大的分区。您不必使用整个磁盘!
使用“nodmraid”作为内核启动参数启动救援 CD。如果使用 ubuntu live CD,则安装 RAID 和 LVM(如果您正在使用它)
apt-get 安装 mdadm lvm2 gddrescue
您需要上网才能使用此功能)。否则,请使用 ubuntu 救援 CD 执行 ddrescue 步骤。我切换了救援 CD 以运行 ddrescue,切换了 live CD 以运行 grub 和 fsck。
假设 /dev/sdb 是故障源磁盘,/dev/sdx 是新磁盘,/mnt/x 是 USB 密钥或已安装的另一个磁盘上的分区。您需要ddrescue 日志文件,真的!因为它跟踪 ddrescue 的运行情况,并允许中断它。
按照http://www.forensicswiki.org/wiki/Ddrescue
ddrescue --no-split /dev/sdb /dev/sdX 映像文件 /mnt/x/logfile
然后
ddrescue --direct --max-retries=3 /dev/sdb /dev/sdX /mnt/x/logfile
然后
ddrescue --direct --retrim --max-retries=3 /dev/sdb /dev/sdX /mnt/x/logfile
如果恢复单个扇区需要几个小时,不要害怕按 Ctrl-C 来完成该过程。只需继续下一步(无论怎样,步骤 1 都应该成功)。最后一步是尝试恢复最后一点可用数据。
你还必须做
mdadm --create /dev/md99 --level-1 --raid-devices=2 缺少 /dev/sdX
使用新磁盘创建新的 RAID 阵列,这会在分区上写入新的 RAID 超级块(在分区末尾的最后 64K 到 128K 之间)。
从系统中删除旧的故障磁盘 /dev/sdb,以便 Linux 看不到它。
使源 RAID 磁盘可访问。您可能必须对内核启动内核使用“nodmraid”参数,因为我在使用 ubuntu 救援 CD 时遇到了问题,最后使用了 Ubuntu live CD (10.4),其中 nodmraid 位于 F6 选项中。您只需要使用
mdadm --assemble /dev/md99 /dev/sdX
然后对 md99 RAID 阵列上的数据执行 fsck 或任何需要执行的检查(我使用 vgscan 然后能够看到 LVM LV 以运行检查)。我将 XFS 用于 mythtv,但 xfs_check 命令导致我的系统崩溃,而 xfs_repair 则没问题。
从新的 /dev/sdX 挂载 /boot 目录
挂载 /dev/mapper/my_vg/root_lv /tmp/x
然后将新的 GRUB 启动记录放在新的 /dev/sdX RAID 磁盘上(仅当您从 RAID 启动时!)
grub-setup -d /tmp/x/boot/grub /dev/sdX
现在您有一个 (几乎) 可启动的 RAID 阵列。您也可以使用 GRUB 本身进行设置,或者使用 dd 将 /dev/sdb 的前 446 个字节复制到 /dev/sdX。只有前 446 个字节,第一个扇区的其余部分是您的分区表,如果您复制更多,您将会严重损坏它!您可能还必须对分区 /dev/sdX1 中的第一个扇区执行相同操作(例如)。使用 dd 备份您要覆盖的任何扇区。
如果使用 grub2 并从 RAID 启动,您会发现 RAID 阵列 UUID 已更改,因此启动将失败。编辑启动命令行(Grub 启动面板中的 e)以删除 splash 和 quiet,这样您就可以看到发生了什么。启动失败后,您将留在 initramfs 中。
mdadm --assemble /dev/md99 /dev/sdX
然后检查 /proc/mdstat 以确保阵列存在。如果存在,则只需“退出”,希望您的 GRUB 启动节能够正常工作(我的设置为使用 LVM,因此一旦有任何 RAID 设备,它就会在 RAID 设备上找到 LV,它只会搜索 LV)。启动后,您就几乎完成了。
initrd 映像文件(gzip 压缩的 cpio 文件)包含启动过程中使用的 mdadm.conf 副本,在启动过程中可作为 /etc/mdadm/mdamdm.conf 查看和编辑。如果您的系统可以正常启动,只需使用以下命令更新 initramfs
更新-initramfs -u
如果由于 mdadm.conf 文件中的 UUID 不匹配而无法启动系统
请注意,当您以不同的方式启动(Grub、救援、实际启动)时,您的目标设备 /dev/sdX 可能会显示为 /dev/sdY。
顺便说一句,除非您使用的是 RAID5 并且对块对齐非常感兴趣,否则我会为您的 RAID 阵列使用一个分区,您不必使用整个磁盘(特别是如果您用 2TB 磁盘替换 1TB 磁盘)。您以后可以随时添加另一个分区和第二个 RAID 阵列以使用整个 2TB。
呼!完成了!