Nächtliche Paket-Backups
Unsere Backups werden derzeit per cron jede Nacht ab 3:11h angefertigt, das Skript ist /root/bin/backup. Der Backup-Server ist in /root/etc/config genannt und steht in einem anderen Rechenzentrum, um auch bei Brand etc. eine Datensicherung zu haben.
Backups dienen zum einen zur Desaster-Recovery, dies wurde zuletzt im April 2002 benötigt, als wir noch keine Standby-System hatten. Zum anderen werden Backups für Einzel-Restore benötigt, falls sich Paket-Admins oder andere User eigene Daten löschen oder überschreiben. Dies wird ca. alle zwei Monate nachgefragt.
Unser Backup ist vom Prinzip her ein kumulativ inkrementelles Backup ("incremental backup"), d.h. dass es für einen Backup-Satz jeweils ein Basis-Archiv und ggf. genau ein Delta gibt, welches die seit der Erstellung des Basis-Archivs veränderten, hinzugefügten oder gelöschten Daten beschreibt. Zur Wiederherstellung ist also das Einspielen von zwei Archiven nötig (genaugenommen drei, weil die Löschliste separat ist). Dieses ist eine ideale Mischung aus geringen zu übertragenden Datenmengen und einfacher Wiederherstellung.
Vor dem eigentlichen Backup werden noch ein paar zum Paket gehörige Daten aus zentralen Bereichen nach ~xyz00/.bak kopiert (für den PaketAdmin ist das das versteckte Verzeichnis ~/.bak/, dort sind sie für ihn auch lesbar). Zu den gesicherten Daten gehören z.B. auch die MySQL- und PostgreSQL-Datenbanken sowie die Daten aus /etc/pacs/ und der zugehörigen Domains aus /etc/doms/. Während des Kopierens der MySQL-Datenbanken können diese nicht beschrieben werden, um inkonsistente Kopien zu verhindern. Die PostgreSQL Datenbanken werden per dump gespeichert, was aber beim Restore u.U. Probleme durch zirkuläre Referenzen bedeuten kann. (Anmerkung für Hostmaster: backup-postgres wird für die einzelnen Pakete aus /root/bin/backup aufgerufen. Damit ist sichergestellt, dass bei Beginn des Backups auch der PostgreSQl Dump bereits vollständig ist)
Die Dateien in ~/.bak/ enthalten vor allem die Datenbanken des Paketes. Diese gehören vertragsmäßig auch zum Speicherplatz des Paketes, praktisch jedoch nicht. Daher ist es korrekt, dass wenigstens die lokalen Backups der Datenbanken in die Quota eingehen. Die restlichen Dateien hier sind in der Größe vernachlässigbar.
Beim Backup selbst wird dann geprüft, ob es ein Basis-Archiv (/var/backups/lokal/xyz00.tar.gz) bzw. genaugenommen die dazugehörige File-Liste (/var/backups/xyz00.files) gibt. Wenn nein, wird ein neues Basis-Archiv vom Paket erstellt. Wenn ja, wird versucht, ein Delta-Archiv (nur die nach Filesystem-Angabe neueren Dateien) zu erstellen. Sollte dieses jedoch zu groß geraten (derzeit >33% vom Basis-Archiv des Pakets), dann wird ein neues Basis-Archiv erstellt. Zu einem Delta-Archiv (/var/backups/lokal/xyz00.delta.tar.gz) gehört immer noch eine Lösch-Liste (/var/backups/lokal/xyz00.delta.rm), die ein Skript ist, welches die Dateien löscht, die seit dem Erstellen des Basis-Archivs gelöscht wurden. Wenn kein Delta-Archiv exisitert, dann sind die beiden Dateien leer und das Basis-Archiv alleine entspricht dem letzten Backup.
Die Dateien, die durch den o.g. Algorithmus neu geschrieben wurden, sind nach /var/backup/lokal/current/ verlinkt und von dort am Ende des cronjobs mit /root/bin/put_backup auf den Backup-Server kopiert, der in /root/etc/config genannt ist. Der gesamte Ablauf wird protokolliert und dieses Protokoll wird den Hostmastern als Mail zugesendet. Wenn also mal das Kopieren nicht klappt (Backup-Server nachts down, Verbindung unterbrochen o.ä.), dann kann dies damit einfach nachgeholt werden.
Auf dem Backup-Server gibt es je Ursprungs-Host die folgenden Verzeichnisse unterhalb von /var/backups/HOST/ (wobei HOST durch den Namen des jeweiligen Ursprungs-Hosts, z.B. Pima, zu ersetzen ist):
- current
- previous
- 2daysago
- 3daysago
- 4daysago
- ?
- 14daysago
Vor dem Backup werden alle Dateien rückwärts in das jeweils nächste Verzeichnis (13daysago -> 14daysago ? current -> previous) hart verlinkt. Dann werden die in /var/backup/lokal/current befindlichen Dateien, also alle neuen Backup-Dateien auf dem Backup-Host im Verzeichnis current gelöscht und dann neu kopiert. Dadurch sind identische Dateien (i.d.R. nur die Basis-Archive) zwar in jedem Verzeichnis passend vorhanden, benötigen aber nur einmal Speicherplatz.
Auf dem Produktiv-Server und auf dem Backup-Server werden md5 Prüfsummen der gesamten Archive, die das Backup eines Tages ausmachen, erstellt. Dies umfasst auch die vom Vortag ggf. unveränderten Basis-Archive. Diese md5 Prüfsummen werden nach dem Verlinken nach previous und nach dem Kopieren nach current verglichen und etwaige Fehler an die Hostmaster gemeldet. Eine Überprüfung der Backups mit den Originalen ist praktisch unmöglich, weil die Originale sich außer unserer Kontrolle verändern und wir absichtliche von fehlerhaften Änderungen nicht unterscheiden könnten, schon gar nicht automatisch.
Vormittags werden die Backups (*.tar.gz) in current außerdem einem Lesbarkeitstest unterzogen (/usr/local/bin/chk-backups), der die Archive einmal zur Probe auspackt. Ein Bericht und evtl. eine Liste der nicht fehlerhaften Dateien wird wieder an die Hostmaster geschickt.
Welche Backups konkret für ein Paket vorhanden sind, lässt sich außerdem auf dem Backup-Server wie folgt ermitteln:
xyz00@hopi:~$ grep "done" /var/backups/pomo/*/xyz00 .log | cut -d':' -f 2- | sort -r

