MySQL Datenbank Backup
Unten stehendes Script kann auf Linux, Solaris und anderen Unix-Varianten als täglichen Cronjob gestartet werden. Es erzeugt MySQL Datenbank Dumps jeder einzelnen Datenbank und konsolidiert durch einen einfachen Recycling Algorithmus ältere Dumps, so dass die lokale Festplatte oder das NFS-Share nicht vollläuft.
- Tägliche Sicherungsdatei mit dem Wochentag im Namen (z. B.
database.daily_Wednesday.sql
). So wird es nach sieben Tagen automatisch überschrieben. - Am letzten Tag des Monates wird stattdessen eine Sicherungsdatei mit der Monatsnummer im Namen erstellt (z. B.
database.monthly_09.sql
). Nach zwölf Monaten wird diese dann automatisch überschrieben. - Am 31. Dezember wird eine Sicherungsdatei mit der Jahreszahl erstellt (z. B.
database.yearly_2013.sql
. Diese wird dann behalten
Programmaufruf wie folgt:
/usr/local/bin/mysqlbackup.sh dbhost1.example.com:3306 dbhost2.example.com:3306
In der MySQL Datenbank muss ein User mit folgenden Privilegien erstellt werden:
grant show databases,show view,file,select,lock tables \ on *.* to 'backup'@'backuphost.example.com' identified by 'changeme';
In der Konfigurationsdatei .my.cnf
im Benutzerverzeichnis muss der Datenbankbenutzer und das Passwort eingetragen werden, so dass es nicht als Prozessargument in der Prozesstabelle erscheint oder im Script eingetragen werden muss.
[client] user=backup password=changeme [mysqldump] max-allowed-packet=2147483648 quote-names=true verbose=true
Hier das Bash-Script:
#!/bin/bash PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin" BACKUPDIR="/var/backup/mysql" CONFIG="/home/user/.my.cnf" EXCLUDEDB='^(Database|information_schema|performance_schema)$' MAILFROM="backup@example.com" MAILTO="user@example.com" # Simple housekeeping # Daily backups with week day names # Monthly backups on the last day of month # Yearly backups on last day of december year=$(date "+%Y") month=$(date "+%m") monthname=$(date "+%B") day=$(date "+%d") dayname=$(date "+%A") d=28 if (( $year % 4 == 0 )); then d=29; fi if (( $year % 100 == 0 )); then d=28; fi if (( $year % 400 == 0 )); then d=29; fi case "$month:$day" in 01:31) timestamp="monthly_${month}" ;; 02:$d) timestamp="monthly_${month}" ;; 03:31) timestamp="monthly_${month}" ;; 04:30) timestamp="monthly_${month}" ;; 05:31) timestamp="monthly_${month}" ;; 06:30) timestamp="monthly_${month}" ;; 07:31) timestamp="monthly_${month}" ;; 08:31) timestamp="monthly_${month}" ;; 09:30) timestamp="monthly_${month}" ;; 10:31) timestamp="monthly_${month}" ;; 11:30) timestamp="monthly_${month}" ;; 12:31) timestamp="yearly_${year}" ;; *) timestamp="daily_${dayname}" ;; esac for hostport in $@; do echo "" echo "*******************************************************************************" echo "Backing up MySQL on $hostport to $BACKUPDIR" echo "*******************************************************************************" echo "" host=$(echo $hostport | awk -F: '{print $1}') port=$(echo $hostport | awk -F: '{print $2}') hostdir="$BACKUPDIR/$hostport" test -d $hostdir || mkdir -p $hostdir databases=$(echo "show databases;" \ | mysql --defaults-file="$CONFIG" -h "$host" -P "$port" | grep -Ev "$EXCLUDEDB") for db in $databases; do echo -n "Dumping database $db ... " dbdir="$hostdir/$db" dumpfile="$dbdir/${db}.${timestamp}.sql" logfile="$dbdir/${db}.${timestamp}.log" test -d $dbdir || mkdir -p $dbdir mysqldump --defaults-file="$CONFIG" --log-error="$logfile" \ -h "$host" -P "$port" "$db" >$dumpfile retval=$? chmod 0644 $logfile chmod 0400 $dumpfile case $retval in 0) echo "OK" ;; *) echo "FAILED" ( echo "From: $MAILFROM" echo "To: $MAILTO" echo "Subject: Error backing up MySQL database $db on $hostport" echo "" echo "The command" echo "mysqldump --defaults-file=$CONFIG --log-error=$logfile -h $host -P $port $db" echo "returned value: $retval" echo "" echo "Error log: $logfile" echo "$(cat $logfile)" echo "." ) | sendmail -t ;; esac done done