Datenbanken mit bareos sichern
Das Sichern von Datenbanken mit bareos oder bacula ohne dabei Plugins zu benutzen ist über Skripte möglich, die in der Jobdescription über den Parameter „RunBeforeJob“ eingebunden werden. Das hier beschrieben Vorgehen lässt sich auch auf andere Backupsoftware wie z.B. rsnapshot übertragen (hier können ebenfalls Skripte eingebunden werden).
Hintergrund
Ich stand vor dem Problem meine Datenbanken in mein Backup (mit bareos) einzubinden. Die Ergebnisse verschiedener Suchläufe im Internet schlugen Plugins vor. Für die zwei der von mir genutzten Datenbanken PostgreSQL und MySQL wäre das auch ein gangbarer Weg. Allerdings bedeutete das eine ganze Menge ausprobieren basteln und selber übersetzen. Da das ganze auch direkt in einem produktiven System zum Einsatz kommen sollte verwarf ich jedoch die Idee mit den Plugins – Zeitmangel zum Ausprobieren und das Fehlen von Testsystemen waren Gründe hierfür.
Also blieb mir nur die Möglichkeit ein Skript zu bauen und dieses über den Sicherungsjob aufzurufen.
Das Mittel der Wahl waren die Dumpbefehle der jeweiligen Datenbanken. Der Nachteil der bei dem Erzeugen von Dumps entsteht, ist dass jedes mal wenn ein Dump erzeugt wird (in meinem Fall sollen die bestehenden überschrieben werden) für das Backupprogramm die Datei geändert wurde (Zeitstempel). Dadurch werden auch jedes mal die Dumpdateien neu gesichert. Für die Zielmedien (Bänder oder Festplatten) ist das eher Kontraproduktiv.
Aus diesem Grund beschloss ich die Dumps permanent in einem bestimmten Verzeichnis vorzuhalten und die aktuellen Dumps in ein temporärem Verzeichnis anzulegen, die Dumps einer Datenbank im Backupverzeichnis (Bestand) mit dem im temporären Verzeichnis über das Programm „diff“ zu vergleichen und wenn sich eine Änderung ergibt den Dump aus dem temporären Verzeichnis in das Backupverzeichnis zu verschieben. Dadurch stelle ich sicher, dass nur veränderte Dumps ihren Weg auf die Backupmedien finden.
Hinweis
Das ganze ist eher interessant für kleine Datenbanken. Sollte sich die Datenbankgröße stark vergrößern sollte man auf eines der Plugins zurückgreifen.
Skript
Genug der Theorie, hier der Codeschnipsel des Bashskriptes:
#!/bin/bash
backupDir=/var/backup/databases
tmpDir=/tmp/databases
# Sicherstellen dass die beiden Zielverzeichnisse existieren, wenn nicht dann
# neu erstellen
if [ ! -d $backupDir ]; then
mkdir $backupDir
fi
if [ ! -d $tmpDir ]; then
mkdir $tmpDir
fi
cd $tmpDir
# PostgreSQL
# Alle Datenbanke auflisten lassen und an die Liste an eine for_Schleife
# übergeben
# Nachfolgende Befehl erfordert inen Eintrag in der
# /etc/sudoers
for DB in `sudo -H -i -u postgres psql -At -c "select datname from pg_database where not datistemplate and datallowconn order by datname;" postgres`
do
echo "createing dump: $DB"
# Nachfolgende Befehl erfordert einen Eintrag in der
# /etc/sudoers
sudo -H -i -u postgres pg_dump -Fp $DB > $tmpDir/$DB.pgsql
if [ -f $backupDir/$DB.pgsql ]; then
echo "are there diffs between $DB in $tmpDir and $backupDir?"
diff $tmpDir/$DB.pgsql $backupDir/$DB.pgsql > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "diffs found -> moving $tmpDir/DB.pgsql to $backupDir"
mv $tmpDir/$DB.pgsql $backupDir/$DB.pgsql
else
echo "No diffs found in the $DB-dumps"
fi
else
echo "New databasedump -> moving to Backupdir"
mv $tmpDir/$DB.pgsql $backupDir/$DB.pgsql
fi
done
# MySQL
TARGETHOST=your.host.tld
USER=yourDbUser
Password=yourDbUserPassword
DATABASENAME=nameOfYourDb
echo "Dump MySQL-db from $TARGEHOST"
mysqldump --skip-dump-date -h $TARGETHOST -u $USER -p$PASSWORD $DATABASENAME > $tmpDir/$DATABASENAME.mysql
echo "are ther diffs between $DATABASENAME in $tmpDir and $backupDir?"
diff $tmpDir/$DATABASENAME.mysql $backupDir/$DATABASENAME.mysql > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "diffs found -> moving to $backupDir"
mv $tmpDir/$DATABASENAME.mysql $backupDir/$DATABASENAME.mysql
else
echo "No differences found an Database $DATABASENAME"
fi
# temporäre Daten löschen
rm $tmpDir/*
Wichtig beim mysqldump ist der Schalter „–skip-dump-date“. Wird dieser Schalter weggelassen, schreibt der mysqldump am Ende des Dumps noch die Information wann der Dump erstellt wurde. Das hat zur Folge, dass sich die Dumps im temporären Verzeichnis und im Backupverzeichnis immer unterscheiden und die Dumps von der Backupsoftware immer mitgesichert werden, auch wenn sich die eigentlichen Daten des Dumps nicht verändert haben.
In der /etc/sudoers muss für das Backup der Postgresdatebank folgendes eingefügt werden, sofern nicht über einen eigenen Postgresbenutzer (eindeutig der bessere Weg) gearbeitet wird:
backupuser ALL=(postgres) NOPASSWD: /usr/bin/psql, /usr/bin/pg_dump
Die Idee Datenbankdumps von Postgres über sudo zu erzeugen kommt aus den Gegebenheiten von Debian.
Zugegeben das ist nicht gerade sicher aber zum Testen allemal OK ;-).
Einbinden in bareos
Ein Beispiel für einen Einfachen Job in bareos / bacula könnte wie folgt aussehen:
# Die Jobdefinition
Job {
Name = "Backup Databases"
JobDefs = "DefaultJob"
FileSet = "Database Set"
RunBeforeJob = "/path/to/script/db-bak.sh"
}
# ... und das dazugehörige Fileset
FileSet {
Name = "Database Set"
Include {
Options {
Signature = MD5
}
File = "/var/backup/databases"
}
}
Einbinden in rsnapshot
Das Einbinden in rsnapshot erfolgt auf noch einfachere Weise:
###
backup_script /path/to/script/db-bak.sh path/to/backupfiles
###