Benutzer-Werkzeuge

Webseiten-Werkzeuge


tachtler:mysql_mariadb_backup_-_skript

MySQL/MariaDB Backup - Skript

:!: HINWEIS - Das nachfolgende Backup-Skript setzt eine lauffähige Installation von MySQL oder MariaDB voraus, wie unter nachfolgendem internen Link beschrieben !!!

MySQL oder MariaDB sind beide Open-Source-Datenbank-Server.


MySQL wird von Oracle entwickelt.

MariaDB wird von The MariaDB Foundation entwickelt.

Beschreibung Externer Link
Homepage MySQL
Dokumentation MySQL Dokumentation
Beschreibung Externer Link
Homepage MariaDB
Dokumentation MariaDB Dokumentation

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

Backup

Nachfolgendes Skript ermöglicht die Erstellung einer *.tar.gz-Datei

  • pro Tag eine eigene *.tar.gz-Datei
  • auf Dateiebene
  • mit konfigurierbaren Parametern
  • und automatischer Löschung von älteren Sicherungsdateien
  • und Erstellung einer fortlaufenden Log-Datei unter /var/log/

Nachfolgende Parameter sind in der aktuellen Version konfigurierbar: (Nur relevanter Ausschnitt)

...
##############################################################################
# >>> Please edit following lines for personal settings and custom usages. ! #
##############################################################################
 
# CUSTOM - Script-Name.
SCRIPT_NAME='mysqldump_backup'
 
# CUSTOM - Backup-Files.
DIR_BACKUP='srv/backup'
FILE_BACKUP=mysqldump_backup_`date '+%Y%m%d_%H%M%S'`.sql
FILE_DELETE='*.tar.gz'
BACKUPFILES_DELETE=7
 
# CUSTOM - mysqldump Parameter.
DUMP_HOST='127.0.0.1'
DUMP_USER='root'
DUMP_PASS='geheim'
# CUSTOM - Depends on the database engine. Example: ('Y'(MyISAM), 'N'(InnoDB))
DUMP_LOCK_ALL_TABLE='Y'
 
# CUSTOM - Mail-Recipient.
MAIL_RECIPIENT='you@example.com'
 
# CUSTOM - Status-Mail [Y|N].
MAIL_STATUS='N'
 
##############################################################################
# >>> Normaly there is no need to change anything below this comment line. ! #
##############################################################################
...

Parametername Beschreibung
SCRIPT_NAME Name des Skriptes
DIR_BACKUP Verzeichnis in dem die Backup-Dateien erstellt werden sollen
FILE_BACKUP Allgemeiner Teil der Bezeichnung für die Backup-Dateien
FILE_DELETE Endung zur Löschung von älteren Archivdateien
BACKUPFILES_DELETE Anzahl der Backup-Dateien pro Benutzer die gespeichert bleiben sollen
DUMP_LOCK_ALL_TABLE Angabe ob beim Backup-Prozesses ein –lock-all-tables durchgeführt werden soll

Skript

#!/bin/bash
 
##############################################################################
# Script-Name : mysqldump_backup.sh                                          #
# Description : Script to backup the --all-databases of a MySQL/MariaDB.     #
#               On successful execution only a LOG file will be written.     #
#               On error while execution, a LOG file and a error message     #
#               will be send by e-mail.                                      #
#                                                                            #
# Last update : 26.05.2017                                                   #
# Version     : 1.00                                                         #
#                                                                            #
# Author      : Klaus Tachtler, <klaus@tachtler.net>                         #
# DokuWiki    : http://www.dokuwiki.tachtler.net                             #
# Homepage    : http://www.tachtler.net                                      #
#                                                                            #
#  +----------------------------------------------------------------------+  #
#  | This program is free software; you can redistribute it and/or modify |  #
#  | it under the terms of the GNU General Public License as published by |  #
#  | the Free Software Foundation; either version 2 of the License, or    |  #
#  | (at your option) any later version.                                  |  #
#  +----------------------------------------------------------------------+  #
#                                                                            #
# Copyright (c) 2017 by Klaus Tachtler.                                      #
#                                                                            #
##############################################################################
 
##############################################################################
#                                H I S T O R Y                               #
##############################################################################
# -------------------------------------------------------------------------- #
# Version     : x.xx                                                         #
# Description : <Description>                                                #
# -------------------------------------------------------------------------- #
# -------------------------------------------------------------------------- #
# Version     : x.xx                                                         #
# Description : <Description>                                                #
# -------------------------------------------------------------------------- #
##############################################################################
 
##############################################################################
# >>> Please edit following lines for personal settings and custom usages. ! #
##############################################################################
 
