web-dev-qa-db-ja.com

MDRAIDでスーパーブロックを失った

Red Hat Linux5での問題。

いくつかの誤解により、環境内の2つのLUNが1.2 TBから1.7TBに拡大されました。

これで、再起動後、mdadmはアレイを再構築するためのスーパーブロックを見つけられません。

一般的なフォーマット(バージョン0.90として知られています)には、4Kの長さのスーパーブロックがあり、デバイスの端から少なくとも64Kから128K未満で始まる64K整列ブロックに書き込まれます(つまり、スーパーブロックのアドレスを取得するためにデバイスのサイズを64Kの倍数に減らしてから、64Kを引きます)。

私はいくつかの古いドキュメントを見つけました:

# mdadm -D /dev/md0
/dev/md0:
        Version : 0.90
  Creation Time : Tue Jul 10 17:45:00 2012
     Raid Level : raid1
     Array Size : 1289748416 (1230.00 GiB 1320.70 GB)
  Used Dev Size : 1289748416 (1230.00 GiB 1320.70 GB)
   Raid Devices : 2
  Total Devices : 2
Preferred Minor : 0
    Persistence : Superblock is persistent

    Update Time : Wed Apr 17 15:03:50 2013
         State : active
Active Devices : 2
Working Devices : 2
Failed Devices : 0
  Spare Devices : 0

           UUID : 2799bd51:67eb54d2:1fcd3c90:293311a1
         Events : 0.39

    Number   Major   Minor   RaidDevice State
       0     253       10        0      active sync   /dev/dm-10
       1     253       11        1      active sync   /dev/dm-11

# fdisk -l /dev/dm-10 /dev/dm-11

Disk /dev/dm-10: 1320.7 GB, 1320702443520 bytes
255 heads, 63 sectors/track, 160566 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/dm-10 doesn't contain a valid partition table

Disk /dev/dm-11: 1320.7 GB, 1320702443520 bytes
255 heads, 63 sectors/track, 160566 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/dm-11 doesn't contain a valid partition table
4
ddeimeke

デバイスを元のサイズに戻すと、RAIDデバイスが復元されます。

次のようにして確認できます。

losetup --sizelimit=$((1230*(2**30))) -r /dev/loop1 /dev/dm-10
mdadm -E /dev/loop1

サイズが正しければ、mdadmはスーパーブロックを見つけるはずです。次に、ディスクのサイズをそのサイズに戻すことができます(上記の-rは読み取り専用であるため、害はありません)。

実際にmd0配列を拡大し、0.9メタデータを保持したい場合は、次のことができます。

dmsetup create d1 --table "0 $((1230*(2**30)/512)) linear /dev/dm-10 0"
dmsetup create d2 --table "0 $((1230*(2**30)/512)) linear /dev/dm-11 0"

もう一度、

mdadm -E /dev/mapper/d1

レイドデバイスを表示する必要があります。

これらのマッパーデバイスでアレイをアセンブルします。

mdadm -A /dev/md0 /dev/mapper/d[12]

次に、デバイスのサイズを完全に変更します。

dmsetup suspend d1
dmsetup suspend d2
dmsetup reload d1 --table "0 $(blockdev --getsize /dev/dm-10) linear /dev/dm-10 0"
dmsetup reload d2 --table "0 $(blockdev --getsize /dev/dm-11) linear /dev/dm-11 0"
dmsetup resume d1
dmsetup resume d2

次に、--growを使用してその余分なスペースを使用できます。

mdadm /dev/md0 --grow --size max

余分なスペースが再同期されるのを待ち、アレイを停止し、余分なdmデバイスをクリーンアップして、元のデバイスで再アセンブルします。

mdadm --stop /dev/md0
dmsetup remove d1
dmsetup remove d2
mdadm -A /dev/md0 /dev/dm-1[01]

ループデバイスを使用して事前にテストを行い、手順を確認できます。これが機能することを確認するために私がしたことのスクリーンキャプチャです:

