RAID(mdadm)-如果驱动器大小不匹配会怎样?


15

问题1-在回答“它只占用较小的磁盘”之前,请快速听我说。我的3TB WD Reds的大小为3001 GB。假设我通过mdadm为sdb1和sdc1设置了一个镜像,该镜像跨越了100%的驱动器。但是突然,其中一个驱动器发生故障。替换为3TB,重为3000 GB。当我放入的驱动器比阵列上当前存在的驱动器小时,会发生什么情况?我知道使用3000 vs 3001的新阵列会把阵列构建为3000。但是就像我说的,当前阵列@ 3001会如何,我添加一个较小的驱动器?是否在重建过程中将自身重新构造为3000 GB?

问题2-如果无法将3000 GB的数据添加到现有3001 GB的阵列中,并且大小只能缩小到3000,我可以将3001的尺寸缩小一点吗?

问题3-还是一个更好的主意。如果我将3TB驱动器减小到2999 GB,该怎么办。这样,驱动器是否短缺1 MB,1字节,10 KB都没有关系,它将始终使用2999 GB的“较小”驱动器。

Answers:


28

我错误地遇到了这个答案,但是如果有人好奇,这是实验支持的答案。

短版

奖励问题:我可以使用md(4)大小不等的块设备创建RAID阵列吗?是的,但是RAID阵列将具有小块设备的大小(加上一些内部管理开销)。如果设备大小彼此之间的误差不超过1%,则会收到警告。

问题1:我可以md(4)将比当前最小成员小的设备添加到现有RAID阵列吗?不,谢谢。mdadm会拒绝这样做以保护您的数据。

问题2:您可以调整现有md数组的大小吗?是的(请阅读mdadm手册!),但是这样做可能不值得。您必须备份所有内容,然后重新调整RAID设备的内容大小,然后重新调整设备本身的大小-所有这些都非常容易出错,计算错误以及其他会浪费您数据的事情(痛苦的谈话经验) 。

这不值得冒险和付出。如果您有一个新的空白磁盘,请执行以下操作以调整其大小,并始终保持所有数据的一到两个副本不变(假设您拥有2磁盘RAID1):

  1. md(4)在上面创建一个新阵列(缺少一个磁盘)。
  2. 重新创建数组内容的结构(Crypto,LVM,分区表,它们的任意组合,无论浮出水面)。
  3. 将数据从现有磁盘复制到新磁盘。
  4. 使用新磁盘重新启动。
  5. 擦除旧磁盘的分区表(或将md(4)超级块清零)。如有必要,请创建所需的分区以匹配新磁盘上的方案。
  6. 将旧磁盘添加到新阵列。
  7. 等待阵列成员同步。喝杯咖啡 为此,飞往拉丁美洲,并选择自己的咖啡豆。:)(如果您居住拉丁美洲,请飞往非洲)。

注意:是的,这与他的答案中描述的技术0xC0000022L相同。

问题3.如果驱动器短1G,该怎么办?:)不用担心。您的替换驱动器可能会更大。实际上,采用上述策略后,每当发生故障时(或更便宜的升级),可以获得便宜的大型驱动器。您可以逐步升级。

实验证明

实验装置

首先,让我们伪造一些块设备。我们将使用/tmp/sdx/tmp/sdy(每个100M)和/tmp/sdz(99M)。

cd /tmp
dd if=/dev/zero of=sdx bs=1M count=100
sudo losetup -f sdx
dd if=/dev/zero of=sdy bs=1M count=100
sudo losetup -f sdy
dd if=/dev/zero of=sdz bs=1M count=99  # Here's a smaller one!
sudo losetup -f sdz

这就建立了三个文件三个环回块设备:/dev/loop0/dev/loop1/dev/loop2,映射sdxsdysdz分别。让我们检查一下大小:

sudo grep loop[012] /proc/partitions
   7        0     102400 loop0
   7        1     102400 loop1
   7        2     101376 loop2

如预期的那样,我们有两个正好为100M(102400 KiB = 100 MiB)的环路设备和一个99M(恰好是99×1024 1K块)的环路设备。

使用大小相同的设备制作RAID阵列

开始:

sudo mdadm  --create -e 1.2 -n 2 -l 1 /dev/md100 /dev/loop0 /dev/loop1
mdadm: array /dev/md100 started.

检查尺寸:

sudo grep md100 /proc/partitions
   9      100     102272 md100

恰好是我们所期望的:一看mdadm手册,便会提醒我们1.2版元数据占用了128K:128 + 102272 =102400。现在我们将其销毁以准备第二个实验。

sudo mdadm --stop /dev/md100
sudo mdadm --misc --zero-superblock /dev/loop0
sudo mdadm --misc --zero-superblock /dev/loop1

利用大小不均的设备制作RAID阵列

这次,我们将使用小型块设备。

sudo mdadm  --create -e 1.2 -n 2 -l 1 /dev/md100 /dev/loop0 /dev/loop2
mdadm: largest drive (/dev/loop0) exceeds size (101248K) by more than 1%
Continue creating array? y
mdadm: array /dev/md100 started.

好吧,我们被警告了,但是阵列已经制作好了。让我们检查一下大小:

sudo grep md100 /proc/partitions
   9      100     101248 md100

我们得到的是101,248个区块。101248 + 128 = 101376 = 99×1024。可用空间是最小设备的空间(加上128K RAID元数据)。让我们在上一个实验中再次将其归结为:

