Voll-Backup eines Linux Systems im laufenden Betrieb

Die Datenbank selbst sollte doch transaktional sein, so dass bei einem Stromausfall immer entweder die Transaktion durch ist und auch auf der Platte gelandet ist, oder nichts von der Transaktion permanent gespeichert ist. Und was ist ein Snapshot aus der Sicht des Filesystems, wenn man ihn zurückrollt? Ein simulierter Stromausfall.
Theoretisch funktioniert das alles, aber bei einem Stromausfall kann man auch ein DBMS schrotten und ggf. muß man den Zustand eines DBMS aus einem Backup in eine neue Version laden und da wirst Du dann oftmals mit Binärdateien Probleme haben. MySQL kann nur direkte Vorgänger binärkonvertieren und PostgreSQL macht es gleich gar nicht. Garantiert wird das alles nur für Dumps. Also sollte man auch nur diesen Weg gehen.

- - - Updated - - -

Und ja: Ich will ein System mit Snapshots, die ich jederzeit wieder zurück spielen kann, um Bedienfehler auszuschließen. Ich werde am Anfang sehr viel mit dem System ausprobieren und hier und da sicher einen Fehler machen, den ich durch das Zurückspielen von Snapshots wieder beheben kann.
Dann wäre ggf. ein VM die einfachere Variante.
 
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Apropos Stromausfall, letztes Jahr hat es mir ein btrfs Dateisystem bei einem Blitzeinschlag in der Nähe zerlegt. Außerdem laufen VMs prinzipbedingt arschlahm auf dieser Art Dateisystem. So viele Scherereien hatte ich seit den frühen Tagen von Reiser FS mit keinem Dateisystem mehr. Ich bin jedenfalls davon geheilt und zurück zu LVM + ext4 bzw. XFS für das Datengrab mit großen Dateien.
 
Dann wäre ggf. ein VM die einfachere Variante.

Zum Rumprobieren nehme ich natürlich erstmal eine VM.
Das "Produktiv-System" muss dann allerdings "echt" sein.

Ich habe mich am Wochenende mal an ein Skript gewagt: Konnte damit Snapshots lokal anlegen und wiederherstellen. Anlegen von Snapshots, die auf einem anderen Server liegen, funktioniert auch. Allerdings hapert es da etwas mit der Wiederherstellung. Ich versuche es weiter...
 
So, nun habe ich noch etwas weiter rumprobiert und möchte meine Ergebnisse teilen, indem ich die Skripts hier hoch lade. Hat ja jemand ähnliche Anforderungen und kann diese Skripts als Grundlage nehmen.

Wichtig: Ich bin kein Linux-Experte, daher kann ich keine Garantie geben, dass die Skripts fehlerfrei laufen. Bei mir scheint es auf einer VM zu funktionieren, aber das muss ja nichts heißen.

Erst einmal das Skript-Paket:
Siehe Post #41

Darin sind 5 Skripts enthalten. Alle gehen davon aus, dass...
  • ...das btrfs-Root-Verzeichnis unter /dev/sda6 liegt
  • ...3 btrfs-Subvolumes vorliegen: @, @home und /var/lib/machines. Dies ist zumindest nach einer Neuinstallation von Ubuntu Server 15.04 der Fall.
  • ...ein (für die Remote-Skripts) Netzlaufwerk unter /mnt/Share gemountet ist. Dateisystem ist hier egal, bei mir ist es eine Freigabe auf einem Windows-Rechner.
  • ...die Skripts mit Root-Rechten ausgeführt werden.

SnapshotLocal.sh
Aufruf: SnapshotLocal.sh SnapshotName
Legt lokale Snapshots aller Subvolumes mit dem angegebenen Namen ('SnapshotName') an. Diese Snapshots werden in einem Ordner 'snapshots' gespeichert, der im btrfs-root liegt.

