Backup
Einleitung
Das immer wieder verschobene und heruntergespielte Thema Backup ("Also mir geht keine Festplatte hopps!") hat es doch endlich auf diese Seiten geschafft.
Fehlende Datensicherung ist schlichtweg grob fahrlässig, oder?
« zurück (Gesammelte Anleitungen)
Inhalt
Grundgedanken
Die Festplattenkapazitäten steigen und man kauft sich mal eben eine externe Festplatte mit 250 GB. Dann rippt man seine CD-Sammlung, was einen Haufen an Zeit in Anspruch nimmt und hofft, dass nichts mit der Platte passiert. Klar, die Originale hat man ja noch, aber das ganze nochmal von vorne anfangen? Nein danke!
Mails, was für eine Unmenge an Mails! Zum Glück liegen die auf dem hiesigen IMAP-Server... aber der ist ja auch schon etwas betagt. Und dann die Konfiguration der beiden Systeme... das alles wieder von Null an einrichten? Oje...
Zugegeben, mir ist noch keine Festplatte abgeraucht. Toi! Toi! Toi! Aber muss man es erst aus Schaden klug werden?
Wo sichert man diese Unmenge an Daten hin? DVD sind mit ihrer ~5 GB Kapazität nicht geeignet. Also muss eine weitere externe Festplatte her, die die angesammelten Daten speichern kann.
Eine reine Datenspiegelung ist nett, was aber ist mit versehentlich gelöschten oder korrupten Dateien? Ein Rücksprung auf ältere Versionen ist schon wünschenswert. Aber wenn man mehrere Versionen vorhält, sichert man auch wieder viele Daten doppelt und dreifach?
Fragen über Fragen... aber erstmal wollen die Festplatten richtig ins System eingebunden werden, also fangen wir doch damit an.
Externe Festplatten einhängen mit Labels
Mit zwei externen Festplatten kommt dann auch schon das erste Problem. Je nachdem, welche der Platten zuerst eingeschaltet wird, bekommt die
Gerätedatei sda
zugewiesen, die andere sdb
. Woher weiß ich denn jetzt, welche der
Partitionen ich unter /backup
und welche ich unter /data
einbinden muss?
Eine Möglichkeit der Unterscheidung ist es, den sich auf der Festplatte befindenden Dateisystemen sogenannte Labels zu verpassen.
Ein Label ist eine Bezeichnung, die auf Dateisystemebene vergeben wird. Labels können bis zu 16 Zeichen (xfs: 12 Zeichen) lang sein und werden von
den gängigen Dateisystemen ext2, ext3, reiserfs, xfs und jfs unterstützt. Labels können beim Anlegen des Dateisystems oder mit den
Managementprogrammen auch nachträglich vergeben werden. Des Setzen der Labels funktioniert (zumindest bei xfs) nicht im laufenden Betrieb, was
bei einer externen Datenplatte aber kein Problem darstellt, da man diese problemlos kurz aushängen kann. Für ein xfs-Dateisystem kann man
das Label mit dem Programm xfs_admin
setzen:
# xfs_admin -L '/backup' /dev/sda1 # xfs_admin -L '/data' /dev/sdb1
In dem obigen Fall hat die erste Partition der eingebundenen USB-Festplatte ein XFS-Dateisystem, das nun das Label "/backup" trägt. Die
andere Festplatte ist für Daten jeglicher Art gedacht und trägt das Label "/data". Die Bezeichnungen der Labels leitet sich von den
zukünftigen Mountpoints ab, die im nächsten Schritt in der Datei /etc/fstab
angegeben werden:
# /etc/fstab # ... weitere Einhaengepunkte ... ... unter anderem die Systempartitionen ... LABEL=/backup /backup xfs ro,noauto 0 0 LABEL=/data /data xfs user,noauto 0 0
Die Backup-Platte kann nur von root eingebunden werden und dann auch nur im schreibgeschützten Modus. Sie wird automatisch vor Beginn
der Backupjobs zum Schreiben gemountet und danach wieder schreibgeschützt einhängt. Die am Ende stehende 0 sorgt dafür, dass diese
Partitionen nicht von fsck
geprüft werden, da die Geräte zu diesem Zeitpunkt evtl. noch gar nicht eingeschaltet
sind.
Damit sind die Einträge unabhängig von den Gerätenamen. Das kann man natürlich auch für die ganzen Systempartitionen machen:
# /etc/fstab # LABEL=/ / reiserfs notail 0 1 LABEL=/usr /usr xfs ro 0 2 LABEL=/var /var reiserfs defaults 0 2 LABEL=/home /home xfs defaults 0 2 LABEL=schwapp none swap sw 0 0 proc /proc proc defaults 0 0 tmpfs /tmp tmpfs rw,size=64M,mode=1777,nodev,nosuid,noexec 0 0 ... weitere Einhaengepunkte ...
Wichtig bei einer solchen Systemkonfiguration mit Labels ist aber, dass diese eindeutig bleiben, wenn man neue Geräte einhängt (z.B. um von diesen Platten Daten zu retten). Das Label der Swap-Partition kann mit
# mkswap -L 'schwapp' /dev/hda6
beim Anlegen gesetzt werden.
Die externen Platten sind eingehängt... es kann losgehen!
dirvish - ein Backuptool
Grundsätzliches
Bevor man sich selbst an die Arbeit macht und eine größere Skriptlösung für eine Problemstellung erstellt, die mit Sicherheit
schon jemand programmiert hat, sieht man sich mal nach bestehenden Lösungen um. Ein mögliches Backuptool ist
dirvish
. Dieses nutzt rsync
zum Abgleich der zu sichernden Verzeichnisse und kopiert dabei nur die
Daten, die sich seit dem vorherigen Backupjob geändert haben. Die ungeänderten Daten werden als Hardlinks angelegt und somit hat man immer
einen kompletten Datenbestand als Sicherung, die alle unabhägig voneinander gelöscht werden können, wenn sie veraltet sind.
Hardlinks contra symbolische Links
Symbolische Links beinhalten einen Pfad, der auf eine Datei oder ein Verzeichnis zeigt. Ein symbolischer Link zeigt also auf den Pfadnamen einer Datei oder eines Verzeichnisses und hat sonst keinen weiteren Inhalt. Kopiert man einen symbolischen Link, kopiert man nur den Pfadnamen von der Datei, auf den der Link zeigt.
Hardlinks beinhalten einen Namen und einen Dateideskriptor, die sogenannte Inode.
Hardlinks können die Grenze eines Dateisystems nicht überschreiten, da Inodes in jedem angelegten Dateisystem unabhängig voneinander gezählt werden. Es kann somit in zwei verschiedenen Dateisystemen die Inode mit der Nummer 13544 geben, die natürlich auch unterschiedliche Dateien repräsentieren.
Hinter jeder Inode verbirgt sich ein Datenbereich im Dateisystem, zu dem die Eigenschaften wie die Größe, Besitzer und Zugriffsrechte, Erstellungsdatum, etc. und auch die Anzahl der auf sie zeigenden Hardlinks beinhaltet. Legt man einen neuen Hardlink an, wird diese Anzahl um eins erhöht. "Löscht" (unlink) man einen dieser Links, verringert sich diese Zahl um eins. Wenn die Anzahl der auf eine Inode zeigenden Hardlinks auf 0 steht, wird der von der Inode reservierte Datenbereich freigegeben.
Das Löschen einer Datei mit rm
entspricht also lediglich dem Entfernen eines Hardlinks von einer Datei. In der
Systemprogrammierung findet man deswegen auch keine Funktion rm()
oder remove()
,
sondern unlink()
.
Wird nun eine veraltete Datensicherung gelöscht, geschieht das unabhängig von den anderen Datenbeständen. Der Hauptvorteil bei der Verwendung von Hardlinks liegt darin, dass gleiche Daten nur einmal auf der Platte landen. Ein weiterer Hardlink darauf macht nur wenige weitere Bytes aus. Damit kann man eine große Anzahl an Tagesständen sichern, zu denen man immer zurückkehren oder einzelne Dateien daraus wiederherstellen kann.
Globale Konfiguration
Vorher noch ein paar Überlegungen:
- Sollen auch Daten von anderen Hosts gesichert werden?
- Was soll überhaupt gesichert werden?
- Was soll nicht gesichert werden?
Um verschiedene Szenarien abzudecken, hier die Konfiguration für zwei Hosts, auf denen diverse Datenbereiche separat gesichert werden sollen.
Die Hostnamen sind iridium
und selenium
, die jeweils als eine eigene bank definiert werden.
In so einer Bank liegen nun mehrere vaults (engl: vault = Tresor), in denen die Dateien und Statistiken der Backupjobs abgelegt werden. Jedes
zu sichernde Verzeichnis bekommt somit einen eigenen Tresor zugewiesen. Über die Tresornamen werden auch die bei einem
run-all
auszuführenden Backupjobs angesprochen, gelistet unterhalb der Option Runall
.
Beispiel der globalen Konfigurationsdatei /etc/dirvish/master.conf
:
bank: /backup/iridium /backup/selenium xdev: 1 log: gzip index: gzip image-default: %Y%m%d exclude: lost+found/ core *~ .nfs* Runall: iridium-data iridium-etc iridium-home iridium-root selenium-etc selenium-home selenium-root selenium-var_lib_cvs selenium-var_spool_cyrus selenium-var_spool_sieve expire-default: +15 days expire-rule: # MIN HR DOM MON DOW STRFTIME_FMT * * * * 1 +3 months # ^--- Sonntags ausgefuehrte Backups haben # eine laengere Aufbewahrungszeit
Die Optionen aus der Konfigurationsdatei im einzelnen:
-
bank
Definiert die Wurzelverzeichnisse für die Datensicherung. Hier wurden für zwei Hosts jeweils ein eigenes Verzeichnis angelegt. Darunter liegen dann die Vaults, in denen die Sicherungjobs abgelegt werden. -
xdev: 1 oder 0
1 = nicht über Partitonsgrenzen hinweg sichern (keine Symlinks verfolgen) -
log, index: gzip oder bzip2
Von jeder Sicherung wird je ein Index und ein Logfile erstellt. Mit dieser Option werden diese Textdateien mit dem angegebenen Packprogramm komprimiert. -
image-default: Datumsformat
Legt das Format für den Verzeichnisnamen der jeweiligen Sicherung fest. Bei der obigen Konfiguration (%Y%m%d) zum Beispiel werden die Sicherungen dann wie folgt abgelegt:/backup/iridium/iridium-etc/20070427 /backup/iridium/iridium-etc/20070428 ...
-
exclude: File Pattern
Globale Ausnahmen, die nicht mitgesichert werden sollen. Diese können noch in den einzelnen Sicherungsjobs erweitert werden. -
Runall: Job List
Die Sicherungsjobs werden beim Aufruf von dirvish-runall ausgeführt. Hinter den Jobs kann auch noch eine Zeitangabe stehen, z.B.iridium-root 23:00
die aber rein kosmetischer Natur ist. Der Backup trägt dann den angegebenen Zeitstempel, z.B. aus Konsistenzgründen. -
expire-default: Time Value (Format von
Time::ParseDate
Perl Modul)
Default Zeitraum, nachdem ein Backup ungültig, sprich gelöscht, wird. -
expire-rule:
Regeln, um bestimmten Backups ein anderes Verfallsdatum, als das unter dem Default Zeitraum eingestellten, zu verpassen. Hier wird z.B. jedes am Sonntag erstellte Backup auf 3 Monate eingestellt (Day Of Week = 1 = Sonntag).# MIN HR DOM MON DOW STRFTIME_FMT * * * * 1 +3 months
Weitere, hier nicht verwendete Optionen:
-
rsh: Remote Shell (z.B.
ssh -c arcfour
)
-
image-perm: Oktalwert (z.B. 700)
Rechte, mit denen die erstellten Backupverzeichnisse angelegt werden. -
meta-perm: Oktalwert (z.B. 600)
Rechte, mit denen die erstellten Indexe (Liste der gesicherten Daten) angelegt werden.
Backup Job Konfiguration
In jedem Vault muss ein Verzeichnis dirvish
angelegt werden, das eine eigene Konfigurationsdatei mit dem Namen
default.conf
hat. Hier ein Beispiel für diese Datei:
# /backup/iridium/iridium-home/dirvish/default.conf client: iridium tree: /home/ exclude: *.bak .googleearth/Cache/* .gftp/cache/* .java/deployment/cache/* .kde/share/apps/kmail/dimap/* .kde/share/apps/kmail/imap/* .kde/share/apps/nsplugins/cache/* .kde/share/apps/RecentDocuments/* .kde/share/config/session/* .macromedia/* .mcop/trader-cache/* .mozilla/firefox/default/*/Cache/* .mozilla-thunderbird/*/ImapMail/* .netbeans/*/var/cache/* .opera/cache4/* .opera/cacheOp/* .opera/images/* .thumbnails/*
Verwendete Optionen:
-
client: Hostname
Definiert, auf welchem Host die zu sichernden Daten liegen. -
tree: Wurzelverzeichnis
Definiert das zu sichernde Verzeichnis. -
exclude:
Erweiterung der globalen Ausnahmen speziell für diesen Sicherungsjob.
Es werden also auf dem Rechner iridium alle Heimverzeichnisse, abgesehen von den definierten Ausnahmen, gesichert. Die obige Konfiguration ist nicht weiter kompliziert und sollte klar sein.
Tresor Initialisierung
Bevor man dirvish nun im regelmäßigen Betrieb einsetzen kann, müssen die Tresore einmalig initialisiert werden. Hierzu werden alle Daten aus den zu sichernden Verzeichnissen in die Tresore kopiert, was je nach Datenmenge eine Weile dauern kann. Außerdem erzeugen dirvish-Läufe hohe Festplattenlast, was im Falle des Einsatzes in Produktivumgebungen zu beachten ist.
Die Initialisierung der Tresore erfolgt durch sequentielles Aufrufen von dirvish
mit der Option
--init
:
# dirvish --vault iridium-data --init # dirvish --vault iridium-etc --init # dirvish --vault iridium-home --init etc.
Nach der Initialisierung sind bereits alle zu sichernden Verzeichnisse zusätzlich innerhalb der Tresore gespeichert. Beim nächsten, zeitgesteuerten Aufruf von dirvish wird bereits der erste Abgleich damit durchgeführt. Während die Datenmenge nach der Initialisierung noch genauso groß wie die der zu sichernden Verzeichnisse ist, wird bei den Folgesicherungen nur noch der Teil an Speicherplatz zusätzlich belegt, den die seitdem geänderten Dateien einnehmen. Dennoch werden alle Dateien und Verzeichnisse in der Hierarchie vorhanden sein. Die ungeänderten Dateien belegen dabei aber kaum zusätzlichen Platz (zur Erinnerung: siehe Hardlinks im Kasten oben).
Einbinden der Backupjobs in Cron
Definition Cronjob
Ein Cronjob ist bei debian bereits vorkonfiguriert und liegt unter /etc/cron.d/dirvish
bereit:
# /etc/cron.d/dirvish # run every night 4 22 * * * root /etc/dirvish/dirvish-cronjob
Der Backupjob wird jeden Tag um 22:04 Uhr gestartet. Ich persönlich bevorzuge es, wenn der Job direkt in der Datei
/etc/crontab
gelistet ist, am besten noch mit einer Kontrolle, ob das Skript existiert:
# /etc/crontab # # [... weitere Eintraege (z.B. anacron) ...] # run a backup using dirvish 4 22 * * * root test -x /etc/dirvish/dirvish-cronjob && /etc/dirvish/dirvish-cronjob
Jetzt fehlt nur noch das dazu gehörende Shellskript.
Das auszuführende Skript
Wenn man es sich ganz einfach machen will, reicht ein Einzeiler:
#!/bin/bash /usr/sbin/dirvish-expire --quiet && /usr/sbin/dirvish-runall --quiet
Es wird zuerst ein dirvish-expire
ausgeführt, um veraltete Backups zu löschen. Die Skripte
dirvish-runall
und dirvish-expire
sollten
nie zusammen (sprich: parallel) ausgeführt werden, da dirvish-expire
sehr rechenintensiv arbeitet
und der Backupvorgang dadurch sehr verlangsamt würde.
Bei diesem Skript muss allerdings gewährleistet sein, dass unter /backup
permanent das Backuplaufwerk eingehängt ist!
Es folgt ein Skript, das auf dem mitgelieferten Standardskript von debian basiert. Die darin enthaltene Funktion mount_check()
ist für mich etwas ungüstig, da der Mountcheck nur mit ext2 bzw. ext3 Dateisystemen funktioniert. Da ich aber XFS benutze, habe ich die
Funktion so umgeschrieben, dass nach der bank /backup/iridium gesucht wird, die in jedem Fall existieren muss, wenn das
Backuplaufwerk gemountet ist.
Außerdem soll eine Benachrichtigung erfolgen, bevor dirvish loslegt!
Hierfür wird mit dem Programm kdialog
direkt
bei dem angemeldeten Benutzer nachgefragt, ob es losgehen kann. Außdem wird nochmal auf das Einhängen der Festplatten aufmerksam gemacht,
worum sich das Skript nicht kümmert.
- Download dirvish-cronjob.txt (15.02.2009)
... und die Hilfsfunktionen in Download helper-functions.sh.txt
Neue Version des Skriptes, die einen Statusreport verschickt und auf Fehler hinweist. Diese Dateien müssen nach/etc/dirvish/dirvish-cronjob
bzw./etc/helper-functions.sh
kopiert werden. - Download dirvish-cronjob.txt (02.12.2007)
Meine ursprüngliche Version des Skriptes, ohne Statusreport via E-Mail.
Hinweis: Für einen automatisch ohne Nachfragen zu startenden Backupjob ist dieses Skript nicht zu gebrauchen, da es auf Interaktion wartet.
Clientspezifische Einstellungen
Man kann die Einstellungen für jeden zu sichernden Client überschreiben. Dazu legt man eine Datei mit dem Hostnamen unterhalb von
/etc/dirvish
ab, z. B.: /etc/dirvish/iridium
, wenn der Rechner iridium
heißt. In der Manpage
dirvish.conf(5)
wird das mit dem Namen client[.conf]
abgehandelt.
Eine mögliche Anwendung wäre z. B. die Verwendung eines speziellen Backupusers an Stelle von root
. Dieser muss natürlich
(Lese-)Zugriff auf die zu sichernden Daten haben. Um das zu erreichen, überschreiben wir einfach die Remote-Shell für den Rechner
iridium
:
# /etc/dirvish/iridium rsh: ssh -l backupuser
Damit das ohne Passwortabfrage funktioniert, muss natürlich wieder der öffentliche SSH-Schlüssel des Benutzers kopiert werden, der dirvish
auf dem Backupserver ausführt. Normalerweise ist das root
(via Cron). Informationen zu der SSH-Authentifizierung via Public Key
habe ich hier beschrieben: Authentisierung mit PublicKey-Verfahren und SSH-Agent.
Grundsätzlich kann man natürlich auch alle anderen Konfigurationsparameter für einen Client überschreiben.
Und jetzt: Back it up!
Weiterführende Links
Weiteres zu dem Programm dirvish
gibt es natürlich auch noch auf anderen Seiten:
- Offizielle dirvish Webseite
http://www.dirvish.org/ -
Gute Anleitung (Basis dieser Doku)
http://wiki.edseek.com/howto:dirvish