En un anterior artículo comenté sobre el método para realizar backups eficientes con el uso de ZFS + compresión + snapshots + rsync sobre FreeBSD. En esta entrada os dejo una versión simplificada de uno de los scripts que utilizo para realizar los backups. Con algunas modificaciones podéis adaptarlo fácilmente a vuestra infraestructura obteniendo la lista de servidores y directorios/ficheros a excluir de una base de datos por ejemplo.
La compresión que se utilizará en cada dataset para cada servidor será heredado del dataset padre que dedicarás a los backups.
El script crea un snapshot por cada día de la semana que irán rotando, igualmente crea un snapshot para cada día 1 de cada mes, la rotación en este caso será anual.
La entrada «cron» puede ser similar a la siguiente para obtener en fichero log del resultado que se guarda en el propio servidor de backup:
0 2 * * * /usr/home/backups/scripts/rsync-external-servers.sh &>> /home/backups/logs/`date +\%Y\%m\%d`-external-rsync.log
El script:
#!/usr/local/bin/bash
mydir="$(dirname "$0")"
# srv list: [email protected]@[email protected]|exclude2|exclude3|...
# Examples:
ARR="[email protected]/@[email protected]/home/user1
[email protected]/var/lib/lxd/storage-pools/zlxd/containers/testvps1/rootfs/@[email protected]/home/user1|/home/user2
[email protected]/var/lib/lxd/storage-pools/zlxd/containers/testvps2/rootfs/@[email protected]/home/user1|/home/user2
[email protected]/iocell/jails/2a4e3ea4/root/@[email protected]/home/jl1|/usr/ports
[email protected]/@aws34.indeax.com
[email protected]/@[email protected]/home/bindmountdata|/var/hugetempdata
"
# Data
emailalert="[email protected]"
SSHKEY="$mydir/keys/backup"
LOCALDIR="/usr/home/backups/vps"
USER="root"
ZPOOL="backup/backups/vps"
CIPHER="aes128-ctr"
# RSYNC general command
MYRSYNC="/usr/local/bin/rsync --stats -e \"ssh -i $SSHKEY -c '$CIPHER' -q -x\" -a --numeric-ids -H --delete \
"
# Shared exclude for all rsync
EXCLUDE='--exclude "catalog/product/cache" --exclude "var/po_fpc/" --exclude "media/tmp" --exclude "var/session/" --exclude "var/cache/" \
--exclude "var/report/" --exclude "var/export/" --exclude "/proc" --exclude "/sys" --exclude "/dev" --exclude "/tmp" --exclude "cache/smarty" \
'
##########################################################################
# bucle start
FECHA=`date "+%Y-%m-%d %T"`
DIA=`date +%u`
echo "#########################################################"
echo "## INI: $FECHA"
echo
for LIN in $ARR; do
# get data from string
IFS='@';
ar1=($LIN)
SRV=${ar1[0]} # server
SOURCE=${ar1[1]} # source
DESDIR=${ar1[2]} # source
EXCstr=${ar1[3]} # exclude string
# zfs and backup paths
DIRBK=${LOCALDIR}/${DESDIR}
ZFSNAME=${ZPOOL}/${DESDIR}
# create dataset if not exist
zfs list $ZFSNAME &> /dev/null
if [[ $? != 0 ]]; then zfs create -p ${ZFSNAME}; fi
# create snapshots
zfs destroy ${ZFSNAME}@dow${DIA}
zfs snapshot ${ZFSNAME}@dow${DIA}
DAYOM=`date "+%d"`
MONOY=`date "+%m"`
if [[ $DAYOM = '01' ]]; then
zfs destroy ${ZFSNAME}@dom${MONOY}${DAYOM}
zfs snapshot ${ZFSNAME}@dom${MONOY}${DAYOM}
fi
# INI backup
FECHA=`date "+%Y-%m-%d %T"`
echo "------------------------"
echo "## INI Servidor: $FECHA -- $SRV: $SOURCE - $EXCstr"
# get excludes for server
IFS='|'; EXC2=""
for EXCL in $EXCstr; do
EXC2="$EXC2 --exclude '$EXCL'"
done
COMMAND="$MYRSYNC $EXCLUDE $EXC2 [email protected]$SRV:$SOURCE ${DIRBK}"
echo "Doing backup..."
echo $COMMAND
MYOUT=$(eval $COMMAND 2>&1)
s="$?"
# Check if backup was done correctly
if [[ ! $s -eq 0 && ! $s -eq 23 && ! $s -eq 24 ]]; then
echo "Error rsync ($s)"
printf "Error rsync ($s) $SRV $SOURCE $FECHA\n$MYOUT" | mail -s "BACKUP ERROR: $SRV $SOURCE $FECHA" $emailalert
fi
echo "OUTPUT: $MYOUT"
FECHA=`date "+%Y-%m-%d %T"`
echo "### FIN: $FECHA"
echo
done
FECHA=`date "+%Y-%m-%d %T"`
echo
echo "----------------------------"
echo "## FIN: $FECHA"
echo