Páginas

martes, 15 de abril de 2025

Script sh Replicar Instantáneas de Conjunto de Datos ZFS desde Servidor FreeBSD Local a otra Máquina FreeBSD Externa

Fuente:

https://www.iceflatline.com/2015/07/using-zfs-replication-features-in-freebsd-to-improve-my-offsite-backups/

El autor de este sencillo e ingenioso guión es iceflatline. Contiene algunas modificaciones para adaptarlo a este laboratorio

https://gnulinuxcodigo.blogspot.com/2025/03/crear-particiones-en-disco-duro-usb-con.html

Conjuntos de datos zbackup

carlos@tormenta:~ % zfs list -r zbackup | grep "/zbackup*"
zbackup                            48.9G  1.71T  4.86M  /zbackup
zbackup/solaris                    40.8G  1.71T    96K  /zbackup/solaris
zbackup/solaris/home               40.8G  1.71T    96K  /zbackup/home
zbackup/solaris/home/carlos        40.8G  1.71T  39.9G  /zbackup/home/carlos
zbackup/tormenta-confiles           800K  1.71T   800K  /zbackup/tormenta-confiles
zbackup/usr                        8.16G  1.71T   104K  /zbackup/usr
zbackup/usr/backup                 7.80G  1.71T   104K  /zbackup/usr/backup
zbackup/usr/backup/docs            7.80G  1.71T  7.80G  /zbackup/usr/backup/docs
zbackup/usr/home                    368M  1.71T   132M  /zbackup/usr/home
#!/bin/sh 
### BEGIN INFO
# PROVIDE: 
# REQUIRE: 
# KEYWORD: 
# Description:	
# This script is used to replicate incremental zfs snapshots daily from one 
# pool/dataset(s) to another using ZFS send and receive. 
# The number of snapshots to retain is defined in the variable retention.
# Note that an initial full snapshot must be created and sent to destination 
# before this script can be successfully used. 
# Author: iceflatline <iceflatline@gmail.com>
#
# OPTIONS:
# -R: Generate replication stream recursively
# -i: Generate incremental stream
# -v: Be verbose
# -u: Do not mount received stream,
# -d: Use the full sent snapshot path without the first element (without pool 
# name) to determine the name of the new snapshot
# -F: Destroy snapshots and file systems that do not exist on the sending side. 
### END INFO
 
### INICIO DEL GUION

# Estas variables se nombran primero porque están anidadas en otras variables. 
snap_prefix=snap 
retention=30
 
# Se necesitan rutas completas a estas utilidades al ejecutar el script desde 
# cron.
date=/bin/date
grep=/usr/bin/grep
sed=/usr/bin/sed
sort=/usr/bin/sort
xargs=/usr/bin/xargs
zfs=/sbin/zfs

src_0="zroot/home"
dst_0="zbackup/solaris"
host="root@192.168.88.160"
today="$snap_prefix-`date +%Y%m%d`"
yesterday="$snap_prefix-`date -v -1d +%Y%m%d`"
snap_today="$src_0@$today"
snap_yesterday="$src_0@$yesterday"
snap_old=`$zfs list -t snapshot -o name | $grep "$src_0@$snap_prefix-*" | \
$sort -r | $sed 1,${retention}d | $sort | $xargs -n 1`
log=/home/carlos/cronlog

# snap_old_dst_0 lista las instantaneas > retention en el pool destino zbackup
dst_0_old="zbackup/solaris"
snap_old_dst_0=`ssh $host $zfs list -t snapshot -o name | \
$grep "$dst_0_old@$snap_prefix*" | $sort -r | $sed 1,${retention}d | $sort \
| $xargs -n 1`


# Crea una línea en blanco entre la entrada de registro anterior y esta
echo >> $log
 
# Imprimir el nombre del script.
echo "zfsrep.sh" >> $log

# Imprime la fecha de hoy
$date >> $log

# Crea una linea en blanco
echo >> $log
 
