我对 Linux 完全陌生。我继承了一台托管在德国某处的专用服务器。操作系统是 CentOS 6.7 版(最终版)64 位。该服务器有两个 3TB 磁盘,采用软件 RAID-1 配置。我处理的情况是,根据 SMART,第二个磁盘即将发生故障,但是前任管理员遇到了一些 RAID 问题,他完全删除了其中的 /dev/sda 组件,因此现在系统从单个磁盘(降级)RAID-1 阵列启动,所有文件都在 /dev/sdb(即将发生故障的磁盘)上。此外,他完全删除了 /dev/sda。为了解决这个问题,我需要执行以下任务:
- 将 /dev/sda 重新分区,使其与 /dev/sdb 相同。
- 将所有数据从 /dev/sdb 复制(克隆)到 /dev/sda。
- 完全删除 RAID-1 配置。
- 将系统配置为从 /dev/sda 作为本机磁盘启动(而不是 /dev/md*)。
- 确保一切正常。
- 安全擦除 /dev/sdb。
- 请求支持人员用新的磁盘 (/dev/sdb) 替换故障磁盘。
- 重新创建并同步 RAID-1 阵列。
问题是我不知道如何在 Linux 中执行这些任务。请注意,我正在远程访问系统,因此我不能犯任何导致系统无法启动的错误。但是我可以访问救援系统(一个可从 DHCP 启动的小型 Linux,可以访问底层系统)。
以下是一些(可能有用的)命令输出和配置文件:
fdisk -l
Disk /dev/sdb: 3000.6 GB, 3000592982016 bytes
255 heads, 63 sectors/track, 364801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x000e76a6
Device Boot Start End Blocks Id System
/dev/sdb1 1 1567 12582912+ 83 Linux
/dev/sdb2 1567 1633 524288+ fd Linux raid autodetect
/dev/sdb3 1633 135307 1073741824+ fd Linux raid autodetect
/dev/sdb4 135307 364802 1843413464 f W95 Ext'd (LBA)
/dev/sdb5 135308 364802 1843412440 fd Linux raid autodetect
Disk /dev/sda: 3000.6 GB, 3000592982016 bytes
255 heads, 63 sectors/track, 364801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00074207
Device Boot Start End Blocks Id System
Disk /dev/md3: 1887.7 GB, 1887654199296 bytes
2 heads, 4 sectors/track, 460853076 cylinders
Units = cylinders of 8 * 512 = 4096 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00000000
Disk /dev/md1: 536 MB, 536858624 bytes
2 heads, 4 sectors/track, 131069 cylinders
Units = cylinders of 8 * 512 = 4096 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00000000
Disk /dev/md2: 1099.5 GB, 1099511488512 bytes
2 heads, 4 sectors/track, 268435422 cylinders
Units = cylinders of 8 * 512 = 4096 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00000000
文件-s /dev/sdb
/dev/sdb: x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, stage2 address 0x2000, stage2 segment 0x200, GRUB version 0.94; partition 1: ID=0x83, starthead 32, startsector 2048, 25165825 sectors; partition 2: ID=0xfd, starthead 254, startsector 25169920, 1048577 sectors; partition 3: ID=0xfd, starthead 254, startsector 26220544, 2147483649 sectors; partition 4: ID=0xf, starthead 254, startsector 2173706240, 3686826928 sectors, code offset 0x48
文件-s /dev/sda
/dev/sda: x86 boot sector, code offset 0xb8
猫/etc/fstab
proc /proc proc defaults 0 0
none /dev/pts devpts gid=5,mode=620 0 0
/dev/md0 none swap sw 0 0
/dev/md1 /boot ext3 defaults 0 0
/dev/md2 / ext4 defaults 0 0
/dev/md3 /home ext4 defaults 0 0
猫/boot/grub/grub.conf
timeout 5
default 0
title CentOS (2.6.32-573.7.1.el6.x86_64)
root (hd0,1)
kernel /vmlinuz-2.6.32-573.7.1.el6.x86_64 ro root=/dev/md2 rd_NO_LUKS rd_NO_DM nomodeset crashkernel=auto SYSFONT=latarcyrheb-sun16 LANG=en_US.UTF-8 KEYTABLE=de
initrd /initramfs-2.6.32-573.7.1.el6.x86_64.img
title CentOS (2.6.32-504.1.3.el6.x86_64)
root (hd0,1)
kernel /vmlinuz-2.6.32-504.1.3.el6.x86_64 ro root=/dev/md2 rd_NO_LUKS rd_NO_DM nomodeset crashkernel=auto SYSFONT=latarcyrheb-sun16 LANG=en_US.UTF-8 KEYTABLE=de
initrd /initramfs-2.6.32-504.1.3.el6.x86_64.img
猫/proc/mdstat
Personalities : [raid1]
md2 : active raid1 sdb3[1]
1073741688 blocks super 1.0 [2/1] [_U]
md1 : active raid1 sdb2[1]
524276 blocks super 1.0 [2/1] [_U]
md3 : active raid1 sdb5[1]
1843412304 blocks super 1.0 [2/1] [_U]
unused devices: <none>
任何帮助都将不胜感激。
谢谢。
答案1
首先,需要理解的是,这不是关于更换 RAID-1 阵列中的故障磁盘,而是关于如何完全移除 RAID 阵列、克隆即将发生故障的磁盘,然后从好磁盘启动系统,而无需任何 RAID 配置。采用这种方法的原因是,第一个磁盘(sda),即好磁盘,完全是空的,没有分区和文件系统,当我将其添加到阵列时,它无法同步(重建),可能是因为第二个磁盘(sdb)上有读取错误。此外,第二个磁盘(坏磁盘)是系统启动的地方。如果您了解 Linux 及其命令,完成此任务所需的步骤相当简单,但是,该过程涉及分区、克隆和 MBR 安装任务,如果您不够小心,这些任务将破坏您的数据。最后,以下步骤特定于问题中描述的磁盘配置,但如果您仔细替换必要的设备和分区名称,它应该可以在其他系统中工作。
具体步骤如下:
1. 以救援模式启动系统。
由于我们要从系统的启动盘克隆数据,因此我们无需担心任何锁定的文件或类似的东西。最好的方法是启动到救援模式。幸运的是,我的服务器托管公司以一种非常简单的方式支持这一点。在您可以直接访问(没有远程)的服务器中,这将类似于从实时 CD 启动或从启动菜单中选择“救援模式”。
2. 准备第一个磁盘(/dev/sda)用于克隆数据。
为了准备 sda,我们需要从 sdb 获取分区信息。实际上,此步骤不是强制性的,因为我们的目标是在没有任何 RAID 配置或与 sdb 没有任何关系的情况下启动系统(如果您愿意的话),因此如果当前分区方案不是我们想要的,那么这是一个更改它的机会。我们唯一需要记住的是,新分区需要有足够的空间来容纳来自 sdb 的数据。但是,在 Linux 中进行分区需要对对齐等内容有深入的了解,而且由于 sdb 已经正确分区,我发现在 sda 中执行相同操作更容易。为此,我们首先需要查看 sdb 中的分区,我为此使用了 parted。
笔记:当您研究如何使用 Linux 时,最困难的任务是找出(众多)命令中哪个命令最适合使用。例如,有很多分区命令和实用程序,决定使用哪一个需要花费大量时间阅读和比较信息。我选择在这里使用 parted,因为它可以显示文件系统和分区,并且它对大磁盘的支持更好?(我不确定)。
# parted /dev/sdb
(parted) unit s
(parted) print
输出:
Model: ATA ST3000DM001-1CH1 (scsi)
Disk /dev/sdb: 5860533168s
Sector size (logical/physical): 512B/4096B
Partition Table: msdos
Number Start End Size Type File system Flags
1 2048s 25167872s 25165825s primary
2 25169920s 26218496s 1048577s primary ext3 raid
3 26220544s 2173704192s 2147483649s primary ext4 raid
4 2173706240s 5860533167s 3686826928s extended lba
5 2173708288s 5860533167s 3686824880s logical ext4 raid
(parted) quit
我们在这里可以看到,sdb 有一个 msdos 类型的分区表,这意味着我们可以在磁盘上创建最多 4 个主分区。在本例中,它有 3 个主分区 (1,2,3) 和一个扩展分区 (4),后者包含一个逻辑分区 (5)。
下一步是在 sda 上创建相同的分区:
# parted /dev/sda
(parted) unit s
(parted) mkpart primary 2048 25167872
(parted) mkpart primary 25169920 26218496
(parted) mkpart primary 26220544 2173704192
(parted) mkpart extended 2173706240 5860533167
(parted) mkpart logical 2173708288 5860533167
(parted) quit
正如您所看到的,我使用了来自 sdb 的相同起始和结束扇区,当然磁盘是相同的,否则您需要相应地排列扇区。
现在我们需要告诉系统 sda 中的分区变化:
# partprobe /dev/sda
最后,我们需要在 sda 上创建文件系统。可能根本不需要此步骤,因为我们要从 sdb 克隆分区,因此克隆过程也会复制文件系统信息,但这不会造成任何影响。
# mkfs -t ext3 /dev/sda2
# mkfs -t ext4 /dev/sda3
# mkfs -t ext4 /dev/sda5
请注意,我们没有在分区 4 (sda4) 中创建文件系统。这是因为它是一个扩展分区,其中包含一个逻辑分区 (sda5),我们只需在逻辑分区上创建文件系统。
现在我们已经对 sda 进行了分区并准备保存我们的数据。
3.从 sdb 复制数据。
这一步需要做大量的研究,主要是因为有很多方法可以复制数据。cp -a 可能就足够了,但是,我没有找到任何关于如何处理任何隐藏文件、链接等以便正确启动系统的可靠信息。所以我决定使用字节到字节复制实用程序(克隆)而不是文件复制命令。我使用的实用程序是 dd:
# dd if=/dev/md1 of=/dev/sda2 bs=512 conv=noerror,sync,notrunc
# dd if=/dev/md2 of=/dev/sda3 bs=512 conv=noerror,sync,notrunc
# dd if=/dev/md3 of=/dev/sda5 bs=512 conv=noerror,sync,notrunc
注意:首先请注意,我们从 /dev/md* 而不是 /dev/sdb* 进行复制。这是因为我们的 sdb 磁盘实际上是 RAID-1 阵列的一部分。这是我没有找到任何可靠信息的另一部分。例如,系统“看到”/dev/sdb2、/dev/sdb3 和 /dev/sdb5 是保存我们数据的分区,但根据 /etc/fstab 文件,它挂载了 /dev/md1、/dev/md2 和 /dev/md3,因此我认为最好从 /dev/md* 进行复制。您需要注意的另一件事是您要将数据复制到 sda 上的哪个位置。换句话说,需要将 /dev/md1,2,3 复制到 sda 上的哪个位置。好吧,在这种情况下,根据分区大小和文件系统很容易找出答案,但在不同的系统中DF-K可以显示这一点,但不能从救援模式内部显示;您需要正常启动才能使其工作。
最后,使用上述命令,我们指示 dd 逐字节单独克隆每个分区,而不会因任何读取错误而停止(noerror 参数)。当然,如果 sdb 上有任何读取数据错误(在本例中确实存在),这可能会导致系统无法启动,但是,在我最终使用 dd 之前,我确实使用了一些技巧来查找哪些文件受到影响以及是否可以安全地继续克隆。这项任务超出了本答案的范围,但一个好的起点是这里。
另一个需要注意的重要点是块大小参数 (bs)。根据 dd 的文档,您应该将 bs 设置为 512 字节,因为如果出现读取错误(确实会出现),它只会“破坏”目标磁盘中的 512 字节,而不是更大的区域,但过程会更慢。同样,我没有找到任何关于此的可靠信息,可能 4096 字节的块大小会产生相同的结果。
最后,dd 在运行过程中不会产生任何输出,而且由于分区的大小,它需要相当长的时间才能完成。如果你想查看它在哪里,你应该打开一个新的控制台会话(在我的情况下是一个新的 ssh 远程会话,因为我是远程执行的)并发出命令:
# kill -USR1 $(pidof dd)
这将强制 dd 在第一个控制台会话中打印其当前进度。
4. 使 sda 可启动。
这很简单。首先,您需要在 sda 上安装必要的挂载点:
# mount -t ext4 /dev/sda3 /mnt
# mount -t proc proc /mnt/proc
# mount -t sysfs sys /mnt/sys
# mount -o bind /dev /mnt/dev
# mount -t ext3 /dev/sda2 /mnt/boot
注意:如果您的系统中没有单独的 /boot 分区,则不需要最后一个命令。
接下来您需要成为 /dev/sda 磁盘上的根用户,现在您是救援系统中的根用户。
# chroot /mnt /bin/bash
接下来我们需要更新我们的 etc/mtab 文件。我真的不知道我们为什么要这么做,我在另一个救援教程中找到了它,但没有解释。
# grep -v rootfs /proc/mounts > /etc/mtab
接下来我们需要在 sda 中安装 GRUB。
# grub-install --recheck /dev/sda
输出:
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
现在我们已经准备好启动 sda,但是还需要一些步骤才能让系统知道从 sda 启动后在哪里找到必要的文件。
第一件事是编辑/boot/grub/grub.conf文件,这是 GRUB 将读取的文件,以便了解它将如何继续。在我的例子中,我必须替换每个“根(hd0,0)”实例“根(hd0,1)”以及每一个“/dev/md2”实例“/dev/sda3”。
grub配置文件可能会非常令人困惑,尤其是对于以前没有使用过它的人来说。最令人困惑的部分是 root 参数,在 grub 中,root 一词有两种不同的含义。当它显示为“root (hd0,1)”时,它会告诉 grub 它的根目录在哪里,以便找到所需的 linux 内核以及如何启动它们的说明。许多人在系统完全启动时将其与系统上的根“/”目录混淆,但 grub 在这里需要的是 /boot 目录的位置。在这种情况下,我有一个单独的分区 (/dev/sda2),其中包含 /boot 目录,并且因为 /dev/sda2 是第一个磁盘的第二个分区,所以我需要准确地告诉 grub,但从零开始(第一个分区是 0,第二个是 1,依此类推),因此命令“root (hd0,1)”告诉 grub 它将在第一张磁盘的第二个分区上找到所需的文件。
当 root 显示为“/dev/”时,它会告诉内核文件系统的 root 在哪里,即系统完全启动时的“/”。因此,在这种情况下,我们在“/”所在的位置输入分区名称(Linux 所看到的),在我的情况下是 /dev/sda3。
最后我们需要编辑/etc/fstab文件来告诉系统在启动时要挂载什么以及在哪里挂载。
就我而言,我必须将所有“/dev/md*”条目替换为核心对应的“/dev/sda*”分区,这些分区如下:
/dev/md1 --> /dev/sda2
/dev/md2 --> /dev/sda3
/dev/md3 --> /dev/sda5
5.验证并禁用从 sdb 启动。
如果你像我一样有强迫症,那么你可能想跑步
# file -s /dev/sda
查看 sda 上是否安装了 grub。如果您得到如下输出:
/dev/sda: sticky x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, stage2 address 0x2000, stage2 segment 0x200, GRUB version 0.94;
然后 grub(GRand Unified Bootloader)安装在 sda 上。
尽管这不是必需的,但您可能希望从 sdd 中删除 grub。我这样做是因为如果上述配置出现问题,则系统将从 sdb 启动,这可能会造成混淆。为了从 sdb 中删除 grub,我使用了 dd:
# dd if=/dev/zero of=/dev/sdb bs=446 count=1
这会将零写入磁盘的前 446 个字节,这是 grub 在具有 msdos 分区表的磁盘中驻留的位置。
$ file -s /dev/sdb
这将检查 grub 是否已被删除。
6. 退出 chroot 并卸载所有内容。
# exit
# umount /mnt/boot
# umount /mnt/dev
# umount /mnt/sys
# umount /mnt/proc
# umount /mnt
如果在执行上述命令期间出现任何错误,则意味着某些操作尚未完成或者我们的 chroot 会话出现问题,我们可能需要重新开始。
7. 重新启动。
现在祈祷并重新启动
# reboot
如果您设法使用原始根凭据登录到服务器并且一切似乎正常运行(数据库、网站等),那么您已成功从 sda 启动。
8.准备sdb以供替换。
就我而言,我想在要求支持人员更换 sdb 之前删除其中的所有数据。此外,我需要从系统中完全删除 RAID 配置,以便在新磁盘到位后从头开始构建新配置。我首先运行 parted 来删除分区:
# parted /dev/sdb
# (parted) rm 5
# (parted) rm 4
# (parted) rm 2
# (parted) rm 2
# (parted) rm 1
# (parted) quit
然后我注意到每个 RAID 配置也被删除了,所以我假设 RAID 定义在分区内,所以我没有对此采取任何进一步的行动。然后我保护了擦除的 sdb。有很多方法可以做到这一点。我选择了/dev/urandom方法来自这里
答案2
最好不要尝试这样做,而是从头开始或做其他事情。当我刚接触 Linux 时,我不会尝试这样做。
话虽如此,您需要做的就是对 /dev/sda 进行分区并将它重新添加到 raid 阵列,重建后替换 /dev/sdb。确保 grub 位于两个磁盘上,并且 bios 在启动时会尝试两个磁盘。