#!/bin/bash VER=0.1 PROJECT="https://git.gresse.net/Ops/Backup" SCRIPT_NAME=mysql_backup.sh SCRIPT_FILENAME=`basename "$0"` BACKUP_DIR=/tmp/backup #LOGIN MYSQL_SERVER=localhost MYSQL_USER= MYSQL_PASSWD= # Number of monthly, weekly and daily backups KEEP_DAILY_BCK=1 KEEP_WEEKLY_BCK=4 KEEP_MONTHLY_BCK=6 # Target weekday to take weekly and monthly backups (Monday is 1 and Sunday is 7 - O to disable) TARGET_WEEKDAY=1 # Ex : "|mydb001|mydb002" EGREP_EXCLUDE_DB="" LATEST_TIMESTAMP=$(date +"%Y%m%d-%HH%M") DAILY_TIMESTAMP=$(date +"%Y%m%d") LOG_FILE=${BACKUP_DIR}/logs/${SCRIPT_NAME}-${LATEST_TIMESTAMP}.log ERR_FILE=${BACKUP_DIR}/logs/${SCRIPT_NAME}.err CMD_MYSQL=/usr/local/mysql/bin/mysql CMD_MYSQLDUMP='/usr/local/mysql/bin/mysqldump --opt --routines' CMD_GZIP=gzip function backup() { DAY_OF_MONTH=$(date +%d) WEEKDAY=$(date +%u) echo_date "Starting Backup" >>${LOG_FILE} DATABASES=`echo "show databases" | ${CMD_MYSQL} -h ${MYSQL_SERVER} -u ${MYSQL_USER} -p${MYSQL_PASSWD} | egrep -v "Database|information_schema|performance_schema${EGREP_EXCLUDE_DB}"` for DB in ${DATABASES}; do echo_date "Remove latest backup of database '${DB}'" >>${LOG_FILE} rm -f ${BACKUP_DIR}/latest/${DB}--* >>${LOG_FILE} 2>&1 echo_date "Starting backup of database '${DB}'" >>${LOG_FILE} ${CMD_MYSQLDUMP} -h ${MYSQL_SERVER} -u ${MYSQL_USER} -p${MYSQL_PASSWD} ${DB} | ${CMD_GZIP} > ${BACKUP_DIR}/latest/${DB}--${LATEST_TIMESTAMP}.dmp.gz 2>>${LOG_FILE} echo_date "Copy to daily backup of database '${DB}' " >>${LOG_FILE} cp ${BACKUP_DIR}/latest/${DB}--${LATEST_TIMESTAMP}.dmp.gz ${BACKUP_DIR}/daily/${DB}--${DAILY_TIMESTAMP}.dmp.gz echo_date "Keep only the last ${KEEP_DAILY_BCK} daily backup of database '${DB}'" >>${LOG_FILE} ls -td ${BACKUP_DIR}/daily/${DB}--* | tail -n +$((${KEEP_DAILY_BCK}+1)) | xargs rm -f >>${LOG_FILE} 2>&1 if [ ${WEEKDAY} = ${TARGET_WEEKDAY} ]; then echo_date "Keep only the last ${KEEP_WEEKLY_BCK} weekly backup of database '${DB}'" >>${LOG_FILE} ls -td ${BACKUP_DIR}/weekly/${DB}--* | tail -n +$((${KEEP_WEEKLY_BCK}+1)) | xargs rm -f >>${LOG_FILE} 2>&1 echo_date "Copy to weekly backup of database '${DB}'" >>${LOG_FILE} cp ${BACKUP_DIR}/latest/${DB}--${LATEST_TIMESTAMP}.dmp.gz ${BACKUP_DIR}/weekly/${DB}--${DAILY_TIMESTAMP}.dmp.gz if [ ${DAY_OF_MONTH} -lt 8 ]; then echo_date "Keep only the last ${KEEP_MONTHLY_BCK} monthly backup of database '${DB}'" >>${LOG_FILE} ls -td ${BACKUP_DIR}/monthly/${DB}--* | tail -n +$((${KEEP_MONTHLY_BCK}+1)) | xargs rm -f >>${LOG_FILE} 2>&1 echo_date "Copy to monthly backup of database '${DB}'" >>${LOG_FILE} cp ${BACKUP_DIR}/latest/${DB}--${LATEST_TIMESTAMP}.dmp.gz ${BACKUP_DIR}/monthly/${DB}--${DAILY_TIMESTAMP}.dmp.gz fi fi done echo_date "Backup finished" >>${LOG_FILE} } function install() { echo "Starting Installation to directory '${BACKUP_DIR}'" if [ -e ${BACKUP_DIR} ] ; then _err "${BACKUP_DIR} already exists" exit 1 fi echo -n " -> Create directory ${BACKUP_DIR}/daily" mkdir -p ${BACKUP_DIR}/data/daily echo ": Done" echo -n " -> Create directory ${BACKUP_DIR}/weekly" mkdir -p ${BACKUP_DIR}/data/weekly echo ": Done" echo -n " -> Create directory ${BACKUP_DIR}/monthly" mkdir -p ${BACKUP_DIR}/data/monthly echo ": Done" echo -n " -> Create directory ${BACKUP_DIR}/latest" mkdir -p ${BACKUP_DIR}/data/latest echo ": Done" echo -n " -> Create directory ${BACKUP_DIR}/logs" mkdir -p ${BACKUP_DIR}/logs echo ": Done" echo -n " -> Create directory ${BACKUP_DIR}/conf" mkdir -p ${BACKUP_DIR}/conf echo ": Done" echo -n " -> Install script to ${BACKUP_DIR}" cp ${SCRIPT_FILENAME} ${BACKUP_DIR}/${SCRIPT_NAME} chmod +x ${BACKUP_DIR}/${SCRIPT_NAME} echo ": Done" echo -n " -> Change Backup Directory in installed script" sed -i -r "s!^BACKUP_DIR=.*!BACKUP_DIR=$BACKUP_DIR!" ${BACKUP_DIR}/${SCRIPT_NAME} echo ": Done" echo -n " -> Install Crontab" crontab -l | { cat; echo "30 22 * * * ${BACKUP_DIR}/${SCRIPT_NAME} -r >/dev/null 2>&1"; } | crontab - echo ": Done" echo " -> Install Finished :)" } function list() { echo "=== === === Listing all backups === === ===" echo " -> List ${BACKUP_DIR}/latest" ls -alth ${BACKUP_DIR}/latest/* 2>/dev/null echo " -> List ${BACKUP_DIR}/daily" ls -alth ${BACKUP_DIR}/daily/* 2>/dev/null echo " -> List ${BACKUP_DIR}/weekly" ls -alth ${BACKUP_DIR}/weekly/* 2>/dev/null echo " -> List ${BACKUP_DIR}/monthly" ls -alth ${BACKUP_DIR}/monthly/* 2>/dev/null } function uninstall() { read -r -p "Are you sure to uninstall ${BACKUP_DIR}? [y/N]" confirm_uninstall case ${confirm_uninstall} in [yY]) echo "=== === === Uninstall all === === ===" echo -n " -> Remove directory ${BACKUP_DIR}" rm -Rf ${BACKUP_DIR} echo ": Done" echo -n " -> Remove crontab (TODO)" echo ": Done" echo " -> Uninstall Finished :)" ;; *) echo "=== === === Abort Uninstall === === ===" exit ;; esac } function _info() { date +"[INFO] ${1}" } function _err(){ echo "[ERROR] ${1}" } function _process(){ while [ ${#} -gt 0 ]; do case "${1}" in --help | -h) showhelp return ;; --version | -v) version return ;; --install | -i) if [ -n "${2}" ]; then BACKUP_DIR=${2} fi install return ;; --uninstall | -u) if [ -n "${2}" ]; then BACKUP_DIR=${2} fi uninstall return ;; --list | -l) list return ;; --run | -r) backup return ;; *) echo "Unknown parameter : ${1}" return 1 ;; esac shift done fi } version() { echo "${SCRIPT_NAME} (${PROJECT}) - Version ${VER}" } function showhelp() { echo "Usage: mysql_backup.sh [commands] Commands: -h, --help Show this help message. -v, --version Show version info. -i, --install Install to the specific direcotry. -u, --uninstall Uninstall to the specific direcotry. -l, --list List backup -r, --run Run backup of all databases " } function main() { [ -z "$1" ] && showhelp && return _process "$@" } main "$@"