Sauvegarder automatiquement ses bases MySQL

Les sauvegardes de base de données ne sont pas toujours simple à effectuer, voici un petit script qui vous mâchera le travail.


Les sauvegardes de base de données ne sont pas toujours simple à effectuer, voici un petit script qui vous mâchera le travail.

S'il est possible de sauvegarder les bases de données de MySQL en se contentant de copier les fichiers contenant les bases, cette méthode est crado et peut se solder par un échec cuisant.
Il est largement recommandé d'utiliser l'utilitaire mysqldump pour cette tâche, cependant, l'utiliser manuellement pour sauvegarder les bases de données une à une n'est pas agréable, un oubli ou une mauvaise manipulation est vite arrivée.

Voici donc un petit script à utiliser avec cron pour sauvegarder toutes vos bases de données MySQL automatiquement.

A modifier selon votre convenance, attention, les droits de root sont nécessaires.

La présence du mot de passe root de MySQL dans le fichier de configuration demande de mettre les droits les plus restrictifs possible sur celui-ci.

Sources

Script

    Emplacement : /usr/local/sbin/mysql-dump
#! /usr/bin/env bash

################################################################################
#                                                                              #
# LICENCE                                                                      #
#                                                                              #
# 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 3 of the License, or (at your option)    #
# any later version.                                                           #
#                                                                              #
# This program is distributed in the hope that it will be useful, but WITHOUT  #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for     #
# more details.                                                                #
#                                                                              #
# You should have received a copy of the GNU General Public License along with #
# this program.  If not, see .                   #
#                                                                              #
################################################################################

################################################################################
#                                                                              #
# DESCRIPTION                                                                  #
#                                                                              #
# Ce script sauvegarde automatiquement les bases de données MySQL/MariaDB en   #
# utilisant la sauvegarde par base.                                            #
#                                                                              #
#                                                                              #
# VARIABLES                                                                    #
#                                                                              #
# - DATE : Date du jour, utilisé pour le dossier de sauvegarde des bases de    #
#   données à sauvegarder.                                                     #
# - MYSQLROOT : Nom de l'administrateur du système de gestion de bases de      #
#   données, root par défaut.                                                  #
# - MYSQLPASSWD : Mot de passe de l'administrateur du système de gestion de    #
#   base de données.                                                           #
# - BACKUP_DIR : Emplacement du répertoire de base pour les sauvegarde, un     #
#   sous-répertoire portant pour nom la variable date sera crée pour contenir  #
#   les sauvegarde du jour.                                                    #
# - LOG_FILE : Fichier utilisé pour la journalisation.                         #
# - LOG_FILE_DATE : Date de journalisation.                                    #
# - RETENTION : Temps de rétention des sauvegardes.                            #
# - MYSQLDUMP_OPTS : Options utilisées par la commande mysqldump.              #
#                                                                              #
#                                                                              #
# FONCTIONS                                                                    #
#                                                                              #
# - logDate() : Ajoute la date aux messages de journalisation.                 #
# - createLog() : Créer un fichier de journalisation et lui donne les droits   #
#   corrects s'il n'existe pas.                                                #
# - createBackupDir() : Vérifie l'existance du répertoire utilisé par les      #
#   sauvegardes du jour, le crée et lui donne les authorisations correctes le  #
#   cas échéant. Voir les variables BACKUP_DIR et DATE.                        #
#   Quitte et retourne l'état de sortie 1 si le dossier n'existe pas et ne     #
#   peut être crée.                                                            #
# - backupPurge() : Utilise la commande tmpreaper pour suprimmer dans le       #
#   dossier de base des sauvegardes -tel que défini par la variable            #
#   BACKUP_DIR- celles dont l'âge est supérieur à celui défini dans la         #
#   variable RETENTION.                                                        #
#   Quitte et retourne l'état de sortie 2 si les sauvegardes les plus          #
#   anciennes ne peuvent être supprimées.                                      #
# - listDB() : Cette fonction liste les bases de données présentes avec la     #
#   commande mysql pour lister les bases de données présentent dans le système #
#   de base de données que l'on souhaite sauvegarder.                          #
#   Quitte et retourne l'état de sortie 3 si les bases de données ne peuvent   #
#   êtres listées                                                              #
#   Quitte et retourne l'état de sortie 4 si aucunes bases de données          #
#   n'existe.                                                                  #
# - backupDB() : Supprime les sauvegardes présente dans le dossier du jour     #
#   s'ils en existes puis utilise mysql afin de sauvegarder les bases de       #
#   données du système de gestion de base de données que l'on souhaite         #
#   sauvegarder.                                                               #
#   Il est possible de spécifier des options à la commande de sauvegarde via   #
#   la variables MYSQLDUMP_OPTS.                                               #
#   Quitte est retourne l'état de sortie 5 si une erreur se produit lors des   #
#   sauvegardes.                                                               #
# - backupCheck() : Cette fonction effectue un test afin de savoir si les      #
#   sauvegardes se sont bien déroulées. Elle vérifie via la commande find      #
#   couplé à la commande wc -l la présence de fichier dans le répertoire de    #
#   sauvegarde du jour, si le résultat de cette commande est est plus grand    #
#   que 0, elle utilise la commande du -ks si la taille totales des fichiers   #
#   sauvegardé est supérieur à quatre kibi-octects, 4 kio étant la taille d'un #
#   dossier vide ou contenant des fichiers de taille nulle.                    #
#   Quitte et retourne l'état de sortie 6 si aucune sauvegarde n'a put être    #
#   effectuée ou si la taille des sauvegardes est nulle.                       #
#                                                                              #
#                                                                              #
# AUTEUR(S)                                                                    #
#                                                                              #
# - Collyer Cédric                                   #
#                                                                              #
#                                                                              #
# DERNIER(S) CHANGEMENT(S) :                                                   #
#                                                                              #
# - 23/10/2010 : Création du script et écriture de la documentation.           #
# - 21/02/2011 : Ajout de la suppression des répertoires vides dans la         #
#   fonction BackupPurge().                                                    #
# - 24/10/2011 : Abandon du GZ, compression des dump en XZ.                    #
# - 25/10/2011 : Mise au format ISO.                                           #
#                                                                              #
################################################################################

