Software-Raid-Partition verkleinern
Nach einem Kernel-Update startete mein Raid nicht mehr. Recherchen ergaben, dass ein Superblock neuerdings am Ende der Platte gesucht wird (Ursache = neue mdadm-Version). Ist das Ende der Platte gleichzeitig das Ende einer Partition, ist dort kein Platz für einen Superblock. Die Partition muss um wenige MB verkleinert werden.
Aktuelle Kernel (ab 2.21.0) fangen das Problem zuverlässig auf. Die Hilfestellung aus spline.eisfair waren für mich sehr lehrreich was den Umgang mit Software-Raid betrifft, weshalb ich dieses HowTo zur Verfügung stelle. Darüber hinaus kann die beschriebene Maßnahme notwendig werden, wenn das Raid auf einen anderen Server umziehen soll. Klassische Tools, wie z.B. „gparted“, können im Raid nicht eingesetzt werden, dieses HowTo arbeitet ausschließlich mit Eisfair-Boardmitteln.
Ausgangslage
- Software-Raid /dev/md0 bestehend aus /dev/sdc1 und /dev/sdd1
- nach einem Neustart des Servers wird das Raid nicht mehr eingebunden
- Setup → System Administration → Filesystems → mdadm → Raid Management → Show Raid-Status:
- Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4] [multipath]
unused devices: <none>
- … → start mdadm:
- * Starting mdadm …Activate configuration now (y/n) [yes]?
No RAID(MD) devices found
- # mdadm –assemble –scan
- mdadm: WARNING /dev/sdd1 and /dev/sdd appear to have very similar superblocks.
If they are really different, please –zero the superblock on one\\If they are the same or overlap, please remove one from the DEVICE list in mdadm.conf.
mdadm: No arrays found in config file or automatically
(man beachte „/dev/sdd“ ohne 1)
Vorhandene Partitionen im Detail
# fdisk -l Device Boot Start End Sectors Size Id Type /dev/sdc1 2048 1953525167 1953523120 931.5G fd Linux raid autodetect /dev/sdd1 2048 1953525167 1953523120 931.5G fd Linux raid autodetect Disk /dev/sdd: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disklabel type: dos Disk identifier: 0x1dde783f
/dev/sdc und /dev/sdd sind identisch
Das Prinzip
- Nach Möglichkeit wird die vorhandene Partition zunächst dem Füllstand angepasst (das erspart viel Zeit)
- Das Raid wird an die verkleinerte Partitionsgröße angepasst
- /dev/sdc1 wird aus dem Raid entfernt, neu partitioniert und wieder eingehängt
- die nachfolgende Synchronisation mit /dev/sdd1 dauert einige Zeit
- /dev/sdd1 wird aus dem Raid entfernt, neu partitioniert und wieder eingehängt
- die nachfolgende Synchronisation mit /dev/sdd1 dauert einige Zeit
- Raid wieder vergrößern
- Dateisystem des Raid wieder vergrößern
- die nachfolgende Synchronisation mit /dev/sdd1 dauert einige Zeit
Der Raid-Verbund der 1TB-Platten mit einem Füllstand von etwa 16% stand dem Server für ca. 3 Stunden nicht zur Verfügung. Insgesamt dauerte die Maßnahme ca. 12 Stunden, das ist aber abhängig von der verwendeten Hardware.
Die Umsetzung
Zunächst wird der Füllstand geprüft:
# df /dev/md0 Filesystem 1K-blocks Used Available Use% Mounted on dev/md0 961433544 142717184 769878288 16% /data
Dann interessiert auch die Blockgröße des Dateisystems:
# tune2fs -l /dev/md0 | grep "Block size" Block size: 4096
Die Platten sollten gut funktionieren (S.M.A.R.T-Werte beachten) und ein funktionierendes Backup sollte vorhanden sein.
Los geht's:
Alle Dienste mit Zugriff auf das Raid müssen gestoppt werden (z.B. Samba, Mail, Apache, Monitoring-Tools…).
Der Raid-Verbund wird ausgehängt. Ab diesem Punkt sind die Daten auf dem Server nicht mehr verfügbar:
# umount /data
Das Dateisystem wird überprüft:
# e2fsck -f -C0 /dev/md0
Auf meinem System sind 16% von 931GB belegt (= 149GB). Damit möglichst wenig fragmentiert wird, gebe ich etwas „Luft“ und verkleinere die Partition zunächst auf 190GB.
„resize2fs“ fordert Größenangaben in Blöcken an:
190GB * 1024 * 1024 * 1024 = 204010946560 Byte
204010946560 / 4096 (Blockgröße) = 49807360
# resize2fs -p /dev/md0 49807360
Der Vorgang dauert, je nachdem wie viel Daten umgelagert werden müssen, 30-90 Minuten. Danach sollte das Dateisystem nochmals geprüft werden:
# e2fsck -f -C0 /dev/md0
Das Dateisystem kann dem Server wieder zur Verfügung werden, weitere Schritte können im laufenden Betrieb ausgeführt werden.
# mount -a
Alle Dienste mit Zugriff auf das Raid können wieder gestartet werden.
Jetzt muss das Raid der neuen Partitionsgröße angepasst werden. Dazu werden zunächst eventuell aktivierte Bitmaps deaktiviert:
# mdadm -G --bitmap=none /dev/md0
Auch das Raid benötigt etwas „Luft“ für die Partition, hier wird auf 200GiB verkleinert:
# mdadm -G -z200G /dev/md0
Die folgenden Schritte müssen für beide Platten nacheinander ausgeführt werden:
Aushängen der Redundanz:
# mdadm --fail /dev/md0 /dev/sdc1 # mdadm --remove /dev/md0 /dev/sdc1
Superblock löschen:
# mdadm --zero-superblock /dev/sdc1
Den Erfolg kann man überprüfen:
# cat /proc/mdstat
/dev/sdc1 ist im Raid nicht mehr enthalten.
Die Platte wird jetzt neu formatiert. Zuletzt war der End-Sector 1953523120. Wird der neue End-Sector auf 1953520000 gesetzt, bleiben am Ende gut 2MB freier Platz hinter der Partition:
# fdisk /dev/sdc Command (m for help): //**d**// Selected partition 1 Partition 1 has been deleted. Command (m for help): //**n**// Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): //**p**// Partition number (1-4, default 1): 1 First sector (2048-1953525167, default 2048): 2048 Last sector, +sectors or +size{K,M,G,T,P} (2048-1953525168, default 1953525168): //**1953520000**// Created a new partition 1 of type 'Linux' and of size xx.x GiB. Command (m for help): //**t**// Selected partition 1 Partition type (type L to list all types): //**fd**// Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): //**w**// The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.
Das Ergebnis wird überprüft:
# cat /proc/partitions
In der Partitionstabelle ist jetzt sdc1 etwas kleiner als sdd1. Ist zu einem späteren Zeitpunkt auch sdd1 verkleinert, sind die Werte wieder identisch.
Die Partition wird nun wieder dem Raid hinzugefügt:
# mdadm --add /dev/md0 /dev/sdc1
Es folgt eine Synchronisation, die Daten von sdd1 werden dabei auf sdc1 geschrieben. Der Vorgang dauerte bei mir etwa 30 Minuten. Den Fortschritt kann man mit
# watch cat /proc/mdstat
anzeigen lassen, CTRL-C/STRG-C bricht die Anzeige ab. Wenn fertig ist sdc1 wieder vollständig im Raid eingebunden und enthält auch wieder alle Daten.
Jetzt muss die zweite Platte /dev/sdd mit identischen Partitions-Informationen gefüttert werden:
- d.h. alle vorangegangenen Maßnahmen mit sdd wiederholt werden (empfohlen)
- oder dieser Abschnitt wird durchgeführt:
Kopieren der Partitionsinformationen von sdc nach sdd:
(ACHTUNG sgdisk -R erwartet als ersten Parameter das ZIEL. Eine Verwechslung zerstört alle Daten!!!)
# sgdisk -R /dev/sdd /dev/sdc
Setze neu GUIDs auf /dev/sdd:
# sgdisk -G /dev/sdd
Das Ergebnis wird überprüft:
# cat /proc/partitions
/dev/sdc1 und /dev/sdd1 sind jetzt identisch.
Ab hier wieder für beide Partitionierungs-Varianten:
Es folgt eine Synchronisierung von sdd. Prüfung mit:
# watch cat /proc/mdstat
Wenn fertig, wird das Raid und das Dateisystem wieder vergrößert.
Vergrößerung des Raid auf die ganze Partition:
# mdadm -G -zmax /dev/md0
Vergrößerung des Dateisystem auf das ganze Raid:
# resize2fs -p /dev/md0
Hiernach wurden bei mir ca 800GB neu synchronisiert, das dauerte etwa 8 Stunden. Auch hier kann mit
# watch cat /proc/mdstat
der Fortschritt überprüft werden. Nach Abschluss können Bitmaps wieder aktiviert werden:
# mdadm -G --bitmap=internal /dev/md0
Die Verkleinerung des Raid ist damit abgeschlossen.
Das Ergebnis
# fdisk -l Device Boot Start End Size Id Type /dev/sdc1 2048 1953520000 1953517953 931.5G fd Linux raid autodetect /dev/sdd1 2048 1953520000 1953517953 931.5G fd Linux raid autodetect Disk /dev/md0: 931.5 GiB, 1000201125888 bytes, 1953517824 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Mit diesem Raid-Verbund startet mein Server mit jeder mdadm-Version wieder normal.
Danksagung
Ich bin keinesfalls in der Lage solche Vorgänge selbst zu erarbeiten. Meinen Dank richte ich insbesondere an Thomas Zweifel, Marcus Roeckrath, Holger Bruenjes und Stefan Welte für Analyse und Behebung meines Problems, sowie Tom Bork für die resultierende Überarbeitung des Kernels. Alle Beteiligten lieferten die für diesen Artikel notwendigen Grundlagen und erweiterten meinen Horizont deutlich.
Grundsätzlich aber auch ein „Danke“ an alle, die am Eisfair-System in irgendeiner Weise aktiv oder passiv mitwirken. Es ist und bleibt ein tolles Server-System!