Mon CV

Encore un script de sauvegarde des bases de données Sql

13 mai 2013

Bon, rien de bien nouveau, car de nombreux blogs proposent déjà des exemples de scripts pour sauvegarder les bases SQL.

Mais voici ici ma version :

  • principe de sauvegarde base par base (plus facile de retrouver le dump de la base en question en cas de besoin)
  • système permettant de garder X sauvegardes hebdomadaires (réalisées le dimanche) et Y sauvegardes quotidiennes.

Les commentaires sont les bienvenus et le code plus bas est suffisamment commenté pour vous permettre de vous l’approprier.

#!/bin/bash

## Inspiré d'un script trouvé sur http://phpnews.fr 
## Et déjà modifié par http://www.mercereau.info et les commentaires de http://e-concept-applications.fr
## 2013 | Yvan GODARD | https://www.yvangodard.fr | godardyvan@gmail.com

## Variables
# Utilisateur SQL à activer si besoin
# USER='sqluser'
# PASS='passusersql'
# Le script
CURRENT_DIR=$(dirname $0)
SCRIPT_NAME=$(basename $0)
HOSTNAME=$(hostname)
# Répertoire de sauvergarde des dump SQL
LOCATION="/home/mysqldump"
# Nom du backup
DATANAME="databasebackup-$(date +%d.%m.%y@%Hh%M)"
# Répertoire temporaire
DATATMP="$LOCATION/temp"
# Mail pour l'envoi du rapport
MAIL_ADMIN="mail@mondomaine.fr"
# Bases SQL à exclure
EXCLUSIONS='(information_schema)'
# Version du script
SCR_VERS="1.3"
# Les logs
LOGSLOCATION="/var/log/mysql-backup"
LOG_OUT="$LOGSLOCATION/out.log"
LOG_CUMUL="$LOGSLOCATION/mysql-backup.log"
DATE_DU_JOUR=$(date)
# Initialisation signal erreur 
ERROR=0

if [ `whoami` != 'root' ]
	then
	echo "Ce script doit être utilisé par le compte root. Utilisez SUDO."
	exit 1
fi

umask 027

## Redirection des sorties vers nos logs : création des dossiers nécessaires
if [ ! -d $$LOGSLOCATION ]; then
    mkdir -p $LOGSLOCATION
    [ $? -ne 0 ] && ERROR=1 && echo "*** Problème pour créer le dossier $LOGSLOCATION ***" && echo "Il sera impossible de journaliser le processus."
fi
if [ ! -d $LOCATION ]; then
    mkdir -p $LOCATION 
    [ $? -ne 0 ] && echo "*** Problème pour créer le dossier $LOCATION ***" && echo "Il est impossible de poursuivre la sauvegarde." && exit 1
fi

# Suppression des anciens logs temporaires
[ -f $LOG_OUT ] && rm $LOG_OUT

# Ouverture de notre fichier de log 
echo "" >> $LOG_OUT
echo "****************************** $DATE_DU_JOUR ******************************" >> $LOG_OUT
echo "" >> $LOG_OUT
echo "Machine : " $HOSTNAME >> $LOG_OUT
echo "" >> $LOG_OUT

cd $LOCATION
[ $? -ne 0 ] && echo "*** Problème pour accéder au dossier $LOCATION ***" && echo "Il est impossible de poursuivre la sauvegarde." && exit 1

## En fonction du jour, changement du nombre de backup à garder et du répertoire de destination
if [ "$( date +%w )" == "0" ]; then
        [ ! -d dimanche ] && mkdir -p dimanche
        DATADIR=${LOCATION}/dimanche
         # Période en jours de conservation des DUMP hebdomadaires
        KEEP_NUMBER=56
        echo "Backup hebdomadaire, $KEEP_NUMBER jours d'ancienneté seront gardés." >> $LOG_OUT
else
        [ ! -d quotidien ] && mkdir -p quotidien
        DATADIR=${LOCATION}/quotidien
        # Période en jours de conservation des DUMP quotidiens
        KEEP_NUMBER=14
        echo "Backup quotidien, $KEEP_NUMBER jours d'ancienneté seront gardés." >> $LOG_OUT
fi

## Création d'un répertoire temporaire pour la sauvegarde avant de zipper l'ensemble des dumps
mkdir -p ${DATATMP}/${DATANAME}
[ $? -ne 0 ] && ERROR=1 && echo "*** Problème pour créer le dossier ${DATATMP}/${DATANAME} ***" >> $LOG_OUT

# On place dans un tableau le nom de toutes les bases de données du serveur
# Version avec mot de passe
# databases="$(mysql --user=$USER --password=$PASS -Bse 'show databases' | grep -v -E $EXCLUSIONS)"
# Version sans mot de passe
databases="$(mysql -Bse 'show databases' | grep -v -E $EXCLUSIONS)"
[ $? -ne 0 ] && ERROR=1 && echo "*** Problème pour obtenir la liste des bases à dumper ***" >> $LOG_OUT
echo "Bases de données à traiter :" >> $LOG_OUT

# Sauvegarde de toutes les bases dans le fichier du jour
# Pour chacune des bases de données trouvées ...
for database in ${databases[@]}
do
    echo "- ${database}.sql"  >> $LOG_OUT
    # Version avec mot de passe
    # mysqldump  --user=$USER --password=$PASS --events --quick --add-locks --lock-tables --extended-insert $database  > ${DATATMP}/${DATANAME}/${database}.sql
    # Version sans mot de passe
    mysqldump --events --quick --add-locks --lock-tables --extended-insert $database  > ${DATATMP}/${DATANAME}/${database}.sql
    [ $? -ne 0 ] && ERROR=1 && echo "*** Problème sur le dump de la base $database ***"  >> $LOG_OUT
done

## On commpresse (TAR) tous et on créé un lien symbolique pour le dernier
cd ${DATATMP}
echo "Création de l'archive ${DATADIR}/${DATANAME}.sql.gz" >> $LOG_OUT
tar -czf ${DATADIR}/${DATANAME}.sql.gz ${DATANAME}
[ $? -ne 0 ] && ERROR=1 && echo "*** Problème lors de la création de l'archive ${DATADIR}/${DATANAME}.sql.gz ***" >> $LOG_OUT
cd ${DATADIR}
chmod 600 ${DATANAME}.sql.gz
[ -f last.sql.gz ] &&  rm last.sql.gz
ln -s ${DATADIR}/${DATANAME}.sql.gz ${DATADIR}/last.sql.gz

## On supprime le répertoire temporaire
 [ -d ${DATATMP}/${DATANAME} ] && rm -rf ${DATATMP}/${DATANAME}

## On supprime les anciens backups
echo "Suppression des vieux DUMP éventuels" >> $LOG_OUT
find $DATADIR -name "*.sql.gz" -mtime +$KEEP_NUMBER -print -exec rm {} \; >> $LOG_OUT
[ $? -ne 0 ] && ERROR=1

## Envoi d'un email de notification
if [ $ERROR -ne 0 ]
    then
        echo "Problème lors de l'éxécution de (${0}). Merci de corriger le processus." >> $LOG_OUT
        mail -s "[FAILED] Rapport Dump MySql (${0})" $MAIL_ADMIN <"${LOG_OUT}"
    else
        echo "Script de dump des bases MySql (${0}) exécuté avec succès."  >> $LOG_OUT
        mail -s "[OK] Rapport Dump MySql (${0})" $MAIL_ADMIN <"${LOG_OUT}"
fi

cat $LOG_OUT >> $LOG_CUMUL
[ -f $LOG_OUT ] && rm  $LOG_OUT

[ $ERROR -ne 0 ] && exit 1

exit 0

Remarquez dans ce script la possibilité d’utiliser ou nom un couple login-pass. Si vous souhaitez l’exécuter ainsi, pensez à

  • décommenter et compléter les lignes 9 et 10 avec les identifiants en question,
  • décommenter la ligne 87 et commenter la ligne 89,
  • décommenter la ligne 99 et commenter la ligne 101.

Vous pouvez limiter les accès en vous créant pour vos backups un utilisateur ayant un accès en lecture seule sur toutes vos bases de données (remplacez usersql et passsql par le couple de login de votre choix) :

$ mysql -u root -p -e "CREATE USER 'usersql'@'localhost' IDENTIFIED BY 'passsql';"
$ mysql -u root -p -e "GRANT SELECT , SHOW DATABASES , LOCK TABLES , SHOW VIEW ON * . * TO 'usersql'@'localhost' IDENTIFIED BY 'passsql' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;"

Si vous le souhaitez, vous pouvez directement télécharger ce script :

# On télécharge le script 
wget -O /usr/local/sbin/mysql-backup.sh --no-check-certificate https://raw.github.com/yvangodard/Scripts-Utiles/master/mysqlbackup/mysql-backup.sh
# On corrige les droits
chmod 750 /usr/local/sbin/mysql-backup.sh

Les commentaires sont là si vous voulez partager d’autres approches, etc.

 

Posted in Apple et Macintosh, Unix et LinuxTags: