Login
Newsletter
Werbung

Do, 7. November 2013, 15:00

Disaster Recovery mit Hilfe der richtigen Backup-Strategie

Sichern auf Block-Ebene

Image-Backups mit dd (dump device)

Die Umkehrung jedes Backup-Befehls zur Wiederherstellung wird zur Vervollständigung jeweils zusätzlich aufgeführt, im Text jedoch nicht mehr detailliert behandelt.

# dd if=/dev/sdx bs=4MB of=/mnt/backup/Devname-sdx.img
# dd if=/mnt/backup/Devname-sdx.img of=/dev/sdx bs=4MB

Der erste Befehl erstellt ein Backup des gesamten Datenträgers in eine Image-Datei der exakt gleichen Größe. Vorher muss sichergestellt werden, dass auf dem Zielmedium ausreichend Platz vorhanden ist, da dd diesen nicht prüft.

In der resultierenden Image-Datei wird ungefähr der unbelegte Bereich des Datenträgers an Platz verschwendet. Möchte man diese Verschwendung vermeiden, so kann man die Image-Datei wie folgt komprimieren:

# dd if=/dev/sdx bs=4MB | gzip --best > /mnt/backup/Devname-sdx.img.gz
# gunzip –c /mnt/backup/Devname-sdx.img.gz | dd of=/dev/sdx bs=4MB

Tipp zur Kompressionssteigerung:

Auch wenn die Platte aktuell vielleicht nur zu 30% belegt ist, so kann es sein, dass durch vielfältige Dateioperationen in der Vergangenheit diese einmal bis zu 100% belegt war. Auch wenn diese einst belegten Sektoren nun wieder freigegeben sind, so enthalten diese dennoch schlecht zu komprimierende Daten. Soll also die komprimierte Image-Datei besonders klein werden, egal welches Kompressionsverfahren verwendet wird, so ist vorher auf Dateiebene der gesamte freie Platz der zu sichernden Festplatte oder Partition mit Nullen zu füllen, indem diese in eine Datei geschrieben werden, die anschließend sofort wieder gelöscht werden muss. Ansonsten gäbe es unerwünschte Effekte wegen Speichermangels, besonders wenn man diesen Schritt als vorbereitende Maßnahme vor der Sicherung aus einem laufenden Linux-System heraus durchführt.

Wenn man es jedoch von der Live-CD aus erledigen möchten, so muss man nun jede der einzelnen Quell-Partitionen unter den zuvor erstellten Einhängepunkten einhängen, z.B. unter /mnt/sdxn und diese dann voll schreiben.

# dd if=/dev/zero of=/mnt/sdxn/Null.txt; rm /mnt/sdxn/Null.txt

Die Partitionen sollten zur Sicherheit wieder ausgehängt werden und erst dann sollte man den vorigen dd-Befehl zur Sicherung mit Kompression ausführen.

Angenommen, man unterliegt aufgrund des Dateiformates seines Ziel-Laufwerkes einer Datei-Größenbeschränkung von 2 GB. Dann kann man die Image-Datei wie folgt aufsplitten:

# dd if=/dev/sdx bs=4MB |gzip | split -b 2000m /mnt/backup/Devname-sdx.img.gz
# gunzip –dc /mnt/backup/Devname-sdx.img.gz | dd of=/dev/sdx bs=4MB

Übrigens: Die angegebene Blocksize (bs) von 4 MB deklariert die Speichermenge, die von den Blöcken des Datenträgers in einem Durchgang in den Cache eingelesen wird. Bei passend gewählten Werten, abhängig von der Hardware, kann man die Lese-/Schreibgeschwindigkeit steigern. Dieser Wert muss also nicht zwingend der Blockgröße des Datenträgers entsprechen, sondern sollte zur Performance-Steigerung angepasst werden. Definiert man keine Blocksize, wird als Standardgröße 512 Byte verwendet.

Die bs=block size – mit einem Wert von z.B. 32k, 512k, 1MB oder 4MB – hat aber nicht nur Einfluss auf die Geschwindigkeit, sondern auch darauf, wie viele Daten bei defekten Blöcken verworfen werden. Um möglichst viele Daten zu retten, ist die Blockgröße möglichst klein zu wählen, was jedoch die Lese-/Schreibgeschwindigkeit verringert. Wenn dd auf defekte Sektoren trifft, bricht es den Vorgang ab. Mit der Option conv=noerror werden die defekten Blöcke dagegen einfach übersprungen.

Die Zieldaten werden dadurch aber um so mehr gekürzt, je größer die Blockgröße für das Auslesen der defekten Blöcke gewählt wurde. Daher gilt es bei defekten Datenträgern, die Blocksize zu verringern, trotzdem wird das Ergebnis vom Ursprung abweichen.

Das Programm ddrescue sorgt hier für Verbesserung des Resultates und ist daher das Werkzeug der Wahl, wenn es um die Datenrettung von defekten Datenträgern geht.

Durch geschicktes Parametrieren kann man sein Verhalten dahingehend steuern, dass es im ersten Durchlauf nur die intakten Sektoren ausliest und die Sektornummern mit Lesefehlern in eine Log-Datei schreibt, um sich diesen in einem späteren zweiten Durchlauf intensiver zu widmen.

Diese Strategie erhöht die Chance, bis zum Totalausfall des Laufwerkes möglichst viele Daten zu retten. Die Anzahl der wiederholten Leseversuche pro Sektor lässt sich entsprechend über Parameter steuern. Jede damit gerettete Information ergänzt so nachträglich die im ersten Durchlauf erzeugte Image-Datei.

Eine von vielen Möglichkeiten, dies zu erreichen, könnte so aussehen:

# ddrescue -f -v -n /dev/sdx /mnt/backup/rescue.img /mnt/backup/rescue.log
# ddrescue -d -f -r10 /dev/sdx /mnt/backup/rescue.img /mnt/backup/rescue.log

Das mit ddrescue gerettete Image kann man wieder mit dd, so wie im ersten Restore-Beispiel gezeigt, auf eine intakte, mindestens gleich große Festplatte wiederherstellen.

Sinnvoll ist auch die eindeutige Benennung der Image-Dateien, damit eine spätere Zuordnung zweifelsfrei erfolgen kann. Beispielsweise könnte durch Hardware-Veränderungen des Systems sdc zu sdb werden. Auch die UUID ist nicht unbedingt beständig oder eindeutig, da eine geklonte Partition dieselbe UUID wie deren Ursprung erhält. Das sorgt für interessante Effekte bei zwei Festplatten in einem System mit gleicher UUID, wenn diese mit nur einem UUID-Eintrag in der fstab nacheinander eingebunden werden. Empfehlenswert ist daher die Vergabe eindeutiger Namen für die Sicherungs-Images, z.B. anhand der Ausgabe von ls -l /dev/disk/by-id/ der jeweils geklonten Platte oder Partition.

Noch ein Tipp für alle ungeduldigen Zeitgenossen, die während lange andauernder dd-Operationen die Ungewissheit plagt, ob das Programm vielleicht abgestürzt sein mag oder wie weit es wohl fortgeschritten ist. Man kann dd den aktuellen Status entlocken, indem man es kurz anhält, allerdings ohne es gänzlich abzubrechen. Am besten auf einer anderen Konsole oder einem anderen X-Terminal so:

# killall -USR1 dd

oder wiederkehrend alle (N) Sekunden:

# watch -n N kill -USR1 `pidof dd`

Um den Status zu sehen, muss man zurück auf die vorherige Konsole wechseln. Zum Beenden der Ausgabe muss man den watch-Befehl mit »Strg+C abbrechen. Weitere nützliche Tipps zu dd lassen sich auf Wikipedia nachlesen.

Natürlich kann man aus einem Image der gesamten Festplatte auch gezielt einzelne Bereiche extrahieren. So kann man beispielsweise nur den in den ersten 440 Byte enthaltenen Bootloader Wiederherstellen:

# dd if=/mnt/backup/Devname-sdx.img of=/dev/sdx bs=440 count=1

oder aber den gesamten MBR wiederherstellen:

# dd if=/mnt/backup/Devname-sdx.img of=/dev/sdx bs=512 count=1

Möchte man aus dem zuvor erstellen Image einzelne Dateien extrahieren, so braucht man das Image nur in einen existierenden Einhängepunkt, hier /mnt/Image-sdx, wie folgt einzuhängen:

# mount -o loop /mnt/backup/Devname-sdx.img /mnt/Image-sdx

Danach kann man per copy, rsync oder einem Dateimanager einzelne Dateien kopieren oder auch ganze Verzeichnisbäume synchronisieren.

Wer statt eine Image-Datei zu erstellen lieber gleich den gesamten Datenträger auf einen anderen, mindestens gleich großen klonen möchte, könnte zum Beispiel so vorgehen:

# dd if=/dev/sdx of=/dev/sdy

Schneller geht es mit

# dd if=/dev/sdx of=/dev/sdy bs=4MB

Ist der Zieldatenträger größer, so ist der überschüssige Platz erst einmal nicht nutzbar. Um diesen Platz zu erschließen, muss man entweder die jeweils letzte Partition in ihrer Größe aufziehen oder stattdessen eine weitere dahinter anlegen, die den verbleibenden Platz ausnutzt. Per Kommandozeile könnte ein Befehl für ein ext-Dateisystem dann zum Beispiel so aussehen, dies ist aber im Bedarfsfall zu prüfen und anzupassen:

# e2fsck -f -y /dev/sdyn; resize2fs -p -f /dev/sdyn

Sehr komfortabel und intuitiv für viele unterstützte Dateisysteme geht das Gleiche mit dem Programm GNU-parted unter einer grafischen Oberfläche.

Dasselbe gilt natürlich beim Klonen der Festplatte mit dd über ein sicheres internes Netzwerk, z.B. unter Verwendung von Netcat. Dazu gilt es, zuerst den Zielrechner mit der Live-CD zu starten, Root-Rechte zu erlangen, die Netzwerkkarte einzurichten, die IP-Adresse zu notieren, die Zielplatte nicht einzuhängen und dort mit diesem Befehl beginnen, da hierdurch ein auf Port 1234 lauschender Server-Dienst gestartet wird, der sich nach einmaliger Ausführung beendet.

Auf dem Zielrechner (der die Daten empfängt):

# nc -l -p 1234 | dd of=/dev/sdx bs=2MB

Auf dem Quellrechner (der die Daten versendet):

# dd if=/dev/sdx bs=2MB | nc IP.of.Target 1234

IP.of.Target ist durch IP-Adresse des Zielrechners zu ersetzen. Der Port ist nahezu beliebig, muss aber auf beiden PCs gleich lauten.

Kommentare (Insgesamt: 21 || Alle anzeigen )
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung