rsync + sshpass: copias de seguridad remotas

Veamos como crear un script para realizar una copia de seguridad remota entre dos servidores.

Supongamos que tenemos dos servidores remotos uno que llamaremos “producción” y otro que llamaremos “backup”, ambos están corriendo el mismo sistema operativo Linux, una versión CentOS 7 . La idea es crear un script sobre el servidor “producción” que se ejecutará mediante un “crontab” todas las noches, ese escript realizará una copia de los archivos de una determinada carpeta y además necesitamos realizar la copia de la base de datos de un determinado usuario de MySQL. Por otro lado tenemos una unidad NAS en la red local del servidor donde realizaremos una copia semanal del servidor de backup. Veamos el siguiente esquema para terminar de entender el problema que planteamos:

Para poder desarrollar esta solución tenemos que tener instalados estos tres programas:

  • rsync: que será el programa principal que realizará las copias
  • sshpass: necesario para poder hacer la validación automática del usuario, ya que la idea del script es que se ejecute de forma auomática por la noche, para ser lanzado desde un crontab, y teniendo en cuenta que rsync no para poder hacer la copia remota siempre nos pedirá el usuario y la contraseña del servidor remoto, es por lo que necesitamos de la ayuda de sshpass para poder hacer la validación.
  • ftp: el cliente de ftp realizará la copia de seguridad del servidor Backup a la unidad NAS.
yum install ftp sshpass rsync

Creando ficheros de respaldo

Lo primero que haremos es un script para crear un fichero que incluya un “mysqldump” para cada una de las bases de datos que queramos respaldar:

#!/bin/bash
mysqldump --user=usuario1 --password=pwdusuario1 nombre-bbdd > /ruta-de-la/copia/bbddusuario1.sql
mysqldump --user=usuario2 --password=pwdusuario2 nombre-bbdd > /ruta-de-la/copia/bbddusuario2.sql
...
mysqldump --user=usuariox --password=pwdusuariox nombre-bbdd > /ruta-de-la/copia/bbddusuariox.sql

Si quisieramos copiar todas las bases de datos con una única instrucción:

#!/bin/bash
mysqldump --user=root --password=pwddelroot --all-databases > /ruta-de-la/copia/todotodotodo.sql

Por último si queremos tener un fichero por cada una de las bases de datos y para cada día, también podemos realizarlo de esta manera más elegante.

#! /bin/bash 
TIMESTAMP=$(date +"%F")
BACKUP_DIR="/ruta-de-la/copia/$TIMESTAMP"
MYSQL_USER="root"
MYSQL=/usr/bin/mysql
MYSQL_PASSWORD="passwordroot"
MYSQLDUMP=/usr/bin/mysqldump
 
mkdir -p "$BACKUP_DIR/mysql"
 
databases=`$MYSQL --user=$MYSQL_USER -p$MYSQL_PASSWORD -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema)"`
 
for db in $databases; do
  $MYSQLDUMP --force --opt --user=$MYSQL_USER -p$MYSQL_PASSWORD --databases $db | gzip > "$BACKUP_DIR/mysql/$db.gz"
done

Comprimir archivos

Luego para ahorrar espacio y hacer que la transmisión sea más rápida ahorrando ancho de banda, comprimiremos dichos archivos.

#!/bin/bash
tar cvzf /ruta-de-la/copia/CopiaTotal.tgz /ruta-de-la/copia/

Si queremos más compresión a cambio de más procesador para comprimir y descomprimir podemos utilizar el algoritmo bz2 (tar.bz2=tbz=tb2):

#!/bin/bash
tar cvfj /ruta-de-la/copia/CopiaTotal.tar.bz2 /ruta-de-la/copia/

Ahora enviamos los archivos:

rsync -avzh --rsh="/usr/bin/sshpass -p claveusuarioremoto ssh -l usuarioremoto" /ruta-de-la/copia/*  ip-maquina-remota:/ruta-del/backup

 

Restaurar base de datos

mysql --user=nombreusuerbbdd --password=pwduserbbdd nombre_bbdd < /ruta-de-la/copia/archivo_dump.SQL