linux

Wie migriere ich mdadm RAID10 mit 4 Festplatten zu RAID5

Ich habe ein Software-RAID10 basierend auf Linux' mdadm unter Debian Buster.Ursprünglich fand ich,dass RAID10 die beste Leistung hat.Aber ich brauche mehr Platz und akzeptiere,etwas Schreibleistung für +50% Platz einzutauschen.

# cat /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4]
md1 : active raid10 sdd1[5] sda1[4] sdb1[1] sdc1[2]
      3899738112 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU]
      bitmap: 3/30 pages [12KB], 65536KB chunk

unused devices: <none>

Dieser Speicher wird über NFS bereitgestellt,und im Idealfall könnte das RAID ohne Ausfallzeiten umgestellt werden.Ja,ich habe Backups und ein Ausfall wäre nicht kritisch,aber warum nicht ohne Unterbrechung migrieren,wenn es funktioniert.

Ich habe einen Artikel aus dem Jahr 2012 gefunden, der den Prozess beschreibt. Die Befehle erwiesen sich als richtig. Damals hatte der Autor Probleme, dass das mdadm - Dienstprogramm (oder wahrscheinlich der Kernel-Treiber) das System beim ersten Befehl sofort hängen ließ. Dieses Problem scheint seitdem behoben worden zu sein.

https://www.tummy.com/blogs/2012/03/29/changing-a-raid-10-into-a-raid-5/

Es gibt keinen direkten Pfad von RAID10→RAID5 in mdadm.Stattdessen müssen Sie zuerst das RAID0 degradieren:

# mdadm --grow /dev/md1 --level=0 --raid-devices=2
mdadm: /dev/md1: could not set level to raid0

Dies war sofort wirksam und führte dazu, dass 2 Geräte ausfielen und aus dem Array entfernt wurden. Leider war der RAID-Level nicht auf RAID0 eingestellt. dmesg zeigte:

md/raid0:md1: All mirrors must be already degraded!
md: md1: raid0 would not accept array

Ich stellte fest, dass das Problem darin bestand, dass sysfs das Array als nicht degradiert gemeldet hat, obwohl dies tatsächlich der Fall war, und mdadm und cat /proc/mdstat korrekt angezeigt wurden:

# cat /sys/block/md1/md/degraded
0

Ich fand keine andere Möglichkeit,dies zu beheben,als den NFS-Server zu stoppen,das Dateisystem auszuhängen,das LUKS-Gerät zu schließen,den RAID-Verbund zu stoppen,den RAID-Verbund neu zusammenzustellen und alle Dienste neu zu starten.Danach wurde es korrekt als degraded gemeldet und konnte in ein RAID0 umgewandelt werden.

Dann könnte ich sie mit RAID5 wieder auf 4 Geräte erweitern:

# mdadm --grow /dev/md1 --level=5 --raid-devices=5 --add /dev/sdb1 /dev/sdd1

Anders als je zuvor zeigte cat /proc/mdstat keinen laufenden „Rebuild“, sondern ein „Reshape“. Dies dauerte eine ganze Weile (ca. 10 Stunden) und das System reagierte viel langsamer als bei RAID10-Neuaufbauten. Ich habe es für die Umbauzeit in Ruhe gelassen.

Seit der Neugestaltung ist das RAID5 sauber und die Geschwindigkeit ist gut.Wahrscheinlich habe ich bei der Messung Fehler gemacht,aber die Lesegeschwindigkeit ist jetzt schneller als vorher und die Schreibgeschwindigkeit ist für mich auch akzeptabel.

# cat /proc/mdstat
Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] 
md1 : active raid5 sdd1[5] sdb1[3] sda1[4] sdc1[7]
      5849607168 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]

unused devices: <none>

(Haftungsausschluss: Die ganze Geschichte wurde aufgeschrieben, als die Migration bereits abgeschlossen war. Ich habe versucht, die eigentlichen Befehle und Fehlermeldungen sorgfältig zu beschreiben, aber es können kleinere Fehler enthalten sein. Der Gesamtprozess funktionierte wie beschrieben.)




(Noch) nicht getestet (vertrauen Sie den folgenden Schritten nicht auf wichtige Daten), aber hier eine Idee für jedes Szenario, in dem der nutzbare Speicherplatz erhöht wird und mdadm --grow sagt: "RAID10-Layout zu komplex für den Grow-Betrieb":

  1. Anhalten des md
  2. Sichern Sie die ersten paar MiB jeder Partition der md (unter der Annahme,dass sich die RAID-Superblöcke am Anfang jeder Partition befinden)
  3. Wischen Sie die Superblöcke
  4. Erstellen Sie ein RAID5 (oder ein anderes RAID) mit --assume-clean unter Verwendung der Partitionen
  5. Erstellen Sie Snapshots von jeder Partition des MD, folgen Sie z. B. https://gist.github.com/jowagner/b36024636140ddf453c12eaf6e590b5d
  6. Wiederherstellung der Sicherungskopie der Partitionen aus Schritt 2 in Schnappschüsse der Partitionen
  7. Stellen Sie das RAID10 aus den Snapshots zusammen
  8. dd zum RAID5 hinzu. Die Verwendung des kleinsten gemeinsamen Vielfachen der 2 Stripe-Größen ist wahrscheinlich am besten für die Leistung, aber jede Blockgröße sollte ausreichen. Die ersten Lesevorgänge werden durch die Schreibvorgänge nicht beschädigt, da sie von Copy-on-Write-Daten stammen, die in Schritt 5 geschrieben wurden. Die verbleibenden Lesevorgänge werden nicht beschädigt, da sie mit einem sicheren Abstand von den Schreibvorgängen auf jeder Partition voraus sind (daher die Beschränkung dieser Idee auf Szenarien, in denen der nutzbare Raum vergrößert wird).
  9. Anhalten des RAID10
  10. Verwerfen der Schnappschüsse

Dabei wird davon ausgegangen,dass ein Snapshot nur Schreibvorgänge auf ein COW-Gerät umleitet und dass Schreibvorgänge auf das Ursprungsgerät nicht dazu führen,dass eine Kopie der alten Daten auf dem COW-Gerät gespeichert wird (andernfalls wäre die Lösung nicht praktikabel,da zu viel zusätzlicher Speicherplatz benötigt wird).

Wenn sich die Superblöcke des alten RAID in der Nähe des Endes der einzelnen Partitionen befinden,müssen diese Daten ebenfalls vor Schritt 3 gesichert werden.Berechnen Sie eine geeignete Position für den Suchlauf und die Datenmenge.Ich würde ein paar Zeilen Python verwenden,aber wahrscheinlich gibt es auch ein Kommandozeilen-Tool,das das erledigen kann.