Nicola Capovilla - 22 Febbraio, 2019

Mysql Backup Script

Index

Il comando mysqldump

Il comando da terminale per generare un backup di un database MySQL è mysqldump. Lo script sottostante effettua il backup e lo salva in una determinata cartella in locale.
Modifica le configurazioni per effettuare il backup.

#! /bin/bash
### MySQL Server Login Info ###
MUSER="[your_mysql_user]"
MPASS="[your_mysql_passwor]"
MHOST="[your_mysql_host]"
MPORT="[your_mysql_port]"
DBNAME="[your_mysql_database]"
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
### File Info ###
# Save backup in temp directory before upload to server
TEMPDIR="[your_bkp_temp_dir]" #Exp: ./bkp_temp
# Name of bkp file (before the date)
FILENAME="[your_bkp_file_name_root]" #Exp: my_prj_daily_bkp_
NOW=$(date +%F)
#Create and clean temp directory
[ ! -d "$TEMPDIR" ] && mkdir -p "$TEMPDIR"
rm -f "$TEMPDIR"/*.*
# Create bkp
TFILENAME="$FILENAME""$NOW".sql
FILE=$TEMPDIR/$TFILENAME
$MYSQLDUMP -u $MUSER -h $MHOST -P $MPORT  -p$MPASS $DBNAME > $FILE

Questo è il comando per effettuare il backup:

$MYSQLDUMP -u $MUSER -h $MHOST -P $MPORT  -p$MPASS $DBNAME > $FILE

e questo è un esempio con le variabili in chiaro:

mysqldump -u root -h localhost -P 3306  -proot testdb > bkp_daily_2018-10-10.sql

Upload backup nel server

Ci sono diverse soluzioni per caricare su un server il file appena generato, va valutato di volta in volta in base anche al tipo di server e di connessione FTP disponibile.
In questo caso abbiamo usato il comando ftp:

### FTP SERVER Login info ###
FTPU="[your_ftp_username]"
FTPP="[your_ftp_password]"
FTPS="[your_ftp_server]"
DESTDIR="[your_ftp_destination_dir]"
ftp -n $FTPS <<END_SCRIPT
quote USER $FTPU
quote PASS $FTPP
binary
put $FILE $DESTDIR/$TFILENAME
quit
END_SCRIPT

($FILE e $TFILENAME sono state generate nello step precedente)
Lo script apre una connessione FTP e carica il file nella cartella impostata.

Eliminazione vecchi backup

A volte non è necessario memorizzare i backup di ogni giorno, lo spazio del server potrebbe esaurirsi in poco tempo. Una soluzione potrebbe essere, ad esempio, memorizzare i backup degli ultimi 30 giorni (in aggiunta magari un backup mensile).
Useremo la data impostata nel nome del file per eliminare i backup più vecchi di un certo periodo.

listing=`ftp -i -n $FTPS <<EOMYF
quote USER $FTPU
quote PASS $FTPP
binary
cd $DESTDIR
ls $FILENAME*
quit
EOMYF
`

Questo script apre una connessione FTP al server e ritorna la lista dei backup presenti.

lista=( $listing )
# loop over our files
for ((FNO=0; FNO<${#lista[@]}; FNO+=9));do
    # month (element 5), day (element 6) and filename (element 8)
    # filename
    f=${lista[`expr $FNO+8`]}
    IFS='_' read -r -a arrayF <<< "$f"
    IFS='.' read -r -a arrayD <<< "${arrayF[2]}"
    # Split name and get date
    d=${arrayD[0]}
    DAY=$(date -d "$d" +%Y-%m-%d)
    diff=$(( ($(date -d $NOW +%s) - $(date -d $DAY +%s) )/(60*60*24) ))
    # Remove older file
    if [[ $NDAYS -lt $diff ]];
    then
        ftp -n $FTPS <<END_SCRIPT
        quote USER $FTPU
        quote PASS $FTPP
        binary
        cd $DESTDIR
        delete $f
        quit
END_SCRIPT
fi
done

Per ogni file prenderemo la data dal nome e se è più vecchia di $NDAYS ci connetteremo al server ed elimineremo il file.

Schedulare backup con crontab

crontab è un comando Linux usato per schedulare jobs usando cron daemon.
Cron daemon legge il file di crontab ed esegue le operazioni indicate nel cronjob in modo completamente automatico.

Comandi base crontab

List

crontab -l

Mostra il contenuto del crontab.

Remove

crontab -r

Rimuove tutti i cronjob.

Edit

crontab -e

Apre un editor Vim e permette la modifica delle configurazioni.

Schedulare un job

Per schedulare in maniera automatica dobbiamo solo specificare la data, il tempo di esecuzione e lo script da eseguire.

Questo è il formato per inserire una nuova attività:

[minutes] [hour] [month day] [month] [week day] [path to script]

Ad esempio:

00 00 * * * /usr/script/mysql-backup.sh

Questa riga esegue il nostro script ogni giorno alle ore 00.00.

All

Con il comando (*) includiamo tutti i possibili valori
00 00 * * * /usr/script/mysql-backup.sh

Ogni giorno alle 00:00.

Repeater

Con il comando (/) specifichiamo la ripetizione del task
*/5 00 * * * /usr/script/mysql-backup.sh

Ogni 5 min.

Range

Con il comando (-) specifichiamo il range
00 9 1-4 * * /usr/script/mysql-backup.sh

Lo script verrà eseguito alle 9:00 dei primi 4 giorni di ogni mese.

List

Con il comando (,) indichiamo una lista
00 9 * 6,12 * /usr/script/mysql-backup.sh

Lo script verrà eseguito ogni giorno alle 9:00 nei mesi di giugno e dicembre.

Shortcat

  • @reboot Avvia il job al reboot del server
  • @yearly Avvia il job ogni anno (il primo dell'anno) [0 0 1 1 *]
  • @annually Avvia il job ogni anno (il primo dell'anno) [0 0 1 1 *]
  • @monthly Avvia il job ogni mese [0 0 1 * *]
  • @weekly Avvia il job ogni settimana [0 0 * * 0]
  • @daily Avvia il job ogni giorno [0 0 * * *]
  • @midnight Avvia il job ogni a mezzanotte [0 0 * * *]
  • @hourly Avvia il job ogni ora [0 * * * *]

Schedulare il nostro job

Ora abbiamo tutti gli elementi per generare il nostro backup in maniera automatica.
Decidiamo di lanciarlo ogni giorno, quindi il nostro comando sarà:

@daily /usr/script/mysql-backup.sh

Ripristino backup

Se c'è la necessità di ripristinare un backup Mysql (speriamo per test e non per fare revert in produzione :D) è sufficiente individuare il backup da ripristinare e scaricarlo dal server. Una volta ottenuto il file basterà lanciare il seguente comando:

mysql -u [username] -p [DB name] < [file.sql]

Se il DB MySQL è situato in un altro host:

mysql -h [host] -u [username] -p [DB name] < [file.sql]

Trovate il codice completo in questo repository Github.