Inkrementelles Backup eines Webhosting Auftritts per sshfs

Viele Webhoster bieten eine Möglichkeit, einfache Backups zu erstellen oder diese sogar nach „extern“ per FTP wegzusichern. Dummerweise handelt es sich bei dieser Sicherung jedes mal um ein Fullbackup. Will sagen, in der Regel hat man genau einen Wiederherstellungspunkt für das Backup auf dem Webserver liegen. Oder eben alternativ viele Fullbackups auf einem FTP Server – wobei man hier ja auch noch aufpassen muss, dass die Backups sich nicht bei jedem Lauf überschreiben. Meistens heißen die Dateien ja doch alle gleich.

Wie schon im vorherigen Artikel beschrieben gehe ich bei der Sicherung wie folgt vor: per sshfs wird das Filesystem des Webservers lokal gemountet. Auf dem Webserver des Hosters läuft ein CRON-Job, der jede Minute ein Script auf dem Server startet. Das Script schaut zunächst in einem Verzeichniss nach einem Startflag (Datei). Wenn die Datei gefunden wurde dumpt es die gefüllten MySQL Datenbanken ins Filesystem und schreibt die Aktionen in ein Logfile. Auf dem Backupserver wird per CRON-Job das Backuptool backup2l gestartet. In der Config des Backuptools wird vor dem Backup ein Script gestartet, dass per sshfs das Dateisystem des Webservers mountet und das Startflag für den CRON-Job auf dem Webserver erzeugt. Nach einem Timeout von 5 Minuten wird geprüft ob das Datenbankbackup gelaufen ist und eine entsprechende Meldung ausgegeben. Anschließend läuft backup2l los und sichert per afio und gzip/bzip den Inhalt des Filesystems.

Was wird benötigt?

Auf dem Webserver:

  • cron mit der Möglichkeit eigene Scripts laufen zu lassen
  • Zugang per ssh/sftp (oder ftp/webdav)
  • mysqldump

Auf dem Backupserver:

  • sshfs (alternativ curlftpfs; unverschlüsselt)
  • backup2l
  • afio (alternativ tar)
  • buffer
  • gzip/bzip

Beginnen wir nun mit dem Webserver. Hier muss ein Cronjob eingerichtet werden, der in möglichst kurzen Abständen läuft:

*/1 	* 	* 	* 	* 	/<Pfad zum Homeverzeihnis>/bin/backup_dbs.sh

Das Script muss ausführbar sein (chmod 750) und sieht bei mir so aus:

#!/bin/bash
#Programm zum Sichern der MySQL Datenbanken
#Patrick Wessel, 23.02.2009

#Konstanten
WORK=/<Homeverzeichnis>/sqldump
SQLUSER=dbuser
SQLDATENBANK=sql_prefix_*
DUMP=/usr/bin/mysqldump
QUOTA=/usr/bin/quota
TMP=/<Homeverzeichnis>/tmp
TRIGGER=$TMP/backup_dbs.run
LOCK=$TMP/backup_dbs.lock
LOG=$WORK/backup_dbs.log
RC=0

#Variablen
DATE=`date '+%d-%m-%Y um %H:%M:%S'`
DATE2=0

#Trigger pruefen
[ -f $TRIGGER ]  || exit 0

#Logfile anlegen
touch $LOG

#Lockfile pruefen
[ -f $LOCK ] && echo "$DATE: Backupjob laueft bereits: $(ps -ef|grep -i backup_dbs.sh)" | tee -a $LOG && exit 1
[ -f $LOCK ] || echo $DATE > $LOCK

echo " " | tee -a $LOG
echo "________________________________________________________________________________" | tee -a $LOG
echo "Starte Datenbankdump am $DATE" | tee -a $LOG
echo " "

[ -d $WORK ] || mkdir -p $WORK | tee -a $LOG

cd $WORK

for i in 1 2 3 4 5
do
    RC=0   
    echo "Datenbank $SQLDATENBANK$i" | tee -a $LOG
    $DUMP -u $SQLUSER -p<DB-User Passwort> $SQLDATENBANK$i > $SQLDATENBANK$i.sql 2> /dev/null
    RC=$?
    if [ "$RC" -gt 0 ]
    then
        if [ "$RC" -eq 2 ]
        then
            echo "Datenbank: $SQLDATENBANK$i existiert nicht" | tee -a $LOG   
            rm $SQLDATENBANK$i.sql | tee -a $LOG
        else   
            echo "Fehler beim Datenbank Dump, Returncode: $RC" | tee -a $LOG
        fi
    else
        echo "Datenbank: $SQLDATENBANK$i erfolgreich gedumpt." | tee -a $LOG
        echo "Datei: $(du -s $SQLDATENBANK$i.sql)" | tee -a $LOG
    fi    

    echo " " | tee -a $LOG
done

echo " " | tee -a $LOG
$QUOTA | tee -a $LOG

#Lock/Trigger loeschen
[ -f $LOCK ] && rm $LOCK
[ -f $TRIGGER ]  && rm $TRIGGER

#Backupzeit fuer Script setzen
DATE2=`date '+%H%M%S'`
echo $DATE2 | tee -a $LOG
exit 0

Das Scripts gibts natürlich auch zum Download

Die Ausgabe ist ein wenig formatiert. Das hat den Vorteil, dass der Output auch in einer Mail ordentlich lesbar ist. Cron verschickt in der Regel eine Email an den Webmaster (dich) mit dem Output der Cronjobs.

webservermount

triggerjob

Fortsetzung folgt…

About the author