sudo mdadm --stop /dev/md100
sudo mdadm --misc --zero-superblock /dev/loop0
sudo mdadm --misc --zero-superblock /dev/loop2

最后:将较小的设备添加到正在运行的阵列

首先,让我们制作一个仅包含100M磁盘之一的RAID1阵列。阵列将降级,但我们并不在乎。我们只想要一个开始的数组。该missing关键字是一个占位符,上面写着“我没有为你的设备还没有,现在就开始他阵列,我会以后再添加一个”。

sudo mdadm  --create -e 1.2 -n 2 -l 1 /dev/md100 /dev/loop0 missing

再次,让我们检查一下大小:

sudo grep md100 /proc/partitions
   9      100     102272 md100

果然,它比102400块少128K。添加较小的磁盘:

sudo mdadm  --add /dev/md100 /dev/loop2
mdadm: /dev/loop2 not large enough to join array

繁荣!它不会让我们这样做,而且错误非常明显。


Synology混合RAID(SHR)解决了此问题。
Denis Denisov

1

有几种设置mdX设备的方法。该方法将使用gdisk(或sgdisk如果您更喜欢仅命令行版本)将其分区为GPT。如果要从阵列引导,请创建“ BIOS引导分区”,键入code ef02。仅在要从该阵列引导时才需要这样做,否则无需关心。然后,创建一个大小等于或小于要添加到阵列的最小磁盘的分区。最后但并非最不重要的一点是,将GPT数据复制到另一个磁盘上(gdisk使用中的x,然后使用,然后u指定目标设备)。这是一个破坏性的过程。

如果文件系统允许,应该可以将现有分区的大小调整为较小的大小,然后使用相同的方法来复制GPT数据。但是,这会使您陷入困境。因为现在您有两个磁盘,但是仍然没有mdX设备。其中之一必须准备为mdX分区级(我在上面暗示)或磁盘级),然后必须将数据从现有磁盘移至该分区。

所以:

  1. 大磁盘(/dev/sda)包含数据,数据小于3001 GB,没有分区
  2. 较小的磁盘/dev/sdb被添加到系统
  3. 你的分区/dev/sdbgdisk
  4. 您可以通过每个分区创建一个数组(mdadm -C /dev/md2 -l 1 -n 1 /dev/sdb2
  5. 您在新阵列上创建文件系统
  6. 复制所有数据,确保您的系统已准备好在GPT磁盘上运行,并使GRUB2了解其中的含义(请参见下文)
  7. 您将GPT分区数据从复制/dev/sdb/dev/sda
  8. 您将“原始”分区从添加/dev/sda到现有阵列中
  9. 等待/proc/mdstat显示同步完成

如果执行了所有步骤,您现在应该能够从mdX阵列启动到新系统中。但是,请随身携带应急CD或PXE引导选项,以防万一。


GRUB2将无法立即识别设置。因此,您需要一些“魔术”。这里是单线:

for i in /dev/disk/by-id/md-uuid-*; do DEV=$(readlink $i); echo "(${DEV##*/}) $i"; done|sort|tee /boot/grub/devicemap

或者让我们更详细些:

for i in /dev/disk/by-id/md-uuid-*
do
  DEV=$(readlink $i)
  echo "(${DEV##*/}) $i"
done|sort|sudo tee /boot/grub/devicemap

这会创建一个(或覆盖)默认值/boot/grub/devicemap,并告诉GRUB2在哪里可以找到每个相应的磁盘。结果将类似于以下列表:

(md0) /dev/disk/by-id/md-uuid-...
(md2) /dev/disk/by-id/md-uuid-...
(md3) /dev/disk/by-id/md-uuid-...
(md4) /dev/disk/by-id/md-uuid-...

如果使用旧版GRUB,则还需要使用元数据版本0.9创建“ BIOS引导分区”,使用mdadm -e 0 ...和过程将有所不同。不过,我还没有这样做。


1
感谢您的回复。该阵列实际上仅用于我的服务器上的原始存储,因此它不会处理引导等问题。我只是担心稍后在游戏中混合和匹配不同大小的硬盘。我的意思是,如果我有sdb1 @ 3001 GB和sdc1 @ 3001 GB,但是sdc1死了,而替换为3000 GB,会发生什么情况?sdb1是否减小到3000?数组@ / dev / md0是否减小到3000 GB?我考虑得越多,最后留出空间就越有意义,例如上面的2999示例-这样就可以消除这种头痛。除非我想念什么?
JaSauders

1
实际上,假设这里的RAID级别为1,mdadm如果不兼容,则首先将拒绝构建该阵列。在RAID 5中,您最终将需要更多磁盘,而在RAID 0中,您将不在乎它,这就是为什么我假设使用RAID1。所以,是的,留出空间是有意义的。
0xC0000022L13年

我并不是要打败这匹马,但是我对您所说的“不兼容”声明有些不确定。什么是不兼容的?在我的示例中,您是否参考了3000 GB与3001 GB的大小差异?无论哪种方式,我都只运行了每个分区为2999 GB的阵列,即使每个磁盘为3001 GB。如果我无法获得相同的替换驱动器,这应该可以消除所有麻烦。感谢您的见识!
JaSauders

@JaSauders:我认为一个或多个GiB已经不兼容了。但坦率地说,我不知道限制在哪里。但是,我知道可以容忍大小上的微小差异。对于其他所有内容,您都必须按照与我概述的方式进行迁移。
0xC0000022L

@ 0xC0000022L:mdadm允许数组成员中大小差异的任意1%。
Alexios 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.