MySQL - Datenbank Backup Script
In einem meiner vorigen Beiträge habe ich beschrieben, wie man MySQL-Datenbanken mit mysqldump kopieren kann.
In Verbindung mit einem Cronjob eignet sich mysqldump aber auch hervorragend dazu, Sicherheitskopien von Datenbanken anzulegen. Das folgende Bash Script nutze ich, um täglich ein Backup aller MySQL-Datenbanken eines Servers anzulegen…
#!/bin/sh #Zugangsdaten mysql_user="MYSQL_BENUZERNAME" mysql_pass="MYSQL_PASSWORT" mysql_host="localhost" #Log Dateien backup_log_info=/var/log/mysql/mysql-backup.log backup_log_error=/var/log/mysql/mysql-backup.err backup_log_date_format="%d.%m.%Y %R"; #Vergangene Zeit berechnen backup_start_time=`date +%s` #Backup Wurzel Ordner backup_root_dir=/var/mysql-backup #Backup Tages Ordner backup_day_dir=`date +%Y-%m-%d` #Backups, die älter als X Tage sind, löschen backup_keep_days=10 #Verschiedene Ordner, bei mehreren Backups an ein und dem selben Tag i=1; backup_version_dir=`printf "%03d" $i` while [ -d $backup_root_dir/$backup_day_dir/$backup_version_dir ] do i=`expr $i + 1` backup_version_dir=`printf "%03d" $i` done #In diesem Ordner wird das Backup gespeichert backup_dir=$backup_root_dir/$backup_day_dir/$backup_version_dir #Loggen echo "[`date +"$backup_log_date_format"`] Creating backup" | tee -a $backup_log_info echo "[`date +"$backup_log_date_format"`] Date: $backup_day_dir, iteration $backup_version_dir" | tee -a $backup_log_info echo "[`date +"$backup_log_date_format"`] Backup to: $backup_dir" | tee -a $backup_log_info #Backup Ordner erstellen mkdir -p $backup_dir #Backup Ordner überprüfen if [ ! -d $backup_dir ] then echo "[`date +"$backup_log_date_format"`] Invalid directory $backup_dir, aborting" | tee -a $backup_log_error exit 1 fi #Alte Ordner löschen find $backup_root_dir -maxdepth 1 -mtime +$backup_keep_days -type d | xargs rm -rf #Namen der Datenbank auslesen for database in `mysql -s -u$mysql_user -p$mysql_pass -e "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mysql','information_schema')"`; do #Log echo "[`date +"$backup_log_date_format"`] Backing up $database" | tee -a $backup_log_info #Sichern mysqldump --opt --password=$mysql_pass --user=$mysql_user --host=$mysql_host $database | gzip --rsyncable > $backup_dir/$database.sql.gz done #Vergangene Zeit berechnen backup_end_time=`date +%s` backup_elapsed_time=`expr $backup_end_time - $backup_start_time` echo -e "[`date +"$backup_log_date_format"`] Elapsed time "`date -d "1970-01-01 $backup_elapsed_time +sec" +"%H:%M:%S"`"\n\n" | tee -a $backup_log_info |
Die Ordner werden von diesem Script automatisch angelegt, und stellen sich wie folgt dar:
/var/mysql-backup # ls -al total 56K drwxr-xr-x 3 root root 4.0K 2009-03-30 03:33 2009-03-30 drwxr-xr-x 3 root root 4.0K 2009-03-31 03:33 2009-03-31 drwxr-xr-x 3 root root 4.0K 2009-04-01 03:33 2009-04-01 drwxr-xr-x 3 root root 4.0K 2009-04-02 03:33 2009-04-02 drwxr-xr-x 3 root root 4.0K 2009-04-03 03:33 2009-04-03 drwxr-xr-x 3 root root 4.0K 2009-04-04 03:33 2009-04-04 drwxr-xr-x 3 root root 4.0K 2009-04-05 03:33 2009-04-05 drwxr-xr-x 3 root root 4.0K 2009-04-06 03:33 2009-04-06 drwxr-xr-x 3 root root 4.0K 2009-04-07 03:33 2009-04-07 drwxr-xr-x 4 root root 4.0K 2009-04-08 03:33 2009-04-08 |
Tagtäglich wird ein neuer Ordner hinzugefügt, und die Ordner, die älter als backup_keep_days Tage sind, gelöscht. Bei mehreren Backups an ein und dem gleichen Tag, werden verschiedene Unterverzeichnisse angelegt. Am 8. April wurden zum Beispiel zwei Backups gefahren:
/var/mysql-backup/2009-04-08 # ls -al total 140K drwxr-xr-x 2 root root 136K 2009-04-08 11:07 001 drwxr-xr-x 2 root root 136K 2009-04-08 11:53 002 |
Die Logs sehen wie folgt aus:
[31.03.2009 03:33] Creating backup [31.03.2009 03:33] Date: 2009-03-31, iteration 001 [31.03.2009 03:33] Backup to: /var/mysql-backup/2009-03-31/001 [30.03.2009 03:33] Backing up lunar [30.03.2009 03:33] Elapsed time 00:00:12 |
Der Cronjob sieht wie folgt aus:
#Datenbank Backup 33 3 * * * sh /root/mysql-backup/mysql-backup.sh |
Viel Spass damit
Funktioniert fast perfekt. Nur die eine Zeile hab ich aendern muessen:
for mydatabase in `mysql -s -u$mysql_user -p$mysql_pass -e “SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN (’mysql’,'information_schema’)”`;
Ohne
-u$mysql_user -p$mysql_pass
ging’s nicht bei mir.
Danke fur den Skript!
Hallo Mike,
danke für den Hinweis.
Ich habe die entsprechenden Änderungen soeben hinzugefügt
Schöne Grüsse
cool! Bin froh dass ich helfen konnte. Der Skript laeuft bei mir als wochentlicher CRON-job.
Great script!!
but the HOST parameter is missing in line:
for database in `mysql -s -u$mysql_user -p$mysql_pass -e “SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN (’mysql’,'information_schema’)”`;
should be:
for database in `mysql -s -u$mysql_user -p$mysql_pass -h$mysql_host -e “SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN (’mysql’,'information_schema’)”`;
regards,
Peter
hi,
echt tolles script, danke!
ich habs noch um “–socket” erweitert …
nochmals danke!