Dies ist eine alte Version des Dokuments!
Inhaltsverzeichnis
Backupskripte
Die folgenden drei Skripte können eine rund-um Backuplösung bilden. Diese besteht aus einem Backup von wichtigen Verzeichnissen, Paketlisten und MySQL-Dumbs. Dazu müssen alle drei Skripte richtig konfiguriert und angepasst werden. Wie du mit dem Code der Skripte umgehen musst, erfährst Erklärungen findest du unter Cron und Shell-Skripte.
Softwarevoraussetzungen: Paketverwaltung | Texteditor | evtl. Mailserver | Cron
Schwierigkeitsgrad: Mittel
Ausgetestet mit folgenden Betriebssystemen: Ubuntu (Karmic, Lucid, Lucid++) | Debian (Lenny, Squeeze) | teilweise auch andere Distributionen
Achtung! sudo:
In dieser Anleitung verdeutlicht der Befehl sudo
, dass die folgende Codezeile mit Root-Rechten ausgeführt werden muss.
In normalen Ubuntu Installationen (Root-/VServer siehe Debian) kann dies durch den Befehl sudo
erreicht werden.
Bei Debian wird bei der Installation ein Passwort für den Root-Benutzer festgelegt, so kann man sich entweder direkt als Root oder als „normaler“ Benutzer mit Eingabe von su
als Root einloggen (Root-Passwort benötigt) → sudo
bleibt dann überflüssig!
Einfaches Backupskript
Von ubuntuusers.de
Mit diesem einfachen Skript kann man durch Cron automatisierte Backups durchführen, indem man es regelmäßig von Cron ausführen lässt. Das Skript kopiert immer nur die veränderten Dateien, der Rest wird mit Hardlinks verlinkt.
Eine ausführlichere Beschreibung der Konfiguration findet man ubuntuusers.de. Hier wird lediglich die Einrichtung beschrieben.
Benötigte Pakete
Benötigt wird zusätzlich noch das Paket rsync
:
user@server:~$ sudo apt-get install rsync
Abspeichern und ausführbar machen
Dieses Skript muss irgendwo im Dateisystem unter beliebigen Namen abgespeichert werden (hier: backup_rsync
), dazu erstellt man mit nano diese Datei:
user@server:~$ mkdir ~/bin #Anlegen eines Skriptordners user@server:~$ touch ~/bin/backup_rsync #Anlegen des Skriptes
Anschließend muss es ausführbar gemacht werden:
user@server:~$ chmod +x ~/bin/backup_rsync #ausführbar machen
Inhalt des Skriptes
Anschließend öffnet man das Skript:
user@server:~$ nano ~/bin/backup_rsync #öffnen des Skriptes
….und fügt diesen Code ein:
- backup_rsync
#!/bin/bash # Simple backup with rsync # SOURCES and TARGET must end with slash SOURCES="/was/soll/gesichert/werden1?/ /was/soll/gesichert/werden2?/ (...)" TARGET="/Ziel/der/Backups/(wo_sollen_die_Backups_hin?/" MOUNTPOINT="" LOGFILE="/wo_soll_die_Logadatei_hin?" EXPIREDAYS=0 RSYNC="--delete" #falls via ssh hier Benutzer, Hostname und Port eintragen #SSHUSER="user" #SSHHOST="hostname" #SSHPORT=22 ### do not edit ### /bin/date > $LOGFILE MOUNTED=$(/bin/mount | /bin/fgrep "$MOUNTPOINT"); if [ -z "$MOUNTPOINT" ] || [ -n "$MOUNTED" ]; then if [ -e $TARGET ]; then LASTBACKUP=$(/bin/ls -d $TARGET[[:digit:]]* 2>> $LOGFILE | /usr/bin/sort -r | /usr/bin/head -1) fi TODAY=$(/bin/date +%y%m%d) if [ $EXPIREDAYS -gt 0 ]; then EXPIRED=$(/usr/bin/find $TARGET[[:digit:]]* -maxdepth 0 -ctime +$EXPIREDAYS 2>> $LOGFILE) for EX in $(/bin/echo $EXPIRED) do /bin/echo "rm -rf $EX " >> $LOGFILE /bin/rm -rf $EX\\ done fi for SOURCE in $(/bin/echo $SOURCES) do if [ "$LASTBACKUP" ]; then INC="--link-dest=$LASTBACKUP$SOURCE" fi if [ "$SSHUSER" ] && [ "$SSHHOST" ] && [ "$SSHPORT" ]; then SSH="ssh -p $SSHPORT -l $SSHUSER"; SOURCEDIR="$SSHHOST:$SOURCE"; else SOURCEDIR=$SOURCE; fi /bin/mkdir -p $TARGET$TODAY$SOURCE >> $LOGFILE echo "/usr/bin/rsync -e \"$SSH\" -av $SOURCEDIR $RSYNC $INC $TARGET$TODAY$SOURCE " >> $LOGFILE 2>> $LOGFILE; /usr/bin/rsync -e "$SSH" -av $SOURCEDIR $RSYNC $INC $TARGET$TODAY$SOURCE >> $LOGFILE 2>> $LOGFILE; done else /bin/echo "$MOUNTPOINT not mounted" >> $LOGFILE fi
Konfiguration
Danach sollte man noch die Pfade Target
und Sources
, sowie die weiteren Einstellungen, wie im Skript kommentiert bearbeiten.
Beispiel
Beispiel zum Sichern von /var/www
und /home/user
nach /var/backups
, wobei /home/user/test
ausgelassen werden soll (Ausschnitt der Config):
#!/bin/bash # Simple backup with rsync # SOURCES and TARGET must end with slash SOURCES="/var/www/ /home/user/" TARGET="/var/backups/" MOUNTPOINT="" LOGFILE="/var/log/backup.log" EXPIREDAYS=0 RSYNC="--delete --exclude=test/" #Auslassen von /home/user/test #SSHUSER="user" #SSHHOST="hostname" #SSHPORT=22 ### do not edit ### (..)
Wenn das Backup auf ein externes Medium erfolgen soll, dass nicht immer zuverlässig gemountet wird, ist es ratsam die Option MOUNTPOINT=„“
auf den Mountpoint (siehe Mounten) dieses Mediums zu setzen:
MOUNTPOINT="/media/test" #Beispiel mit dem Mountpoint /media/test
In Cron ausführen
Zum Schluss muss das Skript noch regelmäßig durch Cron ausgeführt werden.
user@server:~$ sudo crontab -e #Crontab von root editieren
Ein- oder zweimal täglich ist ein guter Ansatz (hier um 08:01 und 14:01 Uhr):
01 08,14 * * * /home/user/bin/backup_rsync #/home/user durch Pfad zum Homeverzeichnis ersetzen (root: /root; andere Benutzer: user durch Benutzername ersetzen)
Achtung: Wenn die beiden anderen Skripte eingesetzt werden, muss dieses Skript vor den beiden anderen ausgeführt werden! Die anderen Skripte warten darauf, bis dies gestartet wurde.
Grund: Wenn die anderen Skripte früher ausgeführt werden, legen diese den Tagesordner bereits an → es entstehen keine Hardlinks.
MySQL-Backupskript
Dieses Skript lässt sich sehr gut auf das obere einfache Backupskript abstimmen. So werden Backups in die gleichen Verzeichnisse erstellt. Das Skript sichert bei jedem Durchlauf jede Datenbank einzeln und komprimiert diese zu einem Tarball.
Abspeichern und ausführbar machen
Dieses Skript muss wie bei Skript Nr.1 irgendwo im Dateisystem unter beliebigen Namen abgespeichert werden (hier: backup_mysql
), dazu erstellt man mit nano diese Datei:
user@server:~$ touch ~/bin/backup_mysql #Anlegen des Skriptes
Anschließend muss es ausführbar gemacht werden:
user@server:~$ chmod +x ~/bin/backup_mysql #ausführbar machen
Inhalt des Skriptes
Anschließend öffnet man das Skript:
user@server:~$ nano ~/bin/backup_mysql #öffnen des Skriptes
….und fügt diesen Code ein:
- backup_mysql
#!/bin/bash ########INFOS################################################################################################################ #skript legt im Pfad ${path}/${datum}/${sub}/$clock/$db Sicherungen jeder Datenbank einzeln an. #Diese werden kompromiert (gzip) und zu einem gemeinsamen Archiv (tar) zusammen gefügt. #Das Skript schreibt ein Logfile mit allen Fehlermeldungen und Abläufen und mailt bei Bedarf den Ablauf per Mail an den Admin. #Falls eine Mailadresse angegeben wird, wird mit dem Logfile eine Mail an diese gesendet. ## # das Skript legt eine $logfile.log.tmp an (hier in Beispielconf: /var/log/backupsql.log.tmp). Um die Logs mit tail -f zu #zu betrachten muss die $logfile.log.tmp verwendet werden (einfach an die angegebene Logdatei ein .tmp anhängen) #In der normalen Logdatei, die hier angegeben wird, werden alle Durchläufe gespeichert, in der .tmp immer nur der aktuelle, #anschließend wird jene bis zum Neudurchlauf des Skriptes gespeichert. ## #Angelegter Pfad: ${path}/${datum}/${sub}/$clock/$db ## #Bugs und sonstiges an: chrisge[at]mein.homelinux[dot]com #Erstellt durch: Christoph Winkler ############################################################################################################################## #######CONFIG################################################################################## ##Beispiel: #bereits vorhandene Config; sieht so aus: #/home/christoph/backups/server/v.1/10-06-29/mysql/16:31.tar #Pfad dem entsprechend so anpassen, wie erwünscht #Falls obrige Struktur auch verwendet werden will nur "path" an eigene Bedürfniss anpassen #und bei Bedarf Mailadresse und Betreff angeben. =>fertig! #####Pflicht #Der Pfad für die Backups (muss angepasst werden) path="/home/christoph/backups/server/v.1" #Das aktuelle (kann angepasst werden) datum="$(date +%y%m%d)" #Die Zeit zu der das Backup angefertigt wurde (kann angepasst werden) clock="$(date +"%R")" #Es wird ein extra Ordner für mySQL angelegt, so haben andere Backups unter selbem Pfad Platz sub="mysql" #mySQl User user="root" #Passwort des mySQl Users password="" #File für die Logs logfile="/var/log/backupsql.log" ######optional #die Mailadresse des Admins (leer lassen=keine Mail) mailaddr="root@localhost" #der Betreff der Mail (wird zum Versenden der Mail benötigt; falls nich angegeben kann keine Mail versendet werden!) mailbetr="mySQL-Sicherung" ######erweitert #Diese Skript wurde darauf konzipiert mit anderen Skripten zusammen zu arbeiten. Viele rsync Skripte müssen den täglich #Backupordner aber selbst anlegen, da sonst (unter Umständen) keine Hardlinks verwendet werden. Dieses Skript wird, wenn diese #Option auskommentiert ist (#) ganz normal ausgeführt. Beim entfernen des "#" läuft das Skript nur durch, wenn der $datum Pfad durch #das andere Backupskript angelegt wurde. #Die Option kann für die meisten einfachen Einsatzzwecken weggelassen werden. #create="yes" ################################################################################################# ########NICHT#VERÄNDERN############# #Befehl #Lognachricht if test -r ${logfile}.tmp ; then rm ${logfile}.tmp && touch ${logfile}.tmp else touch ${logfile}.tmp fi echo " $(date): SQl-Backup gestartet" >> ${logfile}.tmp if [ "$create" ]; then echo "$(date): Lege benötigte Ordner an" >> ${logfile}.tmp if test -d $path/$datum ; then echo "$path/$datum existiert bereits (Normal)" >> ${logfile}.tmp else if [ "$mailaddr" ] && [ "$mailbetr" ] ; then echo "$path/$datum besteht noch nicht; exit, da Option "create" aktiv ist" >> ${logfile}.tmp && echo "Mail mit Betreff "${mailbetr}-failed" an $mailaddr gesendet" >> ${logfile}.tmp && mail -s ${mailbetr}-failed ${mailaddr} < ${logfile}.tmp && cat ${logfile}.tmp >> ${logfile} && exit 1 else echo "$path/$datum besteht noch nicht; exit, da Option "create" aktiv ist" >> ${logfile}.tmp && echo "=>keine Mailadresse angegeben, deshalb keine Mail versendet" >> ${logfile}.tmp && cat ${logfile}.tmp >> ${logfile} && exit 1 fi fi else echo "$(date): Lege benötigte Ordner an" >> ${logfile}.tmp if test -d $path/$datum ; then echo "$path/$datum existiert bereits (Normal)" >> ${logfile}.tmp else mkdir $path/$datum && echo "$path/$datum angelegt" >> ${logfile}.tmp fi fi if test -d ${path}/${datum}/${sub} ; then echo "${path}/${datum}/${sub} existiert bereits (Normal)" >> ${logfile}.tmp else mkdir ${path}/${datum}/${sub} && echo "${path}/${datum}/${sub} angelegt" >> ${logfile}.tmp fi if test -d ${path}/${datum}/${sub}/$clock ; then echo "${path}/${datum}/${sub}/$clock existiert bereits =>Achtung: Backup bereits diese Minute ausgeführt" >> ${logfile}.tmp else mkdir ${path}/${datum}/${sub}/$clock && echo "${path}/${datum}/${sub}/$clock angelegt" >> ${logfile}.tmp fi echo "$(date): Sichere MySQL Datenbanken" >> ${logfile}.tmp for db in `echo show databases | mysql -u root -p$password | egrep -v "^Database$"` do mysqldump --opt -u $user -p$password ${db} > ${path}/${datum}/${sub}/$clock/$db.sql --lock-tables=false && echo "Datenbank $db nach ${path}/${datum}/${sub}/$clock/$db.sql gesichert" >> ${logfile}.tmp done && echo "=>Datenbanken erfolgreich gesichert" >> ${logfile}.tmp echo "$(date): Komprimiere Datenbanken && räume auf" >> ${logfile}.tmp gzip -9 ${path}/${datum}/${sub}/$clock/* && echo "Datenbanken in ${path}/${datum}/${sub}/$clock/ komprimiert" >> ${logfile}.tmp cd ${path}/${datum}/${sub}/ && echo "wechsle in Ordner ${path}/${datum}/${sub}/" >> ${logfile}.tmp tar -cf ${path}/${datum}/${sub}/$clock.tar $clock && echo "${path}/${datum}/${sub}/$clock komprimiert" >> ${logfile}.tmp rm -r ${path}/${datum}/${sub}/$clock && echo "räume ${path}/${datum}/${sub}/$clock auf (Backups liegen nun in ${path}/${datum}/${sub}/${clock}.tar" >> ${logfile}.tmp echo "$(date): !SQl-Backup beendet!" >> ${logfile}.tmp echo "$(date): Versende nun Mail" >> ${logfile}.tmp if [ "$mailaddr" ] && [ "${mailbetr}" ] ; then mail -s ${mailbetr} ${mailaddr} < ${logfile}.tmp && echo "Mail mit Betreff "${mailbetr}" an $mailaddr gesendet" >> ${logfile}.tmp else echo "=>keine Mailadresse angegeben, deshalb keine Mail versendet" >> ${logfile}.tmp fi cat ${logfile}.tmp >> ${logfile}
Konfiguration
Die Doku des Skriptes ist eigentlich sehr verständlich. Trotzdem erfolgt nun noch eine kleine Anweisung.
Option "create"
Wenn alle drei hier aufgeführten Skripte zusammenarbeiten sollen, muss create
von
#create="yes"
auf
create="yes"
gesetzt werden.
Beispiel
Hier arbeitet das Skript mit den beiden anderen zusammen, sämtliche weiteren Optionen können fast bei den Standarteinstellungen belassen werden. Allerdings müssen die Zugangsdaten zur MySQL Datenbank (user
, password
) angepasst werden. Außerdem besteht die Möglichkeit sich das Logfile per Mail zuschicken zu lassen.
path="/var/backup" #Pfad zum Backupdir (identisch mit oben genannten) datum="$(date +%y%m%d)" #Datumssyntax clock="$(date +"%R")" sub="mysql" user="root" password="geheim" logfile="/var/log/backupsql.log" mailaddr="root@localhost" mailbetr="mySQL-Sicherung" create="yes"
In Cron ausführen
Zum Schluss muss das Skript noch regelmäßig durch Cron ausgeführt werden.
user@server:~$ sudo crontab -e #Crontab von root editieren
Hier wird das Skript alle 2 Stunden ausgeführt:
0 */2 * * * /home/user/bin/backup_mysql #/home/user durch Pfad zum Homeverzeichnis ersetzen (root: /root; andere Benutzer: user durch Benutzername ersetzen
Paketlisten speichern
Dieses Skript, dass sich vollkommen auf die beiden oberen Skripte stützt, speichert so oft man es ausführt eine Liste mit den installierten Paketen.
Abspeichern und ausführbar machen
Dieses Skript muss irgendwo im Dateisystem unter beliebigen Namen abgespeichert werden (hier: backup_pks
), dazu erstellt man mit nano diese Datei:
user@server:~$ touch ~/bin/backup_pks #Anlegen des Skriptes
Anschließend muss es ausführbar gemacht werden:
user@server:~$ chmod +x ~/bin/backup_pks #ausführbar machen
Inhalt des Skriptes
Anschließend öffnet man das Skript:
user@server:~$ nano ~/bin/backup_pks #öffnen des Skriptes
….und entscheidet sich für einen der Beiden Skripte:
a) Zusammenarbeit mit den oberen
Diese Version des Skriptes ist bereits an die oberen beiden angepasst:
- backup_pks
#!/bin/bash #Pfad zum Backup path="/var/backup/$(date +%y%m%d)" #Name der datei name="packages.list" ###zurück setzen: xargs -a "packages.list" sudo apt-get install if test -d $path; then sudo dpkg --get-selections | awk '!/deinstall|purge|hold/ {print $1}' > $path/$name else exit 0 fi
b) frei Verwenden/ keine Zusammenarbeit
Um das Skript ohne oben genannte einzusetzen, würde das Ganze so aussehen:
- backup_pks
#!/bin/bash #Pfad zum Backup path="/var/backup/$(date +%y%m%d)" #Name der datei name="packages.list" ###zurück setzen: xargs -a "packages.list" sudo apt-get install if test -d $path; then sudo dpkg --get-selections | awk '!/deinstall|purge|hold/ {print $1}' > $path/$name else mkdir $path fi
In Cron ausführen
Zum Schluss muss das Skript noch regelmäßig durch Cron ausgeführt werden.
user@server:~$ sudo crontab -e #Crontab von root editieren
Am Besten alle 4 Stunden ausführen:
0 */4 * * * /home/user/bin/backup_pks #/home/user durch Pfad zum Homeverzeichnis ersetzen (root: /root; andere Benutzer: user durch Benutzername ersetzen
— chrisge 2011/07/28 19:19
Diskussion