RAID (mdadm) - Was passiert, wenn die Größe der Laufwerke nicht übereinstimmt?


15

Frage 1 - Bevor Sie mit "es dauert nur die kleinere Festplatte" antworten, hören Sie mich schnell aus. Meine 3 TB WD Reds haben eine Größe von 3001 GB. Nehmen wir an, ich habe über mdadm einen Spiegel für sdb1 und sdc1 eingerichtet, der sich über 100% des Laufwerks erstreckt. Aber plötzlich fällt eines der Laufwerke aus. Der Ersatz ist ein 3-TB-Speicher mit einem Gewicht von 3000 GB. Was passiert, wenn ich ein Laufwerk einlege, das kleiner ist als das derzeit auf dem Array vorhandene? Ich weiß, dass bei einem neuen Array mit 3000 vs 3001 das Array 3000 sein würde. Aber wie gesagt, was ist mit einem aktuellen Array @ 3001 und einem kleineren Laufwerk? Wird es während des Wiederaufbaus auf eine Größe von 3000 GB umstrukturiert?

Frage 2 - Kann ich dem Array mit 3001 GB keine 3000 GB hinzufügen und es einfach auf 3000 GB verkleinern? Kann ich die 3001 ein wenig verkleinern?

Frage 3 - Oder eine bessere Idee. Was ist, wenn ich mein 3-TB-Laufwerk auf 2999 GB verkleinere? Auf diese Weise spielt es keine Rolle, ob das Laufwerk um 1 MB, 1 Byte, 10 KB zu kurz ist, sondern immer das "kleinere" Laufwerk mit 2999 GB.

Antworten:


28

Ich bin versehentlich auf diese Antwort gestoßen, aber falls jemand neugierig ist, hier eine Antwort, die durch Experimente gestützt wird.

Die kurze Version

Bonusfrage: Kann ich ein md(4)RAID-Array aus Blockgeräten ungleicher Größe erstellen ? Ja, aber das RAID-Array hat die Größe des kleinsten Blockgeräts (zuzüglich einiger Overheads für die eigene Verwaltung). Wenn die Gerätegrößen nicht innerhalb von 1% voneinander liegen, erhalten Sie eine Warnung.

Frage 1: Kann ich einem vorhandenen md(4)RAID-Array ein Gerät hinzufügen, das kleiner ist als das kleinste aktuelle Mitglied? Nein Entschuldigung. mdadmwird sich weigern, dies zu tun, um Ihre Daten zu schützen.

Frage 2: Können Sie die Größe eines vorhandenen MD-Arrays ändern? Ja (lesen Sie die mdadmManpge!), Aber es kann die Mühe nicht wert sein. Sie müssen alles sichern, dann die Größe des Inhalts des RAID-Geräts und dann die Größe des Geräts selbst ändern - all dies ist sehr anfällig für Fehler, Fehleinschätzungen und andere Dinge, die Sie Ihre Daten kosten (schmerzhafte Erfahrung beim Sprechen). .

Es ist das Risiko und den Aufwand nicht wert. Wenn Sie einen neuen, leeren Datenträger haben, können Sie die Größe wie folgt ändern und auch zwischen einer und zwei Kopien aller Ihrer Daten jederzeit intakt halten (vorausgesetzt, Sie haben RAID1 mit zwei Datenträgern):

  1. Erstellen Sie ein neues md(4)Array (eine Festplatte fehlt).
  2. Erstellen Sie die Struktur des Array-Inhalts neu (Crypto, LVM, Partitionstabellen, beliebige Kombinationen davon, je nachdem, was auf Ihrem Boot schwimmt).
  3. Kopieren Sie die Daten von der vorhandenen Festplatte auf die neue.
  4. Starten Sie mit der neuen Festplatte neu.
  5. Löschen Sie die Partitionstabelle der alten Festplatte (oder setzen Sie den md(4)Superblock auf Null ). Erstellen Sie bei Bedarf die erforderlichen Partitionen, die dem Schema auf der neuen Festplatte entsprechen.
  6. Fügen Sie die alte Festplatte dem neuen Array hinzu.
  7. Warten Sie, bis die Array-Mitglieder synchronisiert sind. Kaffee trinken. Fliegen Sie nach Lateinamerika und pflücken Sie Ihre eigenen Kaffeebohnen. :) (Wenn Sie in Lateinamerika leben, fliegen Sie stattdessen nach Afrika).

Hinweis: Ja, dies ist die gleiche Technik, die 0xC0000022L in seiner Antwort beschrieben hat.

Frage 3. Was ist, wenn das Laufwerk 1 GB kurz ist? :) Mach dir keine Sorgen. Möglicherweise ist Ihr Ersatzlaufwerk größer. In der Tat lohnt es sich bei einer Strategie wie oben, bei jedem Ausfall billigere größere Laufwerke zu kaufen (oder ein billigeres Upgrade). Sie können ein progressives Upgrade erhalten.

Experimenteller Beweis

Versuchsaufbau

Lassen Sie uns zunächst einige Blockgeräte vortäuschen. Wir werden /tmp/sdxund /tmp/sdy(jeweils 100M) und /tmp/sdz(99M) verwenden.

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

Dies stellt drei Dateien als drei Loopback - Block - Geräte: /dev/loop0, /dev/loop1und /dev/loop2, Mapping sdx, sdyund sdzjeweils. Lassen Sie uns die Größen überprüfen:

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

Wie erwartet haben wir zwei Loop-Geräte mit genau 100 MB (102400 KiB = 100 MiB) und eines mit 99 MB (genau 99 × 1024 1K-Blöcke).

Erstellen eines RAID-Arrays aus Geräten mit identischer Größe

Hier geht:

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

Überprüfen Sie die Größe:

sudo grep md100 /proc/partitions
   9      100     102272 md100

Dies ist precicely , was wir erwarten: ein Blick auf die mdadm Handbuch erinnert uns , dass die Version 1.2 Metadaten 128K nehmen: 128 + 102272 = 102400. Nun wollen wir es in der Vorbereitung für den zweiten Versuch zu zerstören.

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

Erstellen eines RAID-Arrays aus ungleich großen Geräten

Dieses Mal werden wir das Small Block-Gerät verwenden.

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.

Nun, wir wurden gewarnt, aber das Array wurde gemacht. Lassen Sie uns die Größe überprüfen:

sudo grep md100 /proc/partitions
   9      100     101248 md100

Was wir hier bekommen, sind 101.248 Blöcke. 101248 + 128 = 101376 = 99 × 1024. Der verwendbare Speicherplatz ist der des kleinsten Geräts (plus 128 KB RAID-Metadaten). Lassen Sie uns für unser letztes Experiment noch einmal alles zusammenfassen:

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

Und schließlich: Hinzufügen eines kleineren Geräts zu einem laufenden Array

Lassen Sie uns zunächst ein RAID1-Array mit nur einer der 100M-Festplatten erstellen. Das Array wird herabgesetzt, aber das interessiert uns nicht wirklich. Wir wollen nur ein gestartetes Array. Das missingSchlüsselwort ist ein Platzhalter mit der Aufschrift "Ich habe noch kein Gerät für Sie, starte das Array jetzt und füge es später hinzu".

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

Überprüfen wir noch einmal die Größe:

sudo grep md100 /proc/partitions
   9      100     102272 md100

Sicher genug, es ist 128K kurz von 102400 Blöcken. Hinzufügen der kleineren Festplatte:

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

Boom! Es lässt uns nicht, und der Fehler ist sehr klar.


1

Es gibt verschiedene Möglichkeiten, mdXGeräte einzurichten . Die Methode wäre, dies als GPT zu partitionieren gdisk(oder sgdiskwenn Sie nur die Befehlszeilenversion bevorzugen). Wenn Sie vom Array booten möchten, erstellen Sie eine "BIOS-Boot-Partition", geben Sie Code ein ef02. Dies ist nur erforderlich, wenn Sie von diesem Array booten möchten, andernfalls besteht kein Grund zur Sorge. Erstellen Sie dann eine Partition mit der gleichen Größe oder kleiner als die kleinste Festplatte, die dem Array hinzugefügt werden soll. Kopieren Sie zu guter Letzt die GPT-Daten auf die andere Festplatte (Expertenmenü in gdisk, mit xund dann uund geben Sie das Zielgerät an). Dies ist ein destruktiver Prozess.

Wenn das Dateisystem dies zulässt, sollte es möglich sein, die Größe einer vorhandenen Partition auf eine kleinere Partition zu ändern und die GPT-Daten auf dieselbe Weise zu kopieren. Dies bringt Sie jedoch in eine Art Kerfuffle. Denn jetzt hast du zwei Festplatten, aber immer noch kein mdXGerät. Einer von ihnen muss mdXentweder partitioniert (was ich oben angedeutet habe) oder festplattenweise vorbereitet werden , und dann müssen die Daten von der vorhandenen Festplatte auf diese verschoben werden.

So:

  1. big disk ( /dev/sda) enthält Daten, Daten sind kleiner als 3001 GB, Partitionen nicht
  2. Eine kleinere Festplatte /dev/sdbwird zum System hinzugefügt
  3. Sie partitionieren /dev/sdbmitgdisk
  4. Sie erstellen ein Array aus den jeweiligen Partitionen ( mdadm -C /dev/md2 -l 1 -n 1 /dev/sdb2)
  5. Sie erstellen Dateisysteme auf den neuen Arrays
  6. Sie kopieren alle Daten, stellen sicher, dass Ihr System für die Ausführung einer GPT-Festplatte vorbereitet ist, und bringen GRUB2 dazu, die Auswirkungen zu verstehen (siehe unten).
  7. Sie kopieren die GPT-Partitionierungsdaten von /dev/sdbnach/dev/sda
  8. Sie fügen die "rohen" Partitionen /dev/sdain die vorhandenen Arrays ein
  9. Sie warten /proc/mdstatdarauf, Ihnen zu zeigen, dass die Synchronisierung abgeschlossen ist

Wenn Sie alle Schritte befolgt haben, sollten Sie nun in der Lage sein, das neue System von den mdX-Arrays aus zu starten. Halten Sie jedoch für alle Fälle eine Rettungs-CD oder eine PXE-Startoption bereit.


GRUB2 kann das Setup nicht sofort erkennen. Du brauchst also etwas "Magie". Hier ist ein Einzeiler:

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

Oder lassen Sie uns ausführlicher sein:

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

Dies erstellt (oder überschreibt) den Standardwert /boot/grub/devicemapmit einem, der GRUB2 mitteilt, wo sich die jeweiligen Datenträger befinden. Das Ergebnis wäre so etwas wie diese Liste:

(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-...

Wenn Sie Legacy-GRUB verwenden, müssen Sie auch die "BIOS-Boot-Partition" mit Metadaten der Version 0.9 erstellen. Die Verwendung von mdadm -e 0 ...und der Prozess unterscheiden sich. Das habe ich aber nicht getan.


1
Danke für deine Antwort. Dieses Array ist eigentlich nur für den Raw-Speicher auf meinem Server gedacht, sodass es nicht für das Booten oder ähnliches geeignet ist. Ich hatte nur Bedenken, später im Spiel Festplatten unterschiedlicher Größe zu mischen und anzupassen. Ich meine, was würde passieren, wenn ich sdb1 @ 3001 GB und sdc1 @ 3001 GB habe, aber sdc1 stirbt und der Ersatz 3000 GB beträgt? Verkleinert sdb1 auf 3000? Verkleinert das Array @ / dev / md0 auf 3000 GB? Je mehr ich darüber nachdenke, desto sinnvoller ist es, am Ende Platz zu lassen, wie im obigen Beispiel 2999 - auf diese Weise sollten diese Kopfschmerzen beseitigt werden. Es sei denn, ich vermisse etwas?
JaSauders

1
Unter der Annahme, dass hier RAID-Level 1 vorliegt, mdadmwürde das Array nicht erstellt, wenn es nicht kompatibel ist. In RAID 5 bräuchten Sie eventuell mehr Festplatten, und in RAID 0 kümmerte es Sie nicht, weshalb ich RAID 1 annahm. Also ist es sinnvoll, Platz zu lassen.
0xC0000022L

Ich habe nicht vor, das Pferd zu schlagen, aber ich bin mir ein wenig unsicher über die "inkompatible" Aussage, die Sie gemacht haben. Was wäre unvereinbar? Haben Sie in meinem Beispiel die Größenunterschiede zwischen 3000 GB und 3001 GB angegeben? In beiden Fällen habe ich nur mein Array mit 2999 GB Partition ausgeführt, obwohl jede Festplatte 3001 GB groß war. Dies sollte nur alle Kopfschmerzen beseitigen, die auf der ganzen Linie auftreten, falls ich keine identischen Ersatzlaufwerke bekomme. Schätzen Sie Ihre Einsicht!
JaSauders

@JaSauders: Ich denke ein GiB mehr oder weniger wäre schon inkompatibel. Aber ehrlich gesagt weiß ich nicht, wo die Grenze liegt. Ich weiß jedoch, dass geringfügige Abweichungen in der Größe toleriert werden. Für alles andere müssen Sie auf ähnliche Weise migrieren, wie ich es skizziert habe.
0xC0000022L

@ 0xC0000022L: mdadmToleriert einen willkürlichen Größenunterschied von 1% in Arraymitgliedern .
Alexios
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.