In einem Kundenserver, der schon ein paar Jahre auf dem Buckel hat, sollte der Speicherplatz erweitert werden – eingebaut waren zwei Festplatten mit je 160 GB; für heutige Verhältnisse in der Tat nicht mehr zeitgemäß. Möglichkeiten gibt es viele: Zusätzliche Platten einbauen (dann verbraucht die Kiste aber mehr Strom und wird lauter); eine externe Festplatte anschließen (die ist dann aber nicht redundant); die Festplatten austauschen und das System umkopieren (das dauert dann aber ewig). Schließlich haben wir uns für die schickste Möglichkeit mit minimaler Downtime entschieden: Die Festplatten nacheinander im RAID auswechseln. Downtime: Etwa zweimal fünf Minuten jeweils für den Austausch einer Platte. Plus ein bisschen Arbeitsaufwand, der aber im laufenden Betrieb erledigt werden kann.
Zum Nachmachen hier nun das Protokoll. Die Festplatten sind Platten nach S-ATA-Standard; stehen im System also als /dev/sda
und /dev/sdb
bereit. Sie haben jeweils drei Partionen, die per Software-RAID zusammengefasst sind:
# cat /proc/mdstat Personalities : [raid1] md1 : active raid1 sda1[0] sdb1[1] 200704 blocks [2/2] [UU] md2 : active raid1 sda3[0] sdb3[1] 974550976 blocks [2/2] [UU] md0 : active raid1 sda2[0] sdb2[1] 2008000 blocks [2/2] [UU] unused devices:
Dabei fungiert /dev/md0
als Swap-Partition; /dev/md1
als /boot
und /dev/md2
als Root-Partition. So, und jetzt geht’s los.
Erstmal wird kurz und schmerzlos eine der beiden Platten ausgebaut – in unserem Fall /dev/sdb
, aber welche zuerst kommt, spielt keine Rolle. An ihrer Stelle wurde eine unpartitionierte Platte eingebaut. Der Server wurde wieder hochgefahren; alles kein Problem – dafür ist ein RAID1 ja da. Anschließend galt es, die neue Festplatte zu partitionieren. Das haben wir hier ganz traditionell mit fdisk
gemacht und dabei für die ersten beiden kleinen Partitionen (Swap und /boot
) die gleiche Zylinderzahl verwendet; die dritte Partition wurde dann entsprechend ausgeweitet. So sieht’s nun aus:
# fdisk -l /dev/sdb Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sdb1 * 1 25 200781 fd Linux raid autodetect /dev/sdb2 26 275 2008125 fd Linux raid autodetect /dev/sdb3 276 121601 974551095 fd Linux raid autodetect
Wichtig ist, hier den korrekten Partitionstyp zu vergeben (in diesem Fall fd
für Linux raid autodetect
) sowie die erste Partition bootfähig zu machen.
Nun fehlt den drei /dev/md*
-Devices ja die Redundanz; die stellen wir also erstmal wieder her, in dem wir mittels mdadm
die frisch angelegten Partitionen hinzufügen:
mdadm /dev/md1 -a /dev/sdb1 mdadm /dev/md0 -a /dev/sdb2 mdadm /dev/md2 -a /dev/sdb3
Die ersten beiden synchronisieren in unter einer Minute; für /dev/md2
wurde gut eine halbe Stunde fällig. Mittels
watch cat /proc/mdstat
lässt sich die Synchronisation gut beobachten. Dieser Vorgang muss vollständig und fehlerfrei abgeschlossen sein, denn wir haben ja vor, gleich die Platte, von der synchronisiert wird, ebenfalls zu wechseln, und dafür muss die neu eingebaute natürlich komplett auf dem neuesten Stand sein!
Nun möchte man meinen, das wär’s, aber eine ganz wichtige Sache fehlt noch: Auch wenn die Daten jetzt wieder synchron sind, so fehlt noch der Bootloader – sprich, wenn jetzt die verbliebene Platte ausgewechselt würde, könnte das System nicht mehr booten. Es gilt also, GRUB auf /dev/sdb
zu installieren, und das ist nicht ganz so einfach, wie es auf den ersten Blick scheint. Die RAID1-Redundanz liegt ja auf Partitionsebene – betrifft also nicht den Bootsektor selbst.
Der Haken an der Sache ist: GRUB führt eine device.map
, in der die physischen Festplatten auf die GRUB-internen Bezeichnungen hd0
und hd1
gemappt werden. Kein Problem, solange es die zweite Festplatte ist, die ausfällt – fällt allerdings die erste aus, wird /dev/sdb
als einzige verbleibende Platte plötzlich hd0
statt hd1
– und das schmeckt GRUB nun überhaupt nicht. Man kann nun in der device.map
zwar beide Platten von Hand als hd0
definieren; das mag jedoch grub-install
nicht und quittiert mit:
The drive (hd0) is defined multiple times in the device map /boot/grub/device.map
Es bleibt also letztlich nur, das Spiel von Hand zu spielen, und zwar so:
grub> device (hd0) /dev/sdb grub> root (hd0,0) grub> setup (hd0) grub> quit
Mit anderen Worten: Man verkauft GRUB die zweite Platte als hd0
, also als erste, denn wenn die echte erste Platte einmal ausfällt – dann ist die zweite Platte ja auch faktisch die erste. Das klappt prima, und das System ist bereit zum Austausch der verbliebenen kleinen Platte gegen das größere Modell. Hat man alles richtig gemacht, sollte der Server problemlos mit der einen neuen großen Platte booten (die nun ihrerseits auch nur eine Hälfte des RAID1 darstellt).
Nun sind die obigen Schritte für die verbliebene Platte, in unserem Fall /dev/sda
, zu wiederholen: Partitionieren; mittels mdadm
zum RAID1 hinzufügen; GRUB von Hand in den Bootsektor packen.
Nun haben wir einen Server mit neuen Festplatten, bei denen die Root-Partition deutlich größer ist, aber bisher haben wir davon noch nichts – es fehlen noch zwei entscheidende Schritte. Zunächst muss die Partition /dev/md2
, die jetzt nur noch einen Bruchteil des physisch vorhandenen Speicherplatzes nutzt, auf die neue Größe ausgedehnt werden. Das erledigen wir mit:
mdadm --grow -z max /dev/md2
Hiermit wird für den zusätzlichen Speicherplatz ein Resync angestoßen – sprich, dieser Vorgang zieht sich eine ganze Weile, zumal wir ja hier auf Terabyte-Platten aufgerüstet haben. Im konkreten Fall mussten wir rund zwei Stunden dafür einkalkulieren.
Nun sind wir aber immer noch nicht fertig. Zwar ist das Device jetzt endlich so groß, wie wir es haben wollen, aber das Dateisystem weiß davon noch nichts – und das muss schließlich die neu hinzugekommenen Blöcke auch ansprechen können.
Erfreulicherweise gibt es seit einigen Jahren die Möglichkeit, ein ext2-/ext3-Dateisystem im laufenden Betrieb, sprich: im gemounteten Zustand zu vergrößern. Bei CentOS 4, das auf diesem Server noch läuft (kein Problem, wird ja noch bis Anfang 2012 supportet), übernimmt diesen Job noch ext2online
; bei neueren Distributionen ist der Live-Resizing-Code in resize2fs
aufgegangen, das bis dahin nur eine Größenanpassung von nicht aktiv verwendeten Devices realisierte. Auf geht’s:
ext2online -v /dev/md2
Der Vorgang zieht sich ein bisschen, aber man kann sehr schön beobachten, wie sich die Größe im laufenden Betrieb ändert – und sich der prozentuale Füllstand der Root-Partition entsprechend nach und nach verringert:
# df -h Filesystem Size Used Avail Use% Mounted on /dev/md2 178G 123G 46G 73% / /dev/md1 190M 15M 166M 8% /boot none 505M 0 505M 0% /dev/shm
… warten …
# df -h Filesystem Size Used Avail Use% Mounted on /dev/md2 203G 123G 69G 65% / /dev/md1 190M 15M 166M 8% /boot none 505M 0 505M 0% /dev/shm
… warten …
# df -h Filesystem Size Used Avail Use% Mounted on /dev/md2 213G 123G 79G 62% / /dev/md1 190M 15M 166M 8% /boot none 505M 0 505M 0% /dev/shm
Wenn dieser Vorgang abschlossen ist – war’s das. Viel Spaß mit dem neu hinzugewonnenen Speicherplatz!
Hallo !
Habe die Anleitung hier genutzt, um das RIAD-1 des Root-FS auf meinem Server zu vergrößern. Danke.
Anmerkung zu grub:
root (hd0,0) passt nicht: Meine Root-Partition (md1) wird durch sda2 und sdb2 gebildet.
Mit
root (hd0,1) klappte das setup dann auch sofort. Dies sowohl beim Tausch von sda als auch sdb.
Gruß
Axel