mysqldump-bash-mail
Ceci est une ancienne révision du document !
Table des matières
Sauvegarde de Base de Donnée MySQL en bash avec mysqldump
Le but du script est de faire une sauvegarde de vos base de données proprement pour pouvoir les ré-importer facilement.
Déroulement du script
- Création d'un répertoire temporaire de travail où stocker votre export des base de données
- Connexion à MySQL pour récupérer la liste des bases de données à sauvegarder
- Dump de la structures des tables des bases de données
- Dump du contenu des tables des bases de données
- Compression de la sauvegarde en l'archivant dans un fichier .tar.gz
- Suppression du répertoire temporaire de travail
- Suppression des archives trop anciennes
- Création d'un fichier de logs concernant la sauvegarde
- Mail du fichier de logs+liens ou télécharger la sauvegarde
Prérequis
- Serveur Linux
- Serveur MySQL
- Serveur Apache (optionnel)
- Serveur de mail (optionnel) –> si besoin utiliser https://doc.ubuntu-fr.org/ssmtp
- CRON pour exécuter automatiquement la sauvegarde
Installation
Le script nécessite un utilisateur pour accéder à la base de données. Ici on va créer un utilisateur “backup”. Pensez à remplacer :
- localhost par l'ip de votre serveur MySQL si il n'est pas local
- VOTRE_MOT_DE_PASSE par le mot de passe que vous voulez donner à l'utilisateur “backup”
mysql -u root -p -e "CREATE USER 'backup'@'localhost' IDENTIFIED BY 'VOTRE_MOT_DE_PASSE';"
Ensuite on donne à l'utilisateur “backup” plusieurs droits pour effectuer des dump
mysql -u root -p -e "GRANT SELECT , SHOW DATABASES , LOCK TABLES , SHOW VIEW ON * . * TO 'backup'@'localhost' IDENTIFIED BY 'VOTRE_MOT_DE_PASSE' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;"
Pour ne pas avoir le mot de passe en clair dans le script (utiliser le mdp de “backup” quand c'est demandé)
mysql_config_editor SET --login-path=backup --host=localhost --user=backup --password
Le script
- backup.sh
#!/bin/bash ######################################################################## # # Génération d'une sauvegarde des base de données # Il faudra exécuter le script automatiquement grâce à un cron # # Le script nécessite un utilisateur pour accéder à la base de données: # mysql -u root -p -e "CREATE USER 'backup'@'localhost' IDENTIFIED BY 'VOTRE_MOT_DE_PASSE';" # mysql -u root -p -e "GRANT SELECT , SHOW DATABASES , LOCK TABLES , SHOW VIEW ON * . * TO 'backup'@'localhost' IDENTIFIED BY 'VOTRE_MOT_DE_PASSE' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;" # # Pour ne pas avoir le mot de passe en clair dans le script (utilisé le mdp de backup quand c'est demandé) : # mysql_config_editor set --login-path=backup --host=localhost --user=backup --password # # Pensez à rendre exécutable le script de sauvegarde: chmod +x backup.sh # # Ajouter le script à votre cron (exécution tous les jours à 3h33) : crontab -e # 33 3 * * * /home/yourhome/yourbackupfolderpath/backup.sh # ######################################################################## # login path utilisé lors de la commande mysql_config_editor DB_LOGIN_PATH="backup" # email du rapport MAIL_REPORT="email@fournisseur.fr" #sujet du mail MAIL_SUBJECT="[MySQL] [backup] $(hostname -s) $(date +%Y.%m.%d@%Hh%M)" # Répertoire de stockage des sauvegardes FOLDER_BACKUP="$HOME/yourbackupfolderpath" # URL d'accès aux sauvegardes FOLDER_WWW="http://votresite.fr/backup/" # Fichiers de log et infos FILE_LOG="${FOLDER_BACKUP}/backup.log" FILE_INFO="${FOLDER_BACKUP}/backup.txt" # Nom de la sauvegarde BACKUP_NAME="backup" # Base de données à ignorer lors de la sauvegarde (vous pouvez en ajouter) BACKUP_IGNORE_DATABASES=( "mysql" "performance_schema" "phpmyadmin" "test" "sys" ) # Contenu des tables à ignorer lors de la sauvegarde (ignore uniquement le contenu, la structure sera bien sauvegardée) # Ex. "DATABASE1.TABLE1" "DATABASE1.TABLE2" "DATABASE2.TABLE1" BACKUP_IGNORE_TABLES_DATA=( "DATABASE1.oc_filecache" # Exemple pour Nextcloud on ne sauvegarde pas les données de cache ) # Nombre de jours max de rétention des sauvegardes BACKUP_RETENTION=300 ######################################################################## # # NE PAS TOUCHER AU RESTE DU CODE SAUF SI VOUS SAVEZ CE QUE VOUS FAITE ! # ######################################################################## # Format de nommage du fichier de sauvegarde (ne pas changer au risque de casser les rotations) BACKUP_DATE="$(date +%Y.%m.%d-%Hh%M)" BACKUP_FILE="${BACKUP_NAME}-${BACKUP_DATE}" BACKUP_PATH="${FOLDER_BACKUP}/${BACKUP_FILE}" ######################################################################## # # Fonctions du script # ######################################################################## tmp_folder_create() { echo "- Création du répertoire de sauvegarde temporaire: ${BACKUP_PATH}" | tee -a "$FILE_LOG" mkdir "${BACKUP_PATH}" 2>> "$FILE_LOG" } tmp_folder_delete() { echo "- Suppression du répertoire de sauvegarde temporaire: ${BACKUP_PATH}" | tee -a "$FILE_LOG" rm -rf "${BACKUP_PATH}" 2>> "$FILE_LOG" } mysql_connect() { echo "- Connexion à mysql pour lister toutes les BDD du serveur." | tee -a "$FILE_LOG" DATABASES="$(mysql --login-path=$DB_LOGIN_PATH -Bse 'show databases' 2>> $FILE_LOG | grep -v information_schema)" } mysql_dump() { echo "- Dump des bases de données" | tee -a "$FILE_LOG" BACKUP_IGNORE_TABLES_ARG="" for TABLE in "${BACKUP_IGNORE_TABLES_DATA[@]}" do BACKUP_IGNORE_TABLES_ARG+=" --ignore-table=${TABLE}" done for DATABASE in ${DATABASES[@]} do if [[ ! " ${BACKUP_IGNORE_DATABASES[@]} " =~ " ${DATABASE} " ]]; then echo " - Sauvegarde: $DATABASE.sql" | tee -a "$FILE_LOG" mysqldump --login-path=$DB_LOGIN_PATH --quick --add-locks --lock-tables --extended-insert --no-data $DATABASE > "${BACKUP_PATH}/${DATABASE}-structure.sql" 2>> $FILE_LOG mysqldump --login-path=$DB_LOGIN_PATH --quick --add-locks --lock-tables --extended-insert --no-create-info $BACKUP_IGNORE_TABLES_ARG $DATABASE > "${BACKUP_PATH}/${DATABASE}-data.sql" 2>> $FILE_LOG fi done } compress_dump() { echo "- Archivage de la sauvegarde: ${BACKUP_FILE}.tar.gz" | tee -a "$FILE_LOG" cd "${FOLDER_BACKUP}" tar -czf "${BACKUP_FILE}.tar.gz" "${BACKUP_FILE}" 2>> "$FILE_LOG" chmod 600 "${BACKUP_FILE}.tar.gz" 2>> "$FILE_LOG" } archive_link_latest() { echo "- Création du lien symbolique vers la dernière version: ${BACKUP_NAME}-latest.tar.gz" | tee -a "$FILE_LOG" unlink "${BACKUP_NAME}-latest.tar.gz" ln -s "${BACKUP_FILE}.tar.gz" "${BACKUP_NAME}-latest.tar.gz" } archive_remove_oldest() { echo "- Suppression des anciennes sauvegardes obsolètes" | tee -a "$FILE_LOG" find "${FOLDER_BACKUP}" -name "*.tar.gz" -mtime +$BACKUP_RETENTION -print -exec rm {} \; } file_info() { echo "- Génération du nouveau fichier d'informations sur les sauvegardes: ${FILE_INFO}" rm "${FILE_INFO}" find "${FOLDER_BACKUP}" -name "*.tar.gz" -exec basename {} \; | sort -r | while read file; do echo "${FOLDER_WWW}$file" >> "${FILE_INFO}"; done } mail_report_success() { echo "- Email du rapport des sauvegardes" cat $FILE_LOG $FILE_INFO | mail -s "$MAIL_SUBJECT" $MAIL_REPORT } mail_report_error() { echo "- Email de log des erreurs" cat $FILE_LOG | mail -s "[ERROR :(] $MAIL_SUBJECT" $MAIL_REPORT } ######################################################################## # # Déroulement du script # ######################################################################## echo "############################################################################### SAUVEGARDE" echo "########################################################################" > "${FILE_LOG}" echo "# NOUVELLE SAUVEGARDE $(hostname -s) ${BACKUP_DATE}" >> "${FILE_LOG}" echo "" >> "${FILE_LOG}" tmp_folder_create mysql_connect mysql_dump # le répertoire temporaire des dump est vide ! if [ -z "$(ls -A $BACKUP_PATH)" ]; then echo "Aucun mysql_dump n'a été trouvé !" >> "${FILE_LOG}" else compress_dump fi tmp_folder_delete # succès, une archive a été créé if [ -f "${BACKUP_FILE}.tar.gz" ]; then archive_link_latest archive_remove_oldest echo "" >> "${FILE_LOG}" echo "# SUCCÈS :)" >> "${FILE_LOG}" echo "########################################################################" >> "${FILE_LOG}" echo "" >> "${FILE_LOG}" echo "" >> "${FILE_LOG}" file_info mail_report_success echo "############################################################################### SUCCÈS :)" exit 0; # erreur, aucune archive n'a été créé else echo "" >> "${FILE_LOG}" echo "# ERREUR :(" >> "${FILE_LOG}" echo "########################################################################" >> "${FILE_LOG}" echo "" >> "${FILE_LOG}" echo "" >> "${FILE_LOG}" file_info mail_report_error echo "############################################################################### ERREUR :(" exit 1; fi
Pensez à rendre exécutable le script de sauvegarde: chmod +x backup.sh
Sauvegarde automatique avec CRON
Ajouter le script à votre cron :
crontab -e
Copiez la ligne si dessous qui va exécuter votre script ici tous les jours à 3h33
33 3 * * * /home/yourhome/yourbackupfolderpath/backup.sh
mysqldump-bash-mail.1575574724.txt.gz · Dernière modification : 2019/12/05 19:38 de JO