# Variables
PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin";

source "/usr/local/etc/mysql-dump.conf";

# Routine d'horodatage des logs
logDate() {
        LOG_FILE_DATE="$(date +'%d/%m/%Y %H:%M')";
}


# Mise en place des journaux.
createLog () {
        if [ ! -f "$LOG_FILE" ]; then
                touch "$LOG_FILE";
                chown mysql "$LOG_FILE";
                chgrp adm "$LOG_FILE";
                chmod 640 "$LOG_FILE";
        fi
}

# Mise en place des répertoires.
createBackupDir () {
        if [ ! -d "$BACKUP_DIR/$DATE" ]; then
                mkdir -p "$BACKUP_DIR/$DATE";
                if [ $? != 0 ]; then
                        logDate;
                        echo "$LOG_FILE_DATE : Impossible de créer le dossier \
de sauvegarde." >> "$LOG_FILE";
                        exit 1;
                fi
                chown root "$BACKUP_DIR/$DATE";
                chgrp backup "$BACKUP_DIR/$DATE";
                chmod 770 "$BACKUP_DIR/$DATE";
        fi
}

# Purge des ancienne sauvegardes.
# Utilisation TMPReaper pour supprimer les sauvegardes vielles de plus de 8
# jours (cf $RETENTION pour changer)
backupPurge() {
        tmpreaper "$RETENTION" "$BACKUP_DIR";
        if [ $? != "0" ]; then
                logDate;
                echo "$LOG_FILE_DATE : Impossible de purger les anciennes \
sauvegardes." >> "$LOG_FILE";
                exit 2;
        fi
        for olddir in $(ls "$BACKUP_DIR"); do
                if [ "$(du -ks $BACKUP_DIR/$olddir | awk {'print $1'})" -eq 4 ]
                then
                        rmdir "$BACKUP_DIR/$olddir";
                fi
        done
}

# Listage des bases de données.
listDB() {
        BASE_LIST="$(mysql --user=$MYSQLROOT --password=$MYSQLPASSWD \\\\
--batch --skip-column-names --execute='SHOW DATABASES;')";
        if [ $? != "0" ]; then
                logDate;
                echo "$LOG_FILE_DATE : Erreur dans la commande de sauvegarde." \
>> "$LOG_FILE";
                exit 3;
        fi
        if [ "$BASE_LIST" = "" ]; then
                logDate;
                echo "$LOG_FILE_DATE : Aucune base présente." >> "$LOG_FILE";
                exit 4;
        fi
}