~# truncate -s 1230G a
~# truncate -s 1230G b
~# losetup /dev/loop1 a
~# losetup /dev/loop2 b
~# lsblk /dev/loop[12]
NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop1   7:32   0   1.2T  0 loop
loop2   7:64   0   1.2T  0 loop
~# mdadm --create /dev/md0 --metadata 0.9 --level 1 --raid-devices 2 --assume-clean /dev/loop[12]
mdadm: array /dev/md0 started.
~# lsblk /dev/md0
NAME MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
md0    9:0    0   1.2T  0 raid1
~# truncate -s 1700G a
~# truncate -s 1700G b
~# losetup -c /dev/loop1
~# losetup -c /dev/loop2
~# lsblk /dev/loop[12]
NAME  MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
loop1   7:32   0   1.7T  0 loop
└─md0   9:0    0   1.2T  0 raid1
loop2   7:64   0   1.7T  0 loop
└─md0   9:0    0   1.2T  0 raid1
~# mdadm -E /dev/loop1
mdadm: No md superblock detected on /dev/loop1.
(1)~# mdadm --stop /dev/md0
mdadm: stopped /dev/md0
~# dmsetup create d1 --table "0 $((1230*(2**30)/512)) linear /dev/loop1 0"
~# dmsetup create d2 --table "0 $((1230*(2**30)/512)) linear /dev/loop2 0"
~# mdadm -A /dev/md0 /dev/mapper/d[12]
mdadm: /dev/md0 has been started with 2 drives.
~# lsblk /dev/mapper/d[12]
NAME       MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
d1 (dm-19) 253:19   0   1.2T  0 dm
└─md0        9:0    0   1.2T  0 raid1
d2 (dm-20) 253:20   0   1.2T  0 dm
└─md0        9:0    0   1.2T  0 raid1
~# dmsetup suspend d1
~# dmsetup suspend d2
~# dmsetup reload d1 --table "0 $(blockdev --getsize /dev/loop1) linear /dev/loop1 0"
~# dmsetup reload d2 --table "0 $(blockdev --getsize /dev/loop2) linear /dev/loop2 0"
~# dmsetup resume d1
~# dmsetup resume d2
~# lsblk /dev/mapper/d[12]
NAME       MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
d1 (dm-19) 253:19   0   1.7T  0 dm
└─md0        9:0    0   1.2T  0 raid1
d2 (dm-20) 253:20   0   1.7T  0 dm
└─md0        9:0    0   1.2T  0 raid1
~# mdadm /dev/md0 --grow --assume-clean --size max
mdadm: component size of /dev/md0 has been set to 1782579136K
~# lsblk /dev/md0
NAME MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
md0    9:0    0   1.7T  0 raid1
~# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 dm-19[0] dm-20[1]
      1782579136 blocks [2/2] [UU]

unused devices: <none>
~# mdadm --stop /dev/md0
mdadm: stopped /dev/md0
~# dmsetup remove d1
~# dmsetup remove d2
~# mdadm -A /dev/md0 /dev/loop[12]
mdadm: /dev/md0 has been started with 2 drives.
~# lsblk /dev/md0
NAME MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
md0    9:0    0   1.7T  0 raid1
~# uname -rs
Linux 3.7-trunk-AMD64
2

mdadm --build -l1 -n2 /dev/md0 /dev/dm-10 /dev/dm11を実行するだけで、データを取り戻すことができます。

これを行う前に、デバイスが正しいことを確認してください(または/ dev/mapperのエイリアスを使用してください!

また、カーネルがこれらのデバイスの1つをすでに使用している(または使用している)場合、データに一貫性がなくなります。 2番目のデバイスを縮退1.2アレイとしてセットアップし、データをコピーして、新しい縮退RAIDの使用を開始し、最初のディスクをそれに追加する必要があります。 現在のバックアップがない場合は、これを試みる前に何をすべきかを知っておいてください。

(1.2 RAIDスーパーブロックはこの種の問題を防ぐため、とにかく1.2に切り替えることをお勧めします。)

6

0.90スーパーブロックを備えたRAID1の場合、RAIDレイヤーをまったく使用せずに直接マウントできるはずです。データはディスクの先頭からオフセットなしで開始されるため、問題はありません。万が一の場合に備えて、実験には読み取り専用マウントオプションまたは読み取り専用ループデバイスを使用してください。

それが機能する場合、最も簡単な方法は、他のディスクを使用して新しいRAIDを最初から作成し(できれば1.2メタデータで、この問題を回避し、2 TBの制限を受けない)、データをコピーして、それが完了したら完了したら、コピー元のディスクを新しいRAIDに追加します。

4
frostschutz