web-dev-qa-db-ja.com

RAID(mdadm)-ドライブのサイズが一致しない場合はどうなりますか?

質問1-「小さいディスクを使用します」と答える前に、すぐに私に聞いてください。 3TB WD Redのサイズは3001 GBです。ドライブの100%にまたがるsdb1とsdc1のmdadmを介してミラーをセットアップしたとしましょう。しかし、突然、ドライブの1つが故障します。代替品は3TBで、重量は3000 GBです。アレイに現在存在するドライブより小さいドライブを挿入するとどうなりますか? 3000と3001を使用する新しいアレイでは、3000になるようにアレイが構築されます。しかし、先ほど言ったように、3001の現在のアレイはどうですか。再構築中にサイズが3000 GBになるように再構築されますか?

質問2-既存の3001 GBのアレイに3000 GBを追加できず、単純に3000に縮小した場合... 3001を少し縮小できますか?

質問3-または、より良いアイデア。 3TBドライブを2999 GBに縮小した場合はどうなりますか。ドライブが1 MB、1バイト、10 KB不足しているかどうかは関係ありません。2999GBの「より小さい」ドライブを常に選択します。

15
JaSauders

間違ってこの答えに出会いましたが、誰かが興味を持っている場合のために、実験によって裏付けられた答えがあります。

ショートバージョン

ボーナス質問:サイズが等しくないブロックデバイスからmd(4) RAIDアレイを作成できますか?はい、ただしRAIDアレイのサイズは最も小さいブロックデバイス(および独自のハウスキーピングのオーバーヘッド)デバイスのサイズが互いに1%以内にない場合、警告が表示されます。

質問1:現在の最小メンバーよりも小さいデバイスを既存のmd(4) RAIDアレイに追加できますか?いいえ、ごめんなさい。 mdadmは、データを保護するために拒否することを拒否します。

質問2:既存のmd配列のサイズを変更できますか?はい(mdadm manpgeを読んでください!)、しかし努力する価値はないかもしれません。すべてをバックアップしてから、RAIDデバイスの内容のサイズを変更してから、デバイス自体のサイズを変更する必要があります。これらはすべて、エラー、誤算、その他のデータの損失につながる傾向があります(会話の苦痛な経験) 。

リスクと労力の価値はありません。新しい空のディスクがある場合、サイズを変更する方法と、すべてのデータのコピーを常に1〜2個保持する方法を次に示します(2ディスクRAID1がある場合)。

  1. 新しいmd(4)配列を作成します(1つのディスクが欠落しています)。
  2. アレイの内容の構造を再作成します(暗号、LVM、パーティションテーブル、それらの任意の組み合わせ、ボートに浮かぶものは何でも)。
  3. 既存のディスクから新しいディスクにデータをコピーします。
  4. 新しいディスクを使用して再起動します。
  5. 古いディスクのパーティションテーブルを消去します(またはmd(4)スーパーブロックをゼロにします)。必要に応じて、新しいディスク上のスキームに一致するように必要なパーティションを作成します。
  6. 古いディスクを新しいアレイに追加します。
  7. アレイメンバーが同期するのを待ちます。コーヒーを飲みます。ラテンアメリカに飛んで、そのためにあなた自身のコーヒー豆を選んでください。 :)(inラテンアメリカに住んでいる場合は、代わりにアフリカに飛びます)。

注:はい、これは彼の答えで説明した0xC0000022Lと同じ手法です。

質問ドライブが1G不足の場合はどうなりますか? :)心配しないでください。交換用ドライブが大きくなる可能性があります。実際、上記のような戦略ではpaysが失敗するたびに(または安価なアップグレードのために)安価で大きなドライブを取得します。プログレッシブアップグレードを取得できます。

実験的証明

実験セットアップ

まず、いくつかのブロックデバイスを偽造しましょう。 /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

これにより、3つのファイルが3つのループバックブロックデバイスとして設定されます。/dev/loop0/dev/loop1および/dev/loop2、それぞれsdxsdyおよびsdzへのマッピング。サイズを確認しましょう:

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

予想どおり、100M(102400 KiB = 100 MiB)の2つのループデバイスと99M(正確に99×1024 1Kブロック)の1つのループデバイスがあります。

同一サイズのデバイスから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です。2回目の実験に備えて破壊しましょう。

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ディスクの1つだけでRAID1アレイを作成しましょう。アレイは劣化しますが、実際には気にしません。 started配列が必要です。 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

ブーム!それは私たちをさせませんし、エラーは非常に明確です。

28
Alexios

mdXデバイスをセットアップするにはいくつかの方法があります。方法は、gdisk(またはコマンドラインのみのバージョンを好む場合はsgdisk)を使用して、これをGPTとしてパーティション分割することです。アレイからブートする場合は、「BIOSブートパーティション」を作成し、コードef02を入力します。これは、このアレイから起動する場合にのみ必要です。それ以外の場合は気にする必要はありません。次に、アレイに追加する最小ディスクと同じサイズまたはそれより小さいパーティションを作成します。最後に、GPTデータを他のディスクにコピーします(gdiskのエキスパートメニュー、x、次にuを使用してターゲットデバイスを指定します)。これは破壊的なプロセスです。

ファイルシステムで許可されている場合は、既存のパーティションのサイズを小さくしてから、同じ方法を使用してGPTデータをコピーすることが可能です。ただし、これにより、ちょっとした混乱が生じます。なぜなら今では2つのディスクがありますが、mdXデバイスはまだないからです。そのうちの1つは、パーティションごと(上記で暗示しています)またはディスクごとに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を使用する場合は、mdadm -e 0 ...を使用してメタデータバージョン0.9で「BIOSブートパーティション」を作成する必要もあり、プロセスは異なります。しかし、私はそれをしていません。

1
0xC0000022L