RollbackLocal.sh:
Aufruf: RollbackLocal.sh SnapshotName
Spielt alle lokalen Snapshots mit dem Namen 'SnapshotName' zurück. Danach ist ein sofortiger Reboot notwendig und man sollte danach das Skript RollbackCleanup ausführen (s.u.).

RollbackCleanup.sh:
Aufruf: RollbackCleanup.sh
Räumt nach einem Rollback auf (nach einem Neustart!) und löscht die nicht mehr benötigten Snapshots, die für das Umkopieren angelegt wurden.

SnapshotRemote.sh:
Aufruf: SnapshotRemote.sh SnapshotName
Legt Snapshots ähnlich wie SnapshotLocal an, transferiert diese jedoch als tar-Archiv auf das Netzlaufwerk.

RollbackRemote.sh:
Aufruf: RollbackRemote.sh SnapshotName
Stellt Remote-Snapshots mit dem angegebenen Namen wieder her. Danach ist ein Reboot notwendig und man sollte danach das Skript RollbackCleanup ausführen (s.o.).


Das alles ist sicherlich nicht perfekt und man könnte hier eine elegantere Lösung anfertigen. Wie gesagt, auf einer Test-VM laufen die Skripts anscheinend ohne Probleme.
Für Verbesserungsvorschläge wäre ich natürlich dankbar.
 
Zuletzt bearbeitet:
Ein paar kleine Anmerkungen zu Details von deinen Skripten, wenn du gestattest:
  • Anführungszeichen
    Die einfachen Anführungszeichen ' bewirken, dass Wildcards/Muster wie *.jpg von der Shell unangetastet bleiben und auch Variablen nicht ersetzt werden. Beim Zusammensetzen von Pfaden hast du richtigerweise " verwendet, aber an deiner Stelle hätte ich überall " verwendet, soweit ich deine Skripte auf die Schnelle überblicke benötigst du nirgends einfache Anführungszeichen '.
  • Anführungszeichen II
    Ich finde du solltest überall um die Pfade die doppelten Anführungsstriche machen (bei tar, mv, btrfs,…). Um wenigstens ein konkretes Beispiel zu nennen, den umount-Befehl in Zeile 54 von SnapshotRemote.sh würde ich in
    Code:
    …
    then
    	echo "ERROR: Backup '${BACKUPDESC}' already exists!"
    	cd ~
    	umount "${TEMPMOUNTDIR}"
    	exit 1
    fi
    …
    ändern.
    Damit gehst du Problemen aus dem Weg, wenn du einmal ein Leerzeichen oder andere Zeichen mit besonderer Bedeutung für die Shell (zB Klammern) in einem Pfad hast.

    edit
    Bei diesem Beispiel ist mir gerade noch etwas aufgefallen: Die einfachen Anführungsstriche um ${BACKUPDESC} verhindern, dass der Variablenname durch den Wert der Variablen ersetzt wird. Die Fehlermeldung wirst du so wie du sie gemeint hast, also nie zu sehen bekommen. Dazu müsstest du die einfachen Anführungsstriche weglassen:
    Code:
    …
    	echo "ERROR: Backup ${BACKUPDESC} already exists!"
    …
    Du hast ja sowieso schon die doppelten Anführungsstriche um die Fehlermeldung und selbst die brauchst du nur, wenn der Pfad irgendwelche besondere Zeichen enthält.
  • Abbruch bei Fehlern
    Speziell solange du nicht sicher bist, dass dein Skript in allen Situationen funktioniert (du überprüfst beispielsweise nie ob das Mounten funktioniert hat, ob der Snaphsot erfolgreich angelegt werden konnte, …) könntest du mit einem "set -e" am Anfang des Skripts dafür sorgan, dass das Skript auf jeden Fall abbricht, wenn bei einem Befehl ein Fehler auftritt. Der Anfang könnte dann so aussehen
    Code:
    #!/bin/bash
    set -e
    
    …
    (Zum Beispiel wirst du wahrscheinlich nicht wollen, dass tar versucht das Backup anzulegen, wenn einer der Schritte davor fehlgeschlagen ist)
    "set +e" bewirkt übrigens genau das Gegenteil (ich weiß gar nicht was normalerweise das Standardverhalten ist, deshalb lege ich es in jedem Skript fest). Mit diesen beiden Befehlen kannst du jederzeit auch mitten im Skript das Verhalten der Shell bei Fehlern „umschalten“.
  • Fehlermeldungen (nur eine Kleinigkeit)
    An einigen Stellen gibst du Fehlermeldungen aus, zB in Zeile 33 von SnapshotRemote.sh. Es ist üblich Fehlermeldungen nicht an die Standardausgabe sondern an die Standardfehlerausgabe auszugeben. Dafür gibt es viele Möglichkeiten, zwei Beispiele:
    Code:
    echo "ERROR: This script has to be run as root!" >&2

    oder du definierst zu Beginn einen Alias, den du in weiterer Folge nutzen kannst

    Code:
    #!/bin/bash
    set -e
    alias errorecho='>&2 echo'
    
    …
    
    …
    errorecho "ERROR: This script has to be run as root!"
    …

    oder ganz ähnlich mit einer Funktion, die in dem Fall etwas robuster gestaltet ist

    Code:
    #!/bin/bash
    set -e
    errorecho() { cat <<< "$@" 1>&2; }
    
    …
    
    …
    errorecho "ERROR: This script has to be run as root!"
    …
und schließlich könntest du dir, abhängig davon woran das Skript scheitert, auch andere Rückgabewerte als 1 (exit 1) überlegen, (zB "exit 42" ☺). Wenn du die Skripten automatisiert aufrufen lässt könntest du so auf unterschiedliche Fehlerursachen reagieren, wenn du andererseits nichts dergleich vorhast, ist es eigentlich egal…
 
Zuletzt bearbeitet:
Speziell solange du nicht sicher bist, dass dein Skript in allen Situationen funktioniert (du überprüfst beispielsweise nie ob das Mounten funktioniert hat, ob der Snaphsot erfolgreich angelegt werden konnte, …) könntest du mit einem "set -e" am Anfang des Skripts dafür sorgan, dass das Skript auf jeden Fall abbricht, wenn bei einem Befehl ein Fehler auftritt. Der Anfang könnte dann so aussehen
Code:
#!/bin/bash
set -e

…
Das geht übrigens auch mit nur einer Zeile:
Code:
#!/bin/bash -e
…

(Zum Beispiel wirst du wahrscheinlich nicht wollen, dass tar versucht das Backup anzulegen, wenn einer der Schritte davor fehlgeschlagen ist)
"set +e" bewirkt übrigens genau das Gegenteil (ich weiß gar nicht was normalerweise das Standardverhalten ist, deshalb lege ich es in jedem Skript fest).
Das Standardverhalten entspricht "set +e".
 
Oha, ne ganze Menge Holz! :p

Werde die Skripts bei Gelegenheit mal anpassen und neu hochladen.

Danke euch beiden für die kompetente Unterstützung!
 
Für deine Grafische Klick Lösung kannst du ja mal Backup PC ausprobieren. Für meine scheduled Datensicherung reichte mir das. Wenn ich dann etwas bastele oder aus anderen Gründen schnell mal alles sichern will nehme ich das bereits erwähnte Linux Hot Copy.
Ansonsten kann ich nur empfehlen, Daten und externe Software separat vom Linux "abzulegen". Im Falle eines Crashes ist das OS schnell wieder drauf und das andere nicht verloren/beschädigt.
Ich habe dafür ein eigenes HW Laufwerk (eigentlich zwei, wenn man den BU Drive dazunimmt)
Ist auch angenehm, wenn mal die HD crashed.

Edit - Das Script aus dem vorherigen Post ist auch etwas feines, danke dafür !
 
Zuletzt bearbeitet:

Ähnliche Themen

Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh