/ Published in: Bash
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
#!/bin/bash # # Saibal MySQL Backup Script # # VER. 1.1 - http://www.lorenzone.it # Copyright (c) 2010 [email protected] # # BY IDEA OF DAVIDE BUZZI'S SCRIPT. THANK YOU BROTHER! # THANK YOU TO MR. GLAUCO TOO! # # 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. # # 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #===================================================================== #===================================================================== # CHANGELOG #===================================================================== # Versione 1.1 # Separazione funzioni dump e compressione # Aggiunti controlli sulla creazione delle cartelle e dei file # Sostituzione funzione touch con echo -e per la creazione del file di log # Sostituzione del comando LET per le operazioni di incremento contatori # Rivisitazione generale del codice # Versione 1.0 # Aggiunto invio log per email # Aggiunto trasferimento FTP # Controllo generale del codice # # Versione 0.5 # Aggiunto backup giornaliero # Aggiunto backup mensile # Aggiunta registrazione dei log #===================================================================== # TO REMEMBER #===================================================================== # # 1) nelle operazioni per aumentare i contatori potrei usare il comando "let". Es.: 'let CONTA++' aumenta di 1 il contatore # Si però tratta di un "bashismo" che non mi assicura la compatibilità su altre shell. # Per questo motivo utilizzo l'espasione classica. Es.: CONTA=$(( CONTA + 1 )). # 2) Per creare un file potrei usare "touch" ma per avere un corretto return-code ($?) se esiste una dir # con lo stesso nome uso 'echo -n'. il parametro -n non inserisce una riga vuota nel nuovo file creato #===================================================================== # Configurazione generale #===================================================================== # host database DBHOST='localhost' # username database USERNAME='root' # password database PASSWORD='' # lista dei database da salvare (separati da spazio) DATABASES='mysql' # directory dove salvare i backup (senza slash finale) OUT_DIR='/home/UTENTE/bk_database' # formato data (it oppure en) DATE_FORMAT='it' # backup mensile? (y oppure n) MONTHLY_BACKUP='y' # giorno del mese in cui effettuare il backup mensile (formato 01, 02, 03, etc) MONTHLY_BKDAY='01' # cartella backup giornalieri DAILY_FOLDER='daily' # cartella backup mensili MONTHLY_FOLDER='monthly' # cartella ultimo backup LAST_FOLDER='last' #===================================================================== # Configurazione logs #===================================================================== # registrazione dei log? (y oppure n) LOGS_REC='y' # directory dove salvare i LOG. Se lasciata vuota sarà la stessa dei backup (senza slash finale) LOGS_DIR='' # cartella dei LOG LOGS_FOLDER='dumplog' # nome del file di LOG LOGS_FILENAME='dump.log' # dimensione massima del file di log (in KB) LOGS_MAXSIZE='900' #===================================================================== # Configurazione invio email #===================================================================== # abilitare invio email con risultato delle operazioni? (y oppure n) EMAIL_SEND='n' # inviare email solo in caso di errore? (y oppure n) EMAIL_ONLYERRORS='y' # programma da utilizzare EMAIL_SERVICE='sendmail' # destinatario email EMAIL_RECIVER='[email protected]' # soggetto email EMAIL_SUBJECT='MySQL Backup - resoconto' #===================================================================== # Configurazione ftp #===================================================================== # abilitare trasferimento FTP dei backup? (y oppure n) FTP_TRANSF='n' # trasferire backup giornalieri o solo i last? (d oppure l) FTP_FILES='d' # indirizzo FTP FTP_HOST='123.123.123.123' # username FTP FTP_USER='xx' # password FTP FTP_PASSWORD='xx' # directory in cui inserire i file FTP_REMOTEDIR='/public_html/bk_db' # file temp. per il log dei comandi di console FTP. Il risultato dell'operazione viene invece registrato sul file generale FTP_LOGS_FILENAME='ftp.log' #===================================================================== # Configurazione messaggi #===================================================================== # messaggi di ritorno per il backup (NOMEDB è un placeholder. se possibile non cancellare) BACKUP_OK="BACKUP RIUSCITO! | $HOSTNAME | Tutti i backup effettuati con successo" BACKUP_KO="ERRORE BACKUP! | $HOSTNAME | I seguenti database: NOMEDB non sono stati copiati e/o compressi" CONNEC_KO="ERRORE MYSQL! | $HOSTNAME | Impossibile connettersi ai seguenti database: NOMEDB" SEMAIL_KO="ERRORE INVIO! | $HOSTNAME | Impossibile trovare il servizio $EMAIL_SERVICE per inviare messaggi" FTPPUT_OK="FTP RIUSCITO! | $HOSTNAME | Tutti i file sono stati trasferiti con successo sul server $FTP_HOST" FTPPUT_KO="ERRORE FTP! | $HOSTNAME | Errore procedura FTP. Errore: FTPERR" ######################################## # START CODE - BE CAREFUL WHEN EDITING ######################################## #========================================= # FUNZIONI VARIE #========================================= # funzione per controllare la corretta creazione delle directory e dei file check_build() { # $1 è il return code dell'operazione precedente ($?) | $2 è il nome della dir che si è tentato di creare if [ "$1" -eq "1" ] then echo "Errore nel creare $2. Controllare che non esista un file/directory con lo stesso nome" exit fi } # funzione per check invio email check_email() { if [ "$EMAIL_SEND" = "y" ] then CHECK_MAIL=$(which $EMAIL_SERVICE) if [ -n "$CHECK_MAIL" ] then MAIL_RESULT=1 else MAIL_RESULT=0 # aumento il contatore ERROR_NOMAIL_SERVICE=$(( ERROR_NOMAIL_SERVICE + 1 )) fi else MAIL_RESULT=0 fi return $MAIL_RESULT } # funzione per check connessione al database check_connection() { # testo la connessione mysql --user=$USERNAME --password=$PASSWORD $DB -e STATUS > /dev/null 2>&1 # id errore CONN_ERROR=$? return $CONN_ERROR } # funzione per effettuare il dump al db do_mysqldump() { # dump del database mysqldump --user=$USERNAME --password=$PASSWORD --host=$DBHOST $DB > "$1" # registro il risultato dell'operazione mysqldump. DUMP_ERROR=$? return $DUMP_ERROR } # funzione per effettuare la compressione del database do_compression() { # comprimo il tutto con gzip gzip -f "$1" #risultato operazione gzip GZIP_ERROR=$? return $GZIP_ERROR } #========================================= # VARIABILI #========================================= # path principali del sistema PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/mysql/bin:/usr/sbin # data di oggi TODAY_DATE=`date +%d/%m/%Y` # ora di oggi TODAY_TIME=`date +%T` # giorno della settimana (1 Lunedì, 2 Martedì, etc etc) NDAY=`date +%u` # giorno del mese (formato 01, 02, 03, etc) DMON=`date +%d` # mese MON=`date +%m` # mese - anno MONYEA=`date +%m_%Y` # date esecuzione backup nei due formati DATEIT=`date +\[%d-%m-%Y_%H-%M\]` DATEEN=`date +\[%Y-%m-%d_%H-%M\]` # formato data per i log LOGDATE="`date +%Y/%m/%d` - `date +%T`" # dichiaro questa variabile perchè il backup mensile è opzionale LOGS_RESULT_MONTHLY=0 # contatori di errori ERROR_CONN_TODB=0 ERROR_COUNT_DAILY=0 ERROR_COUNT_MONTHLY=0 ERROR_NOMAIL_SERVICE=0 ERROR_FTP_TRANSFER=0 # codice per convertire in LOWERCASE le variabili inserite in questo array TO_LOWER=("DATE_FORMAT" "MONTHLY_BACKUP" "LOGS_REC" "EMAIL_SEND" "EMAIL_ONLYERRORS" "FTP_TRANSF" "FTP_FILES") for INPUT in "${TO_LOWER[@]}" do eval $INPUT="$(echo ${!INPUT} | tr 'A-Z' 'a-z')" done # scelgo la formattazione della data if [ "$DATE_FORMAT" = "it" ] then DATE="$DATEIT" else DATE="$DATEEN" fi # se non esiste la directory OUTDIR la creo if [ ! -d "$OUT_DIR" ] then mkdir -p "$OUT_DIR" fi # controllo la creazione della dir check_build "$?" "$OUT_DIR" # se non esiste la directory DAILY la creo if [ ! -d "$OUT_DIR/$DAILY_FOLDER" ] then mkdir -p "$OUT_DIR/$DAILY_FOLDER" fi # controllo la creazione della dir check_build "$?" "$OUT_DIR/$DAILY_FOLDER" # se non esiste la directory LAST la creo if [ ! -d "$OUT_DIR/$LAST_FOLDER" ] then mkdir -p "$OUT_DIR/$LAST_FOLDER" fi # controllo la creazione della dir check_build "$?" "$OUT_DIR/$LAST_FOLDER" # se non esiste la directory MONTHLY la creo if [ "$MONTHLY_BACKUP" = "y" ] then if [ ! -d "$OUT_DIR/$MONTHLY_FOLDER" ] then mkdir -p "$OUT_DIR/$MONTHLY_FOLDER" fi # controllo la creazione della dir check_build "$?" "$OUT_DIR/$MONTHLY_FOLDER" fi # se sono abilitati i logs e non esiste la directory LOGS la creo e calcolo la dimensione massima del file if [ "$LOGS_REC" = "y" ] then # se la variabile LOGS_DIR non è vuota la imposto altrimenti inserisco la cartella dentro la directory di default if [ -n "$LOGS_DIR" ] then LOGS_DIR="$LOGS_DIR/$LOGS_FOLDER" else LOGS_DIR="$OUT_DIR/$LOGS_FOLDER" fi # creo la directory if [ ! -d "$LOGS_DIR" ] then mkdir -p "$LOGS_DIR" fi # controllo la creazione della dir check_build "$?" "$LOGS_DIR" # creo il file di log if [ ! -f "$LOGS_DIR/$LOGS_FILENAME" ] then echo -ne > "$LOGS_DIR/$LOGS_FILENAME" fi # controllo la creazione del file check_build "$?" "$LOGS_DIR/$LOGS_FILENAME" # cancello il file log FTP se viene disabilitata la funzione (ma la funzione log generale deve cmq essere attiva!) if [ "$FTP_TRANSF" != "y" ] then rm -f "$LOGS_DIR/$FTP_LOGS_FILENAME" fi # converto i KB in BYTES dopo aver controllato che la VAR non sia vuota if [ -n "$LOGS_MAXSIZE" ] then LOGS_MAXBYTES=$(( $LOGS_MAXSIZE*1000 )) else LOGS_MAXBYTES=$(( 1000*1000 )) fi fi #========================================= # START BACKUP NOW!!! #========================================= # Controllo l'invio delle email. ritorna $MAIL_RESULT check_email # inizio il ciclo sui database for DB in $DATABASES do # funzione per testare la connessione al database. ritorna $CONN_ERROR check_connection if [ "$CONN_ERROR" -eq "0" ] then ######################################## # BACKUP GIORNALIERO ######################################## # rimuovo i vecchi backup (qualsiasi estensione) rm -f "$OUT_DIR/$DAILY_FOLDER/[${NDAY}]__${DB}__"* # creo il nome del file da dumpare e comprimere in .gz OUTFILE="$OUT_DIR/$DAILY_FOLDER/[${NDAY}]__${DB}__${DATE}.sql" # ci sbatto dentro il dump. ritorna $DUMP_ERROR do_mysqldump "$OUTFILE" # comprimo il file. ritorna $GZIP_ERROR do_compression "$OUTFILE" # se la compressione è avvenuta rimuovo i vecchi file ".last" e copio l'ultimo gzip creato dentro la dir LAST if [ "$GZIP_ERROR" -eq "0" ] then rm -f "$OUT_DIR/$LAST_FOLDER/${DB}__"*"__last.sql.gz" # uso la funzione cp cp "$OUTFILE.gz" "$OUT_DIR/$LAST_FOLDER/${DB}__${DATE}__last.sql.gz" fi # uso le VAR di ritorno delle funzioni per gestire gli errori nei log se abilitati if [ "$LOGS_REC" = "y" ] then if [ "$DUMP_ERROR" -gt "0" -o "$GZIP_ERROR" -gt "0" ] then # aumento il contatore ERROR_COUNT_DAILY=$(( ERROR_COUNT_DAILY + 1 )) # registro i DB nella stessa variabile ERROR_DB+="[${DB}__giornaliero] " fi fi ######################################## # BACKUP MENSILE ######################################## if [ "$MONTHLY_BACKUP" = "y" ] then if [ "$DMON" = "$MONTHLY_BKDAY" ] then # rimuovo i vecchi backup rm -f "$OUT_DIR/$MONTHLY_FOLDER/[${MON}_"*"]__${DB}"* # creo il nome del file da dumpare e comprimere in .gz OUTFILE="$OUT_DIR/$MONTHLY_FOLDER/[${MONYEA}]__${DB}.sql" # ci sbatto dentro il dump. ritorna $DUMP_ERROR do_mysqldump "$OUTFILE" # comprimo il file. ritorna $GZIP_ERROR do_compression "$OUTFILE" # preparo i messaggi di log se abilitati if [ "$LOGS_REC" = "y" ] then if [ "$DUMP_ERROR" -gt "0" -o "$GZIP_ERROR" -gt "0" ] then # aumento il contatore ERROR_COUNT_MONTHLY=$(( ERROR_COUNT_MONTHLY + 1 )) # registro i DB nella stessa variabile ERROR_DB+="[${DB}__mensile] " fi fi fi fi else if [ "$LOGS_REC" = "y" -o "$MAIL_RESULT" -eq "1" ] then # aumento il contatore ERROR_CONN_TODB=$(( ERROR_CONN_TODB + 1 )) # registro i DB nella stessa variabile ERROR_CONN_DB+="[${DB}] " fi fi done #========================================= # FTP SECTION!!! #========================================= if [ "$FTP_TRANSF" = "y" -a "$CONN_ERROR" -eq "0" ] then if [ "$FTP_FILES" = "d" ] then FTP_FOLDER="$DAILY_FOLDER" MFILENAME="*[${NDAY}]*]*.gz" else FTP_FOLDER="$LAST_FOLDER" MFILENAME="*__last*.gz" fi echo " open $FTP_HOST user $FTP_USER $FTP_PASSWORD binary lcd $OUT_DIR/$FTP_FOLDER cd $FTP_REMOTEDIR mdelete $MFILENAME mput $MFILENAME close quit" | ftp -in -v > "$LOGS_DIR/$FTP_LOGS_FILENAME" 2>&1 # visto che le funzioni FTP fanno schifo cerco in qualche maniera di intercettare gli errori # non connesso FTP_TRAPERR=`grep -i "Not connected." "$LOGS_DIR/$FTP_LOGS_FILENAME"` if [ "$?" -eq "0" ] then # aumento il contatore ERROR_FTP_TRANSFER=$(( ERROR_FTP_TRANSFER + 1 )) ERROR_FTP_RESULT="${ERROR_FTP_RESULT}Connessione al server FTP fallita | " fi # autenticazione fallita FTP_TRAPERR=`grep -i "Login authentication failed" "$LOGS_DIR/$FTP_LOGS_FILENAME"` if [ "$?" -eq "0" ] then # aumento il contatore ERROR_FTP_TRANSFER=$(( ERROR_FTP_TRANSFER + 1 )) ERROR_FTP_RESULT="${ERROR_FTP_RESULT}Autenticazione fallita | " fi # directory remota non trovata FTP_TRAPERR=`grep -i "change directory to $FTP_REMOTEDIR" "$LOGS_DIR/$FTP_LOGS_FILENAME"` if [ "$?" -eq "0" ] then # aumento il contatore ERROR_FTP_TRANSFER=$(( ERROR_FTP_TRANSFER + 1 )) ERROR_FTP_RESULT="${ERROR_FTP_RESULT}Directory remota non trovata | " fi # non trovo i file FTP_TRAPERR=`grep -i "no such" "$LOGS_DIR/$FTP_LOGS_FILENAME"` if [ "$?" -eq "0" ] then # aumento il contatore ERROR_FTP_TRANSFER=$(( ERROR_FTP_TRANSFER + 1 )) ERROR_FTP_RESULT="${ERROR_FTP_RESULT}File o directory non trovati | " fi # app chiusa FTP_TRAPERR=`grep -i "killed" "$LOGS_DIR/$FTP_LOGS_FILENAME"` if [ "$?" -eq "0" ] then # aumento il contatore ERROR_FTP_TRANSFER=$(( ERROR_FTP_TRANSFER + 1 )) ERROR_FTP_RESULT="${ERROR_FTP_RESULT}Processo di trasferimento abbandonato | " fi # spazio su disco esaurito (come me!! bwuahbwuah) FTP_TRAPERR=`grep -i "space" "$LOGS_DIR/$FTP_LOGS_FILENAME"` if [ "$?" -eq "0" ] then # aumento il contatore ERROR_FTP_TRANSFER=$(( ERROR_FTP_TRANSFER + 1 )) ERROR_FTP_RESULT="${ERROR_FTP_RESULT}Mancanza di spazio su disco" fi fi #========================================= # MAIL SECTION!!! #========================================= if [ "$MAIL_RESULT" -eq "1" ] then # se viene scelto di ricevere una email anche quando le operazioni sono OK if [ "$EMAIL_ONLYERRORS" = "n" ] then # se tutti i dump sono OK invio il messaggio relativo if [ "$ERROR_CONN_TODB" -eq "0" -a "$ERROR_COUNT_DAILY" -eq "0" -a "$ERROR_COUNT_MONTHLY" -eq "0" ] then BACKUP_OK="$LOGDATE | $BACKUP_OK" # se è attivo il trasferimento file e non ci sono errori aggiungo una parte di messaggio if [ "$FTP_TRANSF" = "y" -a "$ERROR_FTP_TRANSFER" -eq "0" ] then BACKUP_OK="$BACKUP_OK | $FTPPUT_OK" fi echo "$BACKUP_OK" | mail -s "$EMAIL_SUBJECT" $EMAIL_RECIVER fi fi # invio email errore backup giornaliero o mensile if [ "$ERROR_COUNT_DAILY" -gt "0" -o "$ERROR_COUNT_MONTHLY" -gt "0" ] then BACKUP_KO="$LOGDATE | $BACKUP_KO" BACKUP_KO=${BACKUP_KO//NOMEDB/$ERROR_DB} echo "$CONNEC_KO" | mail -s "$EMAIL_SUBJECT" $EMAIL_RECIVER fi # invio email errore connessioni al database if [ "$ERROR_CONN_TODB" -gt "0" ] then CONNEC_KO="$LOGDATE | $CONNEC_KO" CONNEC_KO=${CONNEC_KO//NOMEDB/$ERROR_CONN_DB} echo "$CONNEC_KO" | mail -s "$EMAIL_SUBJECT" $EMAIL_RECIVER fi # invio email errore trasferimento file if [ "$ERROR_FTP_TRANSFER" -gt "0" ] then FTPPUT_KO="$LOGDATE | $FTPPUT_KO" FTPPUT_KO=${FTPPUT_KO//FTPERR/$ERROR_FTP_RESULT} echo "$FTPPUT_KO" | mail -s "$EMAIL_SUBJECT" $EMAIL_RECIVER fi fi #========================================= # LOGS SECTION!!! #========================================= if [ "$LOGS_REC" = "y" ] then echo ====================================================================== echo Saibal MySQL Backup echo echo Start time: $TODAY_TIME - $TODAY_DATE echo Backup of MySQL Databases \(powered by saibal - saibal@lorenzone.it\) echo ====================================================================== echo Risultato delle operazioni: echo # dimensione del file per vedere quando troncarlo LOG_SIZE=$( stat -c %s "$LOGS_DIR/$LOGS_FILENAME") # se la misura attuale è più grande di quella massima tronco il file e ricomincio if [ $LOG_SIZE -gt "$LOGS_MAXBYTES" ] then # con il parametro -n non metto una riga vuota nel file echo -ne > "$LOGS_DIR/$LOGS_FILENAME" fi # se vengono rilevati errori nel servizio di posta if [ "$ERROR_NOMAIL_SERVICE" -gt "0" ] then SEMAIL_KO="$LOGDATE | $SEMAIL_KO" echo "$SEMAIL_KO" echo "$SEMAIL_KO" >> "$LOGS_DIR/$LOGS_FILENAME" fi # se c'è un problema FTP stampo il messaggio if [ "$ERROR_FTP_TRANSFER" -gt "0" ] then FTPPUT_KO="$LOGDATE | $FTPPUT_KO" FTPPUT_KO=${FTPPUT_KO//FTPERR/$ERROR_FTP_RESULT} echo "$FTPPUT_KO" echo "$FTPPUT_KO" >> "$LOGS_DIR/$LOGS_FILENAME" elif [ "$FTP_TRANSF" = "y" -a "$ERROR_FTP_TRANSFER" -eq "0" ] then FTPPUT_OK="$LOGDATE | $FTPPUT_OK" echo "$FTPPUT_OK" echo "$FTPPUT_OK" >> "$LOGS_DIR/$LOGS_FILENAME" fi # se tutti i dump sono OK stampo il messaggio relativo if [ "$ERROR_CONN_TODB" -eq "0" -a "$ERROR_COUNT_DAILY" -eq "0" -a "$ERROR_COUNT_MONTHLY" -eq "0" ] then # replace di alcune variabili BACKUP_OK="$LOGDATE | $BACKUP_OK" echo "$BACKUP_OK" echo "$BACKUP_OK" >> "$LOGS_DIR/$LOGS_FILENAME" # se i dump (mensile e/o giornaliero) fallisce stampo un determinato messaggio else if [ "$ERROR_COUNT_DAILY" -gt "0" -o "$ERROR_COUNT_MONTHLY" -gt "0" ] then BACKUP_KO="$LOGDATE | $BACKUP_KO" BACKUP_KO=${BACKUP_KO//NOMEDB/$ERROR_DB} echo "$BACKUP_KO" echo "$BACKUP_KO" >> "$LOGS_DIR/$LOGS_FILENAME" fi # se c'è un problema di connessione al database stampo il messaggio if [ "$ERROR_CONN_TODB" -gt "0" ] then CONNEC_KO="$LOGDATE | $CONNEC_KO" CONNEC_KO=${CONNEC_KO//NOMEDB/$ERROR_CONN_DB} echo "$CONNEC_KO" echo "$CONNEC_KO" >> "$LOGS_DIR/$LOGS_FILENAME" fi fi fi exit
URL: http://www.lorenzone.it/my-ubuntu/script-bash-per-il-backup-dei-database-mysql/764/