# CUSTOM - Script-Name.
SCRIPT_NAME='mysqldump_backup'
 
# CUSTOM - Backup-Files.
DIR_BACKUP='/srv/backup'
FILE_BACKUP=mysqldump_backup_`date '+%Y%m%d_%H%M%S'`.sql
FILE_DELETE='*.tar.gz'
BACKUPFILES_DELETE=7
 
# CUSTOM - mysqldump Parameter.
DUMP_HOST='127.0.0.1'
DUMP_USER='root'
DUMP_PASS='geheim'
# CUSTOM - Binary-Logging active. Example: ('Y'(my.cnf|log_bin=bin-log), 'N')
DUMP_BIN_LOG_ACTIVE='N'
# CUSTOM - Depends on the database engine. Example: ('Y'(MyISAM), 'N'(InnoDB))
DUMP_LOCK_ALL_TABLE='Y'
 
# CUSTOM - Mail-Recipient.
MAIL_RECIPIENT='you@example.com'
 
# CUSTOM - Status-Mail [Y|N].
MAIL_STATUS='N'
 
##############################################################################
# >>> Normaly there is no need to change anything below this comment line. ! #
##############################################################################
 
# Variables.
MYSQLDUMP_COMMAND=`command -v mysqldump`
TAR_COMMAND=`command -v tar`
TOUCH_COMMAND=`command -v touch`
RM_COMMAND=`command -v rm`
PROG_SENDMAIL=`command -v sendmail`
CAT_COMMAND=`command -v cat`
DATE_COMMAND=`command -v date`
MKDIR_COMMAND=`command -v mkdir`
FILE_LOCK='/tmp/'$SCRIPT_NAME'.lock'
FILE_LOG='/var/log/'$SCRIPT_NAME'.log'
FILE_LAST_LOG='/tmp/'$SCRIPT_NAME'.log'
FILE_MAIL='/tmp/'$SCRIPT_NAME'.mail'
FILE_MBOXLIST='/tmp/'$SCRIPT_NAME'.mboxlist'
VAR_HOSTNAME=`uname -n`
VAR_SENDER='root@'$VAR_HOSTNAME
VAR_EMAILDATE=`$DATE_COMMAND '+%a, %d %b %Y %H:%M:%S (%Z)'`
 
# Functions.
function log() {
        echo $1
        echo `$DATE_COMMAND '+%Y/%m/%d %H:%M:%S'` " INFO:" $1 >>${FILE_LAST_LOG}
}
 
function retval() {
if [ "$?" != "0" ]; then
        case "$?" in
        *)
                log "ERROR: Unknown error $?"
        ;;
        esac
fi
}
 
function movelog() {
        $CAT_COMMAND $FILE_LAST_LOG >> $FILE_LOG
        $RM_COMMAND -f $FILE_LAST_LOG   
        $RM_COMMAND -f $FILE_LOCK
}
 
function sendmail() {
        case "$1" in
        'STATUS')
                MAIL_SUBJECT='Status execution '$SCRIPT_NAME' script.'
        ;;
        *)
                MAIL_SUBJECT='ERROR while execution '$SCRIPT_NAME' script !!!'
        ;;
        esac
 
$CAT_COMMAND <<MAIL >$FILE_MAIL
Subject: $MAIL_SUBJECT
Date: $VAR_EMAILDATE
From: $VAR_SENDER
To: $MAIL_RECIPIENT
 
MAIL
 
$CAT_COMMAND $FILE_LAST_LOG >> $FILE_MAIL
 
$PROG_SENDMAIL -f $VAR_SENDER -t $MAIL_RECIPIENT < $FILE_MAIL
 
$RM_COMMAND -f $FILE_MAIL
 
}
 
# Main.
log ""
log "+-----------------------------------------------------------------+"
log "| Start backup of --all-databases of database server............. |"
log "+-----------------------------------------------------------------+"
log ""
log "Run script with following parameter:"
log ""
log "SCRIPT_NAME...: $SCRIPT_NAME"
log ""
log "DIR_BACKUP....: $DIR_BACKUP"
log ""
log "MAIL_RECIPIENT: $MAIL_RECIPIENT"
log "MAIL_STATUS...: $MAIL_STATUS"
log ""
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$MYSQLDUMP_COMMAND" ]; then
        log "Check if command '$MYSQLDUMP_COMMAND' was found................[FAILED]"
        sendmail ERROR
        movelog
        exit 11
else
        log "Check if command '$MYSQLDUMP_COMMAND' was found................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$TAR_COMMAND" ]; then
        log "Check if command '$TAR_COMMAND' was found......................[FAILED]"
        sendmail ERROR
        movelog
        exit 12
else
        log "Check if command '$TAR_COMMAND' was found......................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$TOUCH_COMMAND" ]; then
        log "Check if command '$TOUCH_COMMAND' was found....................[FAILED]"
        sendmail ERROR
        movelog
        exit 13
else
        log "Check if command '$TOUCH_COMMAND' was found....................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$RM_COMMAND" ]; then
        log "Check if command '$RM_COMMAND' was found.......................[FAILED]"
        sendmail ERROR
        movelog
        exit 14
else
        log "Check if command '$RM_COMMAND' was found.......................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$CAT_COMMAND" ]; then
        log "Check if command '$CAT_COMMAND' was found......................[FAILED]"
        sendmail ERROR
        movelog
        exit 15
else
        log "Check if command '$CAT_COMMAND' was found......................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$DATE_COMMAND" ]; then
        log "Check if command '$DATE_COMMAND' was found.....................[FAILED]"
        sendmail ERROR
        movelog
        exit 16
else
        log "Check if command '$DATE_COMMAND' was found.....................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$MKDIR_COMMAND" ]; then
        log "Check if command '$MKDIR_COMMAND' was found....................[FAILED]"
        sendmail ERROR
        movelog
        exit 17
else
        log "Check if command '$MKDIR_COMMAND' was found....................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$PROG_SENDMAIL" ]; then
        log "Check if command '$PROG_SENDMAIL' was found................[FAILED]"
        sendmail ERROR
        movelog
        exit 18
else
        log "Check if command '$PROG_SENDMAIL' was found................[  OK  ]"
fi
 
# Check if LOCK file NOT exist.
if [ ! -e "$FILE_LOCK" ]; then
        log "Check if script is NOT already runnig .....................[  OK  ]"
 
        $TOUCH_COMMAND $FILE_LOCK
else
        log "Check if script is NOT already runnig .....................[FAILED]"
        log ""
        log "ERROR: The script was already running, or LOCK file already exists!"
        log ""
        sendmail ERROR
        movelog
        exit 20
fi
 
# Check if DIR_BACKUP Directory NOT exists.
if [ ! -d "$DIR_BACKUP" ]; then
        log "Check if DIR_BACKUP exists.................................[FAILED]"
        $MKDIR_COMMAND -p $DIR_BACKUP
        log "DIR_BACKUP was now created.................................[  OK  ]"
else
        log "Check if DIR_BACKUP exists.................................[  OK  ]"
fi
 
# Start backup.
log ""
log "+-----------------------------------------------------------------+"
log "| Run backup $SCRIPT_NAME ................................... |"
log "+-----------------------------------------------------------------+"
log ""
 
# Start backup process via mysqldump.
 
cd $DIR_BACKUP
 
if [ $DUMP_LOCK_ALL_TABLE = 'Y' ]; then
        DUMP_LOCK_ALL_TABLE='--lock-all-tables'
else
        DUMP_LOCK_ALL_TABLE='--single-transaction'
fi
 
if [ $DUMP_BIN_LOG_ACTIVE = 'Y' ]; then
        log "Dump data with bin-log data ..."
        $MYSQLDUMP_COMMAND --host=$DUMP_HOST --user=$DUMP_USER --password=$DUMP_PASS --all-databases --flush-privileges $DUMP_LOCK_ALL_TABLES --master-data=1 --flush-logs --triggers --routines --events --hex-blob > $FILE_BACKUP
else
        log "Dump data ..."
        $MYSQLDUMP_COMMAND --host=$DUMP_HOST --user=$DUMP_USER --password=$DUMP_PASS --all-databases --flush-privileges $DUMP_LOCK_ALL_TABLES --triggers --routines --events --hex-blob > $FILE_BACKUP
fi
 
log ""
log "Packaging to archive ..."
$TAR_COMMAND -cvzf $FILE_BACKUP.tar.gz $FILE_BACKUP --atime-preserve --preserve-permissions
 
log ""
log "Delete archive files ..."
(ls $FILE_DELETE -t|head -n $BACKUPFILES_DELETE;ls $FILE_DELETE )|sort|uniq -u|xargs rm
if [ "$?" != "0" ]; then
        log "Delete old archive files $DIR_BACKUP .....[FAILED]"
else
        log "Delete old archive files $DIR_BACKUP .....[  OK  ]"
fi
 
log ""
log "Delete dumpfile ..."
$RM_COMMAND $FILE_BACKUP
 
# Delete LOCK file.
if [ "$?" != 0 ]; then
        retval $?
        log ""
        $RM_COMMAND -f $FILE_LOCK
        sendmail ERROR
        movelog
        exit 99
else
        log ""
        log "+-----------------------------------------------------------------+"
        log "| End backup $SCRIPT_NAME ................................... |"
        log "+-----------------------------------------------------------------+"
        log ""
fi
 
# Finish syncing.
log "+-----------------------------------------------------------------+"
log "| Finish......................................................... |"
log "+-----------------------------------------------------------------+"
log ""
 
# Status e-mail.
if [ $MAIL_STATUS = 'Y' ]; then
        sendmail STATUS
fi
# Move temporary log to permanent log
movelog
 
exit 0

Skript - Log

Nachfolgende Log-Datei entsteht im Verzeichnis

  • /var/log/ - hier z.B. /var/log/mysqldump_backup.log

2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:24  INFO: | Start backup of --all-databases of database server............. |
2017/05/24 18:42:24  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: Run script with following parameter:
2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: SCRIPT_NAME...: mysqldump_backup
2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: DIR_BACKUP....: /srv/backup
2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: MAIL_RECIPIENT: root@tachtler.net
2017/05/24 18:42:24  INFO: MAIL_STATUS...: N
2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: Check if command '/bin/mysqldump' was found................[ OK ]
2017/05/24 18:42:24  INFO: Check if command '/bin/tar' was found......................[ OK ]
2017/05/24 18:42:24  INFO: Check if command '/bin/touch' was found....................[ OK ]
2017/05/24 18:42:24  INFO: Check if command '/bin/rm' was found.......................[ OK ]
2017/05/24 18:42:24  INFO: Check if command '/bin/cat' was found......................[ OK ]
2017/05/24 18:42:24  INFO: Check if command '/bin/date' was found.....................[ OK ]
2017/05/24 18:42:24  INFO: Check if command '/bin/mkdir' was found....................[ OK ]
2017/05/24 18:42:24  INFO: Check if command '/sbin/sendmail' was found................[ OK ]
2017/05/24 18:42:24  INFO: Check if script is NOT already runnig .....................[ OK ]
2017/05/24 18:42:24  INFO: Check if DIR_BACKUP exists.................................[ OK ]
2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:24  INFO: | Run backup mysqldump_backup ................................... |
2017/05/24 18:42:24  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:24  INFO:
2017/05/24 18:42:24  INFO: Dump data ...
2017/05/24 18:42:27  INFO:
2017/05/24 18:42:27  INFO: Packaging to archive ...
2017/05/24 18:42:29  INFO:
2017/05/24 18:42:29  INFO: Delete archive files ...
2017/05/24 18:42:29  INFO: Delete old archive files /srv/backup ....................[FAILED]
2017/05/24 18:42:29  INFO:
2017/05/24 18:42:29  INFO: Delete dumpfile ...
2017/05/24 18:42:29  INFO:
2017/05/24 18:42:29  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:29  INFO: | End backup mysqldump_backup ................................... |
2017/05/24 18:42:29  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:29  INFO:
2017/05/24 18:42:29  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:29  INFO: | Finish......................................................... |
2017/05/24 18:42:29  INFO: +-----------------------------------------------------------------+
2017/05/24 18:42:29  INFO:

Anmerkung zur Ausführung:

:!: HINWEIS - Falls nachfolgende Fehlermeldung auftreten sollte:

...  INFO: Delete old archive files /srv/backup ......................[FAILED]
bedeutet dies nur, dass noch nicht genug alte Archivdateien vorhanden sind, damit diese gelöscht werden können!

Skript - Logrotate

Damit die LOG-Datei des Skriptes nicht ins unendliche wächst, sollte diese ebenfalls, wie auch die Log-Dateien von hier z.B. MariaDB selbst, rotiert werden.

Um die LOG-Dateien des Skriptes ebenfalls wie die LOG-Dateien von hier z.B. MariaDB selbst zu rotieren ist nachfolgende Ergänzung in der Kofigurationsdatei

  • /etc/logrotate.d/mariadb

erforderlich:

VORHER: (Komplette Konfigurationsdatei)

# This logname can be set in /etc/my.cnf
# by setting the variable "log-error"
# in the [mysqld_safe] section as follows:
#
# [mysqld_safe]
# log-error=/var/log/mariadb/mariadb.log
#
# If the root user has a password you have to create a
# /root/.my.cnf configuration file with the following
# content:
#
# [mysqladmin]
# password = <secret> 
# user= root
#
# where "<secret>" is the password. 
#
# ATTENTION: This /root/.my.cnf should be readable ONLY
# for root !

# Then, un-comment the following lines to enable rotation of mysql's log file:

# Tachtler - uncommented following lines -
/var/log/mariadb/mariadb.log {
        create 640 mysql mysql
        notifempty
        daily
        rotate 3
        missingok
        compress
    postrotate
        # just if mysqld is really running
        if test -x /usr/bin/mysqladmin && \
           /usr/bin/mysqladmin ping &>/dev/null
        then
           /usr/bin/mysqladmin flush-logs
        fi
    endscript
}

NACHHER: (Komplette Konfigurationsdatei)

# This logname can be set in /etc/my.cnf
# by setting the variable "log-error"
# in the [mysqld_safe] section as follows:
#
# [mysqld_safe]
# log-error=/var/log/mariadb/mariadb.log
#
# If the root user has a password you have to create a
# /root/.my.cnf configuration file with the following
# content:
#
# [mysqladmin]
# password = <secret> 
# user= root
#
# where "<secret>" is the password. 
#
# ATTENTION: This /root/.my.cnf should be readable ONLY
# for root !

# Then, un-comment the following lines to enable rotation of mysql's log file:

# Tachtler - uncommented following lines -
/var/log/mariadb/mariadb.log /var/log/mysqldump_backup.log {
        create 640 mysql mysql
        notifempty
        daily
        rotate 3
        missingok
        compress
    postrotate
        # just if mysqld is really running
        if test -x /usr/bin/mysqladmin && \
           /usr/bin/mysqladmin ping &>/dev/null
        then
           /usr/bin/mysqladmin flush-logs
        fi
    endscript
}

Nachfolgend die geänderte Zeile (Nur relevanter Ausschnitt):

...
/var/log/mariadb/mariadb.log /var/log/mysqldump_backup.log {
...

Skript - cron-Job

Nachfolgend kann auch ein cron-Job zur z.B. nächtlichen Ausführung eingerichtet werden. Dazu können nachfolgende zwei Konfigurationszeilen an die bestehende Konfigurationsdatei

  • /etc/crontab

angehängt werden:

# Backup mariadb mysqldump
5 03 * * * root /usr/local/bin/mysqldump_backup.sh > /dev/null 2>&1
* Ausführung nächtlich um 03:05 Uhr

Skript - Dateien

Nachfolgend sollten nachfolgende Dateien im Backup-Verzeichnis, welches im Skript definiert ist, erstellt worden sein, nachdem das Skript zur Ausführung gekommen ist. Hier z.B. /srv/backup/, was mit nachfolgendem Befehl überprüft werden kann:

# ls -la /srv/backup/
total 5520
drwxr-xr-x  2 mysql mysql      56 May 24 18:42 .
drwxr-xr-x. 4 mysql mysql      52 May 24 18:27 ..
-rw-r--r--  1 root  root  5648600 May 24 18:42 mysqldump_backup_20170524_114224.sql.tar.gz

Recovery

Die Erstellung eines Backups (Sicherung) ist eine Sache, jedoch wie können im Fall eines Datenverlusts, die Daten wiederhergestellt werden.

Entpacken

Nachfolgendes Beispiel zeigt, wie zuerst die im Backup enthaltenen Daten in eine Verzeichnis unterhalb von

  • /tmp

wiederhergestellt werden können.

Dazu kann mit nachfolgendem Befehl ein Verzeichnis mit dem Namen recovery unterhalb des Verzeichnisses /tmp angelegt werden:

# mkdir /tmp/recovery

Anschließend kann dann mit nachfolgendem Befehl die komplette Datenbank/Schema Sicherung wiederhergestellt werden:

Als Beispiel sind hier nachfolgende Gegebenheiten angenommen:

  1. Das Backup befindet sich unter /srv/backup

# tar -xvzf mysqldump_backup_20170524_184224.sql.tar.gz -C /tmp/recovery --atime-preserve --preserve-permissions

Nach erfolgreicher Ausführung des oben gezeigten Befehls, kann mit nachfolgendem Befehl überprüft werden, ob alle Daten aus der Backup-Datei erfolgreich extrahiert werden konnten:

# ls -la /tmp/recovery/
total 45936
-rw-r--r-- 1 root root 47034466 May 24 11:42 mysqldump_backup_20170524_184224.sql

Widerherstellen

FIXME

Cookies helfen bei der Bereitstellung von Inhalten. Durch die Nutzung dieser Seiten erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Rechner gespeichert werden. Weitere Information
tachtler/mysql_mariadb_backup_-_skript.txt · Zuletzt geändert: 2017/05/26 10:19 von klaus