Kontakt
Anfahrt

Philipp-Reis-Str. 4
35398 Gießen

Standort anzeigen:
OpenStreetMap
Google-Maps

Reparatur eines defekten Software-RAIDs (mdadm)

Bei einem unserer Kunden wird ein NAS eingesetzt, das im Hintergrund das Linux Software-RAID mdadm nutzt. Nach einem geplanten Neustart hatte das NAS seine Informationen über das konfigurierte RAID10 verloren. In Folge konnte das RAID10 nicht mehr assembliert werden und es war kein Zugriff mehr auf die Daten möglich.

Unser Ziel war es nun, uns testweise an die Ursachenforschung und Fehlerbehebung zu machen, ohne aber den Ausgangszustand zu modifizieren. Da uns dies erfolgreich gelungen ist, möchten wir in diesem Blog-Beitrag unsere Praxis-Erfahrung teilen. Nachfolgend werden wir also Schritt für Schritt aufzeigen, wie an Hardware-Servern mit physikalischen Festplatten Tests am RAID möglich sind, ohne dass die physikalischen Festplatten verändert oder beschrieben werden. Das ist vor allem dann hilfreich, wenn man nicht mal eben das komplette RAID10-Volume oder die einzelnen Festplatten sichern kann, man aber einen sauberen oder unveränderten Stand der Festplatten benötigt.

Ausgangslage

Nach dem Neustart konnte das NAS das mdadm -Volume md1 nicht mehr starten.
Normalerweise sieht ein sauberes RAID so aus:

root@nas:/# cat /proc/mdstat ###linebreak### Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]###linebreak###md1 : active raid10 sdk2[0] sdd2[3] sdc2[2] sdj2[1]###linebreak###      3864801280 blocks super 1.1 512K chunks 2 near-copies [4/4] [UUUU]###linebreak###      bitmap: 0/29 pages [0KB], 65536KB chunk

In unserem Fall wurde md1 aber nicht mehr in /proc/mdstat aufgelistet.

Daraufhin haben wir geprüft, ob die vier Festplatten noch erkannt werden und die Informationen des RAID-Members auf der Festplatte im Superblock stehen.
Diese Informationen lassen sich mit dem Befehl mdadm --examine prüfen:

root@nas:/# mdadm --examine /dev/sd[kjcd]2 | grep -E "^/dev|Update|State|Event|Role|Array State"###linebreak###/dev/sdc2:###linebreak###    Update Time : Mon Sep 11 17:30:14 2023###linebreak###         Events : 327926###linebreak###   Device Role : Active device 2###linebreak###   Array State : AAAA ('A' == active, '.' == missing, 'R' == replacing)###linebreak###/dev/sdd2:###linebreak###    Update Time : Mon Sep 11 17:30:14 2023###linebreak###         Events : 327926###linebreak###   Device Role : Active device 3###linebreak###   Array State : AAAA ('A' == active, '.' == missing, 'R' == replacing)###linebreak###/dev/sdj2:###linebreak###    Update Time : Mon Sep 11 17:30:16 2023###linebreak###         Events : 327929###linebreak###   Device Role : Active device 1###linebreak###   Array State : AA.. ('A' == active, '.' == missing, 'R' == replacing)###linebreak###/dev/sdk2:###linebreak###    Update Time : Mon Sep 11 17:30:16 2023###linebreak###         Events : 327929###linebreak###   Device Role : Active device 0###linebreak###   Array State : AA.. ('A' == active, '.' == missing, 'R' == replacing)

In der Ausgabe ist vermutlich auch der Grund erkennbar, weshalb das RAID nach dem Neustart nicht mehr assembliert werden konnte: Es sind die unterschiedlichen Counter der Events und Array State .
Weichen diese zu sehr voneinander ab, ist das für md ein Indikator, dass die Festplatte ein Problem hat, woraufhin sie nicht mehr mit in das RAID aufgenommen wird. Passiert das bei nur einer Festplatte, wird nur diese eine Festplatte aus dem RAID geworfen. Da es sich hier aber um ein RAID10 handelt und genau die zwei falschen Festplatten betroffen waren, konnte das RAID-Volume gar nicht mehr gestartet werden.

Die Festplatten sind also laut mdadm --examine in Ordnung und smartctl -a /dev/[kjcd]2 zeigt auch keine S.M.A.R.T.-Fehler.

Layout der Mirror-Disks + Auslesen der Stripes vom RAID10

Da die vier Festplatten technisch in Ordnung sind, muss das RAID10 neu erstellt werden. Bevor das jedoch gemacht werden kann, muss man wissen, wie das ursprüngliche RAID10 erstellt wurde. Da das nicht manuell sondern über die WebGUI der NAS-Software gemacht wurde, muss man hier ein wenig debuggen.

root@nas:/# for drive in sd{k,j,c,d}; do###linebreak###    echo -n ${drive}2:###linebreak###    dd if=/dev/${drive}2 skip=1M bs=1M count=64 2>/dev/null | md5sum###linebreak###done###linebreak###sdk2:de9d32bfeb5d8e19a12a8dc79a8d0980  - # RAID1 (1)###linebreak###sdj2:de9d32bfeb5d8e19a12a8dc79a8d0980  - # RAID1 (1)###linebreak###sdc2:c5c486d841b7d620bbd4cfcbb18f1e3a  - # RAID1 (2)###linebreak###sdd2:c5c486d841b7d620bbd4cfcbb18f1e3a  - # RAID1 (2)

In der Ausgabe ist anhand von md5sum erkennbar, welche Festplatten dieselben Daten enthalten.
Über RAID1 (1) und RAID1 (2) liegt demnach dann das RAID0/Stripe vom RAID10.

Der aufmerksame Leser hat möglicherweise festgestellt, dass die weiter oben gelistete Device Role schon einen Hinweis dazu gibt.
Dort ist Active device 0 - Active device 3 erkennbar, was die Reihenfolge der Festplatten beim Erstellen des RAIDs festlegt.

Anlegen von Temp-Dateien für Festplatten-Snapshots

Damit die Änderungen, die ggf. auf die Festplatten geschrieben werden, nicht tatsächlich auf die Festplatten, sondern in temporäre Dateien geschrieben werden, muss folgendes vorbereitet werden:

Erstellen von overlay-Dateien für loop-Device

Dieser Befehl legt Dateien im thin-Format mit einer maximalen Größe von 2TB an.

root@nas:/# truncate --size 2T /tmp/overlay-sdk2###linebreak###root@nas:/# truncate --size 2T /tmp/overlay-sdj2###linebreak###root@nas:/# truncate --size 2T /tmp/overlay-sdc2###linebreak###root@nas:/# truncate --size 2T /tmp/overlay-sdd2

Bereitstellen der overlay-Dateien als Blockdevice

Damit die overlay-Dateien als Snapshot-Device genutzt werden können, müssen sie als Block-Device verfügbar gemacht werden.

root@nas:/# losetup --find --show -- /tmp/overlay-sdk2###linebreak###root@nas:/# losetup --find --show -- /tmp/overlay-sdj2###linebreak###root@nas:/# losetup --find --show -- /tmp/overlay-sdc2###linebreak###root@nas:/# losetup --find --show -- /tmp/overlay-sdd2###linebreak###root@nas:/# losetup --all###linebreak###/dev/loop3: [fd02]:262150 (/tmp/overlay-sdk2)###linebreak###/dev/loop4: [fd02]:262153 (/tmp/overlay-sdj2)###linebreak###/dev/loop5: [fd02]:262154 (/tmp/overlay-sdc2)###linebreak###/dev/loop6: [fd02]:262155 (/tmp/overlay-sdd2)

Ermitteln der Größe der physikalischen Festplatten

root@nas:/# blockdev --getsz /dev/sdk2###linebreak###3865063424###linebreak###root@nas:/# blockdev --getsz /dev/sdj2###linebreak###3865063424###linebreak###root@nas:/# blockdev --getsz /dev/sdc2###linebreak###3865063424###linebreak###root@nas:/# blockdev --getsz /dev/sdd2###linebreak###3865063424

Alle physikalischen Festplatten weisen also 3865063424 512-Byte-Sektoren auf.

Anhängen von Snapshot-Device an die physikalische Festplatte

Mit diesem Befehl werden die zuvor erstellten Snapshot-Devices an die physikalischen Festplatten angehängt:

root@nas:/# echo "0 3865063424 snapshot /dev/sdk2 /dev/loop3 P 8" | dmsetup create sdk2-snapshot###linebreak###root@nas:/# echo "0 3865063424 snapshot /dev/sdj2 /dev/loop4 P 8" | dmsetup create sdj2-snapshot###linebreak###root@nas:/# echo "0 3865063424 snapshot /dev/sdc2 /dev/loop5 P 8" | dmsetup create sdc2-snapshot###linebreak###root@nas:/# echo "0 3865063424 snapshot /dev/sdd2 /dev/loop6 P 8" | dmsetup create sdd2-snapshot

Die vier erzeugten Devices können jetzt anstelle der physikalischen Festplatten genutzt werden. Lese-Anfragen werden direkt an die physikalische Festplatte weitergeleitet. Alle Schreib-Anfragen arbeiten nach dem CoW-Prinzip (Copy-on-Write). Wenn also etwas auf das Device /dev/mapper/sdc2-snapshot geschrieben wird, werden die Änderungen in das Loop-Device /dev/loop5 und am Ende in die Datei /tmp/overlay-sdc2 geschrieben und nicht in das physikalische Device /dev/sdc2 .

Neu-Erstellen des RAID10 mit Snapshot-Devices

