Tägliches inkrementelles Backup mit cron und tar unter Linux
Wer einen Server betreibt, kann unter Linux mit einfachen Bordmitteln ein tägliches Backup erstellen lassen. Dazu benötigen wir lediglich das Programm tar und den Dienst cron. Am ersten jeden Monats wird ein vollständiges Backup erstellt und an jedem folgenden Tag werden nur die Änderungen vom Vortag gespeichert. Das spart ungemein Speicherplatz, vor allem da sich in den meisten Dateibäumen nur ein kleiner Teil der Daten täglich ändert.
Vorbereitungen
Als Beispielsystem wird hier Ubuntu angenommen, wobei im Prinzip jedes andere Unix (auch Mac OS X) ähnlich funktionieren dürfte.
Folgende Software muss auf dem System vorhanden sein:
- tar
- cron (Alternativ könnte man hier vermutlich mit anacron arbeiten, z.B. für Laptops. Darauf will ich hier jedoch nicht eingehen)
Praktisch alle modernen Unix-Systeme installieren beide Programme standardmäßig.
Das Backup-Skript
Man lege das Backup-Skript in ein Verzeichnis z.B. /usr/local/sbin/ mit folgenden Befehlen:
cat > /usr/local/sbin/backup.sh << EOF
#!/bin/bash
#################################################
# Einfaches inkrmentelles Backup Programm Max Kalus
#################################################
BACKUPDIR=/var/local
LASTMONTHDIR=lastmonth
TSNAME=timestamp.snar
BACKUPNAME=backup
DIRS="/home /etc"
if [ $1 == "complete" ]; then
#Komplettes Backup
MYDATE=complete
#Alte Timestamps löschen
rm -f "$BACKUPDIR/$TSNAME"
#Alte Backups löschen
rm -rf "$BACKUPDIR/$LASTMONTHDIR.$BACKUPNAME.d"
#Neue alte Backups in Ordner verschieben
mkdir "$BACKUPDIR/$LASTMONTHDIR.$BACKUPNAME.d"
mv -f "$BACKUPDIR/$BACKUPNAME.*".tgz "$BACKUPDIR/$LASTMONTHDIR.$BACKUPNAME.d"
else
#Inkrementelles Backup
MYDATE=$(date +%y%m%d)
fi
#Abzug erstellen
tar czf "$BACKUPDIR"/"$BACKUPNAME".$MYDATE.tgz -g "$BACKUPDIR/$TSNAME" "$DIRS" 2> /dev/null
EOF
chmod +x /usr/local/sbin/backup.sh
Damit wird ein SKript erstellt, dass Backups inkrementell erstellen kann. Man kann folgende Parameter ändern:
- BACKUPDIR Verzeichnis, in das die Backups gespeichert werden. Könnte also auch eine USB-Festplatte sein (z.B. über /media/USB).
- LASTMONTHDIR Name des Verzeichnisses für letzten Monat
- TSNAME Name der Timestamp-Datei
- BACKUPNAME Präfix der Backups
- DIRS Liste der Verzeichnisse, die gespeichert werden sollen
Eleganter wäre hier mittelfristig eine Parameterübergabe per Kommandozeile, vielleicht hat jemand Lust, das zu erstellen und mir zu schicken…
Es gibt im Skript 2 Modi: a) vollständiges Backup (mit Parameter “complete”) und b) inkrementell. Beim vollständigen Backup werden die alten Daten in einen Unterordner “lastbackup” verschoben, damit auf den letzten Monat noch zugegriffen werden kann, falls Bedarf besteht.
cron einrichten
Nach der Einrichtung des Skripts kann man cron einrichten. In den meisten Fällen wird man vermutlich das Skript als root ausführen lassen wollen:
sudo crontal -e
Hier folgende Zeilen einfügen:
#Dump jeden Tag, am ersten des Monats vollständig
10 1 1 * * /usr/local/sbin/backup.sh complete
10 1 2-31 * * /usr/local/sbin/backup.sh
Damit wird am ersten jeden Monat um 1:10 ein komplettes Backup erstellt und an allen anderen Tagen ein inkrementelles. Der cron-Dienst muss hierzu laufen (bei MacOS X schaltet der Dienst sich, glaube ich, direkt ein, sobald ein crontab existiert).
Der Bedarfsfall: Retten der Daten
Um einen bestimmten Zustand wiederherzustellen, muss man die Sicherungen nacheinander einspielen. Dabei wird mit der Vollsicherung begonnen. Dann werden nacheinander die inkrementellen Snapshot-Archive eingespielt.
Vollständig sollte das mit folgenden Befehlen gehen:
tar xzf /var/local/backup.complete.tgz --listed-incremental=/var/local/timestamp.snar
ls /var/local/backup.[0-9][0-9][0-9][0-9][0-9][0-9].tgz | sort | xargs tar xzf --listed-incremental=/var/local/timestamp.snar
Meinungen und Hinweise nehme ich gerne entgegen!
- 5 Kommentare
Fehler
Hallo!
Schönes, kleines Tutorial!
Leider bringt mir das Script so in Zeile 26 (irgendwo beim “fi”) einen Fehler und bricht ab.
(Mint Linux, auf Ubuntu 9.04 basierend)
Re: Fehler
Hallo!
welcher Fehler wird denn ausgegeben?
Max.
Ubuntu
Unter Ubuntu ist /bin/sh wirklich die Bourne Shell. Bei Debian ist es ein Symlink auf /bin/bash, also die Bourne Again Shell. Das erklärt auch, wieso das Script auf Debian fehlerfrei läuft.
Ohne das Script jetzt überhaupt getestet zu haben, wird der Fehler hier liegen:
MYDATE=$(date +%y%m%d)
Die Bourne Shell unterstützt die POSIX-Kommandosubstitution nicht. Die wurde erst mit der Bash eingeführt. Entweder du verwendest die alte Methode der Kommandosubstitution:
MYDATE=`date +%y%m%d`
oder du änderst den Shebang auf #!/bin/bash, was in der Regel auf jedem neueren System vorhanden sein sollte.
Kleinere Fixes
Hi,
Erstmal: Danke, hat mir Arbeit erspart. :)
Kleine Fixes musste ich dann doch machen, damit es läuft (Ubuntu Server 10.04):
Zeile 1 wie schon erwähnt ändern in #!/bin/bash
Zeile 8 ändern in:
if [ "$1" == "complete" ]; then
Die "" um $1 damit es keinen Fehler gibt wenn kein Parameter übergeben wird und == statt = ... ist klar. ;)
Gruß, Peter
Re: Kleinere Fixes
Danke für die Hinweise. Ich habe das direkt geändert.