# Sauvegarde des BDD.
backupDB() {
        for db in $BASE_LIST; do
                if [ -f "$BACKUP_DIR/$DATE/$db.sql.xz" ]; then
                        rm -f "$BACKUP_DIR/$DATE/$db.sql.xz";
                fi
                mysqldump $MYSQLDUMP_OPTS --user="$MYSQLROOT" \
--password="$MYSQLPASSWD" "$db" 2>> "$LOG_FILE" | xz -c\
> "$BACKUP_DIR/$DATE/$db.sql.xz";
                if [ $? -ne "0" ]; then
                        logDate;
                        echo "$LOG_FILE_DATE : Attention erreur dans les \
sauvegardes."  >> "$LOG_FILE";
                        exit 5;
                fi
                chown root "$BACKUP_DIR/$DATE/$db.sql.xz";
                chgrp backup "$BACKUP_DIR/$DATE/$db.sql.xz";
                chmod 660 "$BACKUP_DIR/$DATE/$db.sql.xz";
        done
}

# Vérificarion des sauvegardes.
backupCheck() {
        if [ "$(find $BACKUP_DIR/$DATE -type f | wc -l)" -gt 0 -a \
"$(du -ks $BACKUP_DIR/$DATE | awk {'print $1'})" -gt 4 ]; then
                logDate;
                echo "$LOG_FILE_DATE : Sauvegarde des bases terminé avec \
succés." >> "$LOG_FILE";
        else
                logDate;
                echo "$LOG_FILE_DATE : Aucune base sauvegardées ou leur taille \
est de zéro." >> "$LOG_FILE";
                exit 6;
        fi
}

main() {
        createLog;
        createBackupDir;
        listDB;
        backupDB;
        backupCheck;
        backupPurge;
}

main;

exit 0;

Fichier de configuration

    Emplacement : /usr/local/etc/mysql-dump.conf
# Root directory for backups.
BACKUP_DIR="/var/archives/MySQL";

# Date format, used to name the backup directory.
DATE="$(date '+%Y%m%d')";

# MySQL user used for backup.
MYSQLROOT="root";
MYSQLPASSWD="fDGUTDJS";

# Retention time.
RETENTION="7d";

# MySQL options.
MYSQLDUMP_OPTS="--routines --skip-lock-tables --events";

# Log file.
LOG_FILE="/var/log/mysql-dump.log";
Laissez un commentaire

7 Commentaires

  • Bon, il faut que je me décide à l'installer sur le serveur d'AG un de ces jours, actuellement on est sans filet ouf

  • Hum..."sans filet" est un terme de programmation ultra-complexe ou cela veut simplement dire que si le serveur d'AG crash les données seront perdues ?

  • Absolument, c'est tout à fait ça, mas les causes de crash n'impliquent pas toutes une perte inévitable des données. Les principales raisons qui rayeraient cette communauté sont les suivantes :

    • Panne de disque dur
    • Hack par un malveillant sachant ce qu'il fait

    Les deux occurences ont chacune très peu de chances de se produire, mais on n'est jamais trop prudent, et c'est toujours après une perte de données qu'on se dit qu'il aurait fallu sauvegarder.

  • Hop, script installé et journalisé, attention pour l'option --events il faut avoir MySQL > 5.1.8, je l'ai appris à mes dépends ouf

  • Ertaï a écrit :

    Les principales raisons qui rayeraient cette communauté sont les suivantes :

    • Panne de disque dur

    Vu que le cas s'est présenté, je ne peux que te remercier d'avoir mis à ma disposition ce script qui a permis de restaurer le contenu des bases. J'ai quand même dû recréer les bases de données et les comptes utilisateurs à la main mais ça a bien marché smile

    Sinon depuis ta mise à jour au format ISO (qu'est-ce que ça change exactement ?), le script ne peut pas fonctionner, l'erreur est à la ligne 191, il manque un espace avant l'anti-slash en bout de ligne, sinon la commande interprétée est mysql --user=root--password=XXXXX ce qui provoque une erreur d'authentification. smile

  • Ertaï a écrit :

    Sinon depuis ta mise à jour au format ISO (qu'est-ce que ça change exactement ?), le script ne peut pas fonctionner, l'erreur est à la ligne 191, il manque un espace avant l'anti-slash en bout de ligne, sinon la commande interprétée est mysql --user=root--password=XXXXX ce qui provoque une erreur d'authentification.

    Dit-il alors qu'il m'avais embêté lors de la mise à disposition du script parce que ce n'était pas ISO. sourire

    Corrigé.

  • Il n'y a pas de changelog pour cette édition ? razz

Laissez un commentaire

Vous devez être connecté pour commenter sur le Refuge. Identifiez-vous maintenant ou inscrivez-vous !