Da wir nun vier neue Devices haben, bei denen alle Änderungen nur in die temporären Dateien geschrieben werden und Lese-Zugriffe tatsächlich von der physikalischen Festplatte kommen, können wir so das RAID10 neu erstellen, ohne die Festplatten zu ändern. Denn es wäre ja möglich, dass beim Erstellen des RAID10 etwas schief geht, der Befehl mit falschen Parametern o.ä. ausgeführt wird, wodurch tatsächlich der Superblock auf den Festplatten neu geschrieben wird und infolgedessen ein realer Datenverlust entsteht.

Das RAID10 wurde im ersten Schritt mit folgendem Befehl neu erstellt. Hier ist die Reihenfolge der Disks wichtig.

  • Disk 0=sdk2
  • Disk 1=sdj2
  • Disk 2=sdc2
  • Disk 3=sdd2
root@nas:/# mdadm --verbose --create --assume-clean --level=10 --raid-devices=4 /dev/md1 /dev/mapper/sdk2-snapshot /dev/mapper/sdj2-snapshot /dev/mapper/sdc2-snapshot /dev/mapper/sdd2-snapshot

Das hatte zur Folge, dass das RAID nicht neu erstellt werden konnte, weil der Default von metadata , 1.2 ist. Das originale RAID10 wurde mit 1.1 erstellt.

Also muss der Befehl entsprechend abgeändert werden:

root@nas:/# mdadm --verbose --create --metadata=1.1 --assume-clean --level=10 --raid-devices=4 /dev/md1 /dev/mapper/sdk2-snapshot /dev/mapper/sdj2-snapshot /dev/mapper/sdc2-snapshot /dev/mapper/sdd2-snapshot

Das RAID10 kann damit neu erstellt und wieder gestartet werden:

root@nas:/# cat /proc/mdstat###linebreak###Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]###linebreak###md1 : active raid10 sdk2-snapshot[0] sdd2-snapshot[3] sdc2-snapshot[2] sdj2-snapshot[1]###linebreak###      3864801280 blocks super 1.1 512K chunks 2 near-copies [4/4] [UUUU]###linebreak###      bitmap: 0/29 pages [0KB], 65536KB chunk

In unserem Fall ist /dev/md1 ein Physical-Volume von LVM. Auf die Logical-Volumes, die auf /dev/md1 liegen, konnte nun wieder zugegriffen werden.

Jetzt hätten wir im Prinzip die Daten von den LVs sichern können. Da wir aber noch eine weitere Kopie der Daten hatten, konnten wir uns diesen Schritt sparen.

Neu-Erstellen des RAID10 mit physikalischen Festplatten

Mit dem geschilderten Vorgehen konnten wir testen und sicherstellen, dass wir die richtigen Parameter von mdadm --create genutzt haben und auf die Daten zugreifen können.
Da damit die Änderungen nur in die Snapshot-Devices geschrieben werden, muss das Setup wieder teilweise zurückgebaut werden.

RAID10 /dev/md1 stoppen:

root@nas:/# mdadm --stop /dev/md1

Mit folgenden Befehlen wird das Snapshot-Device von der physikalischen Festplatte entfernt und sie kann wieder direkt angesprochen werden:

root@nas:/# dmsetup rm sdc2-snapshot###linebreak###root@nas:/# dmsetup rm sdd2-snapshot###linebreak###root@nas:/# dmsetup rm sdj2-snapshot###linebreak###root@nas:/# dmsetup rm sdk2-snapshot

Nun den o.g. Befehl für das Neuerstellen anpassen und RAID10 neu erstellen:

root@nas:/# mdadm --verbose --create --metadata=1.1 --assume-clean --level=10 --raid-devices=4 /dev/md1 /dev/sdk2 /dev/sdj2 /dev/sdc2 /dev/sdd2

Kontrolle des RAID10:

root@nas:/# cat /proc/mdstat###linebreak###Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4]###linebreak###md1 : active raid10 sdk2[0] sdd2[3] sdc2[2] sdj2[1]###linebreak###      3864801280 blocks super 1.1 512K chunks 2 near-copies [4/4] [UUUU]###linebreak###      bitmap: 0/29 pages [0KB], 65536KB chunk

Im Anschluss muss noch kontrolliert werden, ob auch wieder das PV, LVs und die Daten verfügbar sind.

Fazit

Mit diesem Vorgehen konnten wir sicherstellen, dass wir während der Fehlersuche und Wiederherstellung des RAIDs keine Änderungen an den Festplatten vorgenommen haben. Alle Änderungen wären nur in die temporären Dateien geschrieben worden. Dadurch hat man vom Prinzip her die Möglichkeit, bei physikalischen Linux-Servern genauso wie bei virtuellen Servern Snapshots zu erstellen, auf die man bei Bedarf zurückrollen kann.



Bild von Bruno auf Pixabay

Erstellt am 15.02.2024