# Busca la instantánea de hoy y, si no la encuentras, créala.
if $zfs list -H -o name -t snapshot | $sort | $grep "$snap_today$" > \
/dev/null
then
	echo "La instantánea de hoy '$snap_today' ya existe." >> $log
	
else
	echo "Tomando la instantánea de hoy: $snap_today" >> $log
	$zfs snapshot -r $snap_today >> $log 2>&1
fi
 
echo >> $log

# Busque la instantánea de ayer y, si la encuentra, realice una replicación 
# incremental; de lo contrario, imprima un mensaje de error
if $zfs list -H -o name -t snapshot | $sort | $grep "$snap_yesterday$" > \
/dev/null 
then
	echo "La instantánea de ayer '$snap_yesterday' existe. Continuando con 
    # la replicacion..." >> $log
	$zfs send -R -i $snap_yesterday $snap_today | ssh $host $zfs receive \
    -vudF $dst_0 >> $log 2>&1
	 
	echo >> $log
 	echo "Replicacion completada." >> $log
else
	echo "Error: Replicacion no completada. Falta la instantánea de ayer." \
    >> $log
fi
 
echo >> $log
 
# Eliminar instantáneas más antiguas que el valor asignado a retention.
echo "Intentando destruir instantáneas antiguas $src_0..." >> $log
 
if [ -n "$snap_old" ]
then
	echo "Destruyendo las siguientes instantáneas antiguas:" >> $log
	echo "$snap_old" >> $log
	$zfs list -t snapshot -o name | $grep "$src_0@$snap_prefix*" | \
    $sort -r | $sed 1,${retention}d | $sort | $xargs -n 1 $zfs destroy -r >> \
    $log 2>&1
else
    echo "No se pudo encontrar ninguna instantánea para destruir." >> $log
fi

echo >> $log

# Eliminar instantáneas más antiguas que el valor asignado a retention.
echo "Intentando destruir instantáneas antiguas $dst_0..." >> $log
 
if [ -n "$snap_old_dst_0" ]
then
	snap_remoto="zbackup/solaris/home"
	echo "Destruyendo las siguientes instantáneas antiguas:" >> $log
	echo "$snap_old_dst_0" >> $log
	ssh $host $zfs list -t snapshot -o name | $grep \
    "$snap_remoto@$snap_prefix-*" | $sort -r | $sed 1,${retention}d | \
    $sort | $xargs -n 1 $zfs destroy -r >> $log 2>&1
else
    echo "No se pudo encontrar ninguna instantánea para destruir." >> $log
fi

# Marcar el fin del script con un delimitador.
echo "**********" >> $log
 
### FIN DEL SCRIPT

Luego, agregue una tarea a la tabla cron bajo la cuenta del usuario. El script se ejecuta todos los días a las 22:00 (hora local):

# Ejecuta script backup cada día a las 22:00
0 22 * * * /home/carlos/bin/zfsrep.sh

Las entradas del archivo /home/carlos/cronlog se verán así:

**********

zfsrep.sh
Tue Apr 15 09:45:19 CEST 2025

Tomando la instantánea de hoy: zroot/home@snap-20250415

La instantánea de ayer 'zroot/home@snap-20250414' existe. Continuando con la replicacion...
receiving incremental stream of zroot/home@snap-20250415 into zbackup/solaris/home@snap-20250415
received 312B stream in 0.91 seconds (341B/sec)
receiving incremental stream of zroot/home/carlos@snap-20250415 into zbackup/solaris/home/carlos@snap-20250415
received 16.3M stream in 7.07 seconds (2.30M/sec)

Replicacion completada.

Intentando destruir instantáneas antiguas zroot/home...
Destruyendo las siguientes instantáneas antiguas:
zroot/home@snap-20250327

Intentando destruir instantáneas antiguas zbackup/solaris...
No se pudo encontrar ninguna instantánea para destruir.
FreeBSD es genial!.

No hay comentarios:

Publicar un comentario