如何在 Linux 软件 RAID 中更换故障硬盘
在此页
- 1 条初步说明
- 2 如何判断硬盘是否出现故障?
- 3 移除故障磁盘
- 4 添加新硬盘
本指南介绍如何从 Linux RAID1 阵列(软件 RAID)中移除故障硬盘,以及如何在不丢失数据的情况下将新硬盘添加到 RAID1 阵列。我将使用 gdisk 复制分区方案,因此它也适用于具有 GPT(GUID 分区表)的大型硬盘。
1 初步说明
在此示例中,我有两个硬盘驱动器,/dev/sda 和/dev/sdb,分区为/dev/sda1 和/dev/sda2 以及/dev/sdb1 和/dev/sdb2。
/dev/sda1 和/dev/sdb1 组成RAID1 阵列/dev/md0。
/dev/sda2 和/dev/sdb2 组成RAID1 阵列/dev/md1。
/dev/sda1 + /dev/sdb1 = /dev/md0
/dev/sda2 + /dev/sdb2 = /dev/md1
/dev/sdb 失败了,我们想替换它。
2 如何判断硬盘是否出现故障?
如果磁盘发生故障,您可能会在日志文件中发现很多错误消息,例如/var/log/messages 或 /var/log/syslog。
你也可以运行
cat /proc/mdstat
如果您的 RAID1 阵列降级,您将看到 [U_] 而不是字符串 [UU]。
3 移除故障磁盘
要删除 /dev/sdb,我们会将 /dev/sdb1 和 /dev/sdb2 标记为失败,并将它们从各自的 RAID 阵列(/dev/md0 和 /dev/md1)中删除。
首先我们将 /dev/sdb1 标记为失败:
mdadm --manage /dev/md0 --fail /dev/sdb1
的输出
cat /proc/mdstat
应该是这样的:
server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md0 : active raid1 sda1[0] sdb1[2](F)
24418688 blocks [2/1] [U_]
md1 : active raid1 sda2[0] sdb2[1]
24418688 blocks [2/2] [UU]
unused devices: <none>
然后我们从 /dev/md0 中删除 /dev/sdb1:
mdadm --manage /dev/md0 --remove /dev/sdb1
输出应该是这样的:
server1:~# mdadm --manage /dev/md0 --remove /dev/sdb1
mdadm: hot removed /dev/sdb1
和
cat /proc/mdstat
应该显示这个:
server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md0 : active raid1 sda1[0]
24418688 blocks [2/1] [U_]
md1 : active raid1 sda2[0] sdb2[1]
24418688 blocks [2/2] [UU]
unused devices: <none>
现在我们对 /dev/sdb2(它是 /dev/md1 的一部分)再次执行相同的步骤:
mdadm --manage /dev/md1 --fail /dev/sdb2
cat /proc/mdstat
server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md0 : active raid1 sda1[0]
24418688 blocks [2/1] [U_]
md1 : active raid1 sda2[0] sdb2[2](F)
24418688 blocks [2/1] [U_]
unused devices: <none>
mdadm --manage /dev/md1 --remove /dev/sdb2
server1:~# mdadm --manage /dev/md1 --remove /dev/sdb2
mdadm: hot removed /dev/sdb2
cat /proc/mdstat
server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md0 : active raid1 sda1[0]
24418688 blocks [2/1] [U_]
md1 : active raid1 sda2[0]
24418688 blocks [2/1] [U_]
unused devices: <none>
然后关闭系统:
shutdown -h now
并用新的 /dev/sdb 硬盘驱动器替换旧的(它的大小必须至少与旧的相同——如果它只比旧的小几 MB,那么重建阵列将失败)。
4 添加新硬盘
更换硬盘/dev/sdb 后,启动系统。
我们现在必须做的第一件事是创建与 /dev/sda 上完全相同的分区。我们可以使用 gdisk 包中的命令 sgdisk 来做到这一点。如果您还没有安装 gdisk,请运行此命令在 Debian 和 Ubuntu 上安装它:
apt-get install gdisk
对于基于 RedHat 的 Linux 发行版(如 CentOS),请使用:
yum install gdisk
对于 OpenSuSE 使用:
yast install gdisk
下一步是可选的,但建议执行。为确保您有分区方案的备份,您可以使用 sgdisk 将两个磁盘的分区方案写入一个文件。我会将备份存储在 /root 文件夹中。
sgdisk --backup=/root/sda.partitiontable /dev/sda
sgdisk --backup=/root/sdb.partitiontable /dev/sdb
如果出现故障,您可以使用 sgdisk 命令的 --load-backup 选项恢复分区表。
现在将分区方案从 /dev/sda 复制到 /dev/sdb 运行:
sgdisk -R /dev/sdb /dev/sda
之后,您必须随机化新硬盘上的 GUID 以确保它们是唯一的
sgdisk -G /dev/sdb
你可以跑
sgdisk -p /dev/sda
sgdisk -p /dev/sdb
检查两个硬盘驱动器现在是否具有相同的分区。
接下来我们将/dev/sdb1 添加到/dev/md0 并将/dev/sdb2 添加到/dev/md1:
mdadm --manage /dev/md0 --add /dev/sdb1
server1:~# mdadm --manage /dev/md0 --add /dev/sdb1
mdadm: re-added /dev/sdb1
mdadm --manage /dev/md1 --add /dev/sdb2
server1:~# mdadm --manage /dev/md1 --add /dev/sdb2
mdadm: re-added /dev/sdb2
现在两个阵列(/dev/md0 和/dev/md1)将被同步。跑步
cat /proc/mdstat
看看它什么时候完成。
在同步期间,输出将如下所示:
server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md0 : active raid1 sda1[0] sdb1[1]
24418688 blocks [2/1] [U_]
[=>...................] recovery = 9.9% (2423168/24418688) finish=2.8min speed=127535K/sec
md1 : active raid1 sda2[0] sdb2[1]
24418688 blocks [2/1] [U_]
[=>...................] recovery = 6.4% (1572096/24418688) finish=1.9min speed=196512K/sec
unused devices: <none>
同步完成后,输出将如下所示:
server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md0 : active raid1 sda1[0] sdb1[1]
24418688 blocks [2/2] [UU]
md1 : active raid1 sda2[0] sdb2[1]
24418688 blocks [2/2] [UU]
unused devices: <none>
就是这样,你已经成功替换了/dev/sdb!