Páginas

Mostrando entradas con la etiqueta sh. Mostrar todas las entradas
Mostrando entradas con la etiqueta sh. Mostrar todas las entradas

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!.