Esta es LA manera de hacerlo con máquinas de verdad (Linux)
Bueno, gracias a mi actual laburo pude conocer a la enorme rsnapshot. Hoy quiero compartirla por acá con su finalidad básica. Otro día voy a mostrar la aplicación que di para casos remotos.
Es extremadamente simple en base, pero permite poder hacer setups más complejos a gusto y está disponible en prácticamente cualquier OS, eso lo hace tan bueno. En resumen, sirve para hacer backups incrementales (como snapshots), por lo que tendremos historial de cambios con las intervalos que configuremos.
Igual, acá viene lo más groso.. Para ver donde brilla, se requiere conocer lo básico de como funcionan los archivos.
rsnapshot depende de rsync (para sincronizar los datos) y de cron (para automatizarlo), otras dos enormes herramientas. Su detalle más interesante es que aprovecha los hard-links de UNIX, cosa que personalmente desconocía hasta antes de este software.
Los hard-links permiten crear un archivo que apunta a los sectores del filesystem donde se guardan los datos de otro archivo, en lugar de su ruta human-readable con la que interactuamos a diario.
De esta forma en lugar de duplicar esos datos, se crea una referencia más a los mismos ya existentes en algún lugar del disco. Y estos datos solo se eliminan definitivamente cuando ya no existen más referencias (más hard-links) hacia ellos.
Básicamente, si lo pensamos, todo archivo “común” de por sí ya es un hard-link… Y si la ves, podrás imaginarte por donde viene la mano.. Sino, te cuento.
Así, resulta enorme la reducción de potencial espacio ocupado.
Lo que hace rsnapshot en Perl, es muy, muy simple. Prácticamente, hablamos de scripts:
- Utiliza
rsyncpara sincronizar las diferencias actuales contra el último snapshot. - Y luego, cuando termina, rota los directorios correspondientes.
En resumen como puntos clave:
- Para poder hacer nuestros snapshots, necesitaremos libre; el peso de lo que queremos backupear, más un mínimo overhead de los hard-links y los cambios reales en los datos.
- Los hard-links tienen peso despreciable comparado a duplicar datos; deberemos estar atentos también a los inodos disponibles
- No es lo más óptimo para archivos muy grandes (e.g., máquinas virtuales, respaldos de bases de datos, etc,.)
- Vamos a configurarlo con
sync_first 1ylink_dest 0. Más adelante lo detallo. - Ideal y minimamente deberíamos hacerlo en otro disco.
0. Instalar dependencias
Fijate como conseguirlo para tu distro/OS. En Debian/Devuan (13+), es simplemente:
apt install rsnapshot
Eso ya va a pedir por su cuenta rsync. Y cron viene instalado.
1. Configuración de rsnapshot
Abramos el archivo de config default: "vim /etc/rsnapshot.conf"
Importante: NO SEPARAR CON LA BARRA ESPACIADORA, SINO CON TABULACIONES
De lo contrario, tendremos errores y no correrá el programa.
Variables importantes a cambiar
Con las mismas notas del archivo y el manpage, hay mucha cosa para chusmear y tocar, sea libre de probar y hacer lo que quiera. Pero yo planteo lo siguiente sí o sí:
- La primera es
snapshot_root: donde quieras guardar los snapshots.
Importante: Para esto hay que tener en cuenta quién es el owner del directorio. Ese usuario tiene que poder leer la conf de rsnapshot y escribir en el directorio que designemos acá.
-
Justo la siguiente,
no_create_root: cambiémosla a “1”, para evitar que se cree el directorio raíz si no es encontrado. Esto nos puede ahorrar muchos dolores de cabeza si justo no estaba montada la unidad donde realmente queremos hacer la ejecución. -
Seguimos para abajo hasta la sección de intervalos. Que por defecto ahora plantea “alpha, beta, gamma”, para poder abstraerse del calendario, ya que no necesariamente tiene que depender de reglas como “hora, dia, semana, mes” para la ejecución y orden.
Pero por lógica, pragmatismo para ajustarlo al calendario, lo planteo así:
retain hourly 6
retain daily 7
retain weekly 4
retain monthly 3
El número del intervalo solo define cuantas snapshots máximas vamos a guardar de ese grupo. Cómo y cuando rotan viene luego. Sigamos con los últimos detalles.
-
Para el primer mencionado antes,
sync_first: esto me parece indispensable activarlo, lo cual nos va a sumar algo más en el cronjob. Pero que permite que podamos cortar el proceso de sincronización, sin cagar los enlaces de nuestro backup, y evitando posibles duplicaciones indeseadas. -
Y para el último mencionado antes,
link_dest: tampoco puede faltar, ya que hace que los hard-links los manejersyncen lugar decp, que resulta más fiable en general. Maneja distinto el movimiento, ya que siempre deja enlaces en el directorio .sync. -
También me gusta habilitar el
use_lazy_deletes: así antes de eliminar el directorio que le corresponde lo renombra con el PID. -
Finalmente, nos quedan las cosas que querramos backupear. Vale volver a aclarar que para todas estas líneas por favor separen con tabulaciones, no con espacios.
Por ejemplo, para incluir /etc/ tal como está a la raíz de la ruta de snapshot:
backup /etc/ ./
Y si quisiéramos traer /root/ con otro destino:
backup /root/ ./rootdata/
Como última yapa, podemos usar backup_script para correr scripts que saquen data al $PWD. Estos, se van a ejecutar en un directorio “tmp” de la raíz de snapshots. Y cuando termine, lo renombrará como lo indicamos en la conf:
backup_script /scripts/mysql_backup.sh ./mysqldb/
Así se ve lo que hace backup_script durante el sync, paso por paso:
[2026-08-01T20:01:35] mkdir -m 0755 -p /backup/tmp/
[2026-08-01T20:01:35] cd /backup/tmp/
[2026-08-01T20:01:35] /scripts/mysql_backup.sh
[2026-08-01T20:01:37] cd /backup/
[2026-08-01T20:01:37] /bin/cp -al /backup/hourly.0//mysqldb /backup/.sync//mysqldb
[2026-08-01T20:01:37] sync_if_different("/backup/tmp/", "/backup/.sync//mysqldb/")
[2026-08-01T20:01:37] /bin/rm -rf /backup/tmp/
2. Soltar la correa
rsnapshot puede usarse a mano, sin depender de cron. Pero el chiste está en automatizarlo, así que nos falta esa parte.
Un importante detalle de cómo se usa es que tenemos que correr los intervalos, del más “viejo” al más nuevo.
Pensemos así la rotación:
1. Primero se rota el mensual, para asegurar convertirlo desde el último semanal.
2. Luego se rota al semanal, para asegurar convertirlo desde el último diario.
3. Penúltimo se rota al diario, para asegurar convertirlo desde el último cada hora.
4. Finalmente se sincroniza y después se rota al de cada hora, para asegurar la instancia más reciente con los cambios que acabamos de sincronizar.
Ahora veamos por partes un log para que se entienda:
Mensual:
[2026-08-01T00:00:01] /usr/bin/rsnapshot -c /etc/rsnapshot.conf monthly: started
[2026-08-01T00:00:01] echo 37775 > /var/run/rsnapshot.pid
[2026-08-01T00:00:01] mv /backup/monthly.2/ /backup/_delete.37775
[2026-08-01T00:00:01] mv /backup/monthly.1/ /backup/monthly.2/
[2026-08-01T00:00:01] mv /backup/monthly.0/ /backup/monthly.1/
[2026-08-01T00:00:01] mv /backup/weekly.3/ /backup/monthly.0/
[2026-08-01T00:00:01] rm -f /var/run/rsnapshot.pid
[2026-08-01T00:00:01] /bin/rm -rf /backup/_delete.37775
[2026-08-01T00:04:06] /usr/bin/rsnapshot -c /etc/rsnapshot.conf monthly: completed successfully
Semanal:
[2026-08-01T00:10:00] /usr/bin/rsnapshot -c /etc/rsnapshot.conf weekly: started
[2026-08-01T00:10:00] echo 35260 > /var/run/rsnapshot.pid
[2026-08-01T00:10:00] mv /backup/weekly.2/ /backup/_delete.35260
[2026-08-01T00:10:00] mv /backup/weekly.1/ /backup/weekly.2/
[2026-08-01T00:10:00] mv /backup/weekly.0/ /backup/weekly.1/
[2026-08-01T00:10:00] mv /backup/daily.6/ /backup/weekly.0/
[2026-08-01T00:10:00] rm -f /var/run/rsnapshot.pid
[2026-08-01T00:10:01] /bin/rm -rf /backup/_delete.35260
[2026-08-01T00:12:22] /usr/bin/rsnapshot -c /etc/rsnapshot.conf weekly: completed successfully
Diario:
[2026-08-01T00:20:01] /usr/bin/rsnapshot -c /etc/rsnapshot.conf daily: started
[2026-08-01T00:20:01] echo 50073 > /var/run/rsnapshot.pid
[2026-08-01T00:20:01] mv /backup/daily.6/ /backup/_delete.50073/
[2026-08-01T00:20:01] mv /backup/daily.5/ /backup/daily.6/
[2026-08-01T00:20:01] mv /backup/daily.4/ /backup/daily.5/
[2026-08-01T00:20:01] mv /backup/daily.3/ /backup/daily.4/
[2026-08-01T00:20:01] mv /backup/daily.2/ /backup/daily.3/
[2026-08-01T00:20:01] mv /backup/daily.1/ /backup/daily.2/
[2026-08-01T00:20:01] mv /backup/daily.0/ /backup/daily.1/
[2026-08-01T00:20:01] mv /backup/hourly.5/ /backup/daily.0/
[2026-08-01T00:20:01] rm -f /var/run/rsnapshot.pid
[2026-08-01T00:20:01] /bin/rm -rf /backup/_delete.50073
[2026-08-01T00:21:28] /usr/bin/rsnapshot -c /etc/rsnapshot.conf daily: completed successfully
Sync antes de cada hora:
[2026-08-01T02:00:01] /usr/bin/rsnapshot -c /etc/rsnapshot.conf sync: started
[2026-08-01T02:00:01] echo 56230 > /var/run/rsnapshot.pid
[2026-08-01T02:00:01] mkdir -m 0755 -p /backup/.sync/
[2026-08-01T02:00:01] /usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded --link-dest=/backup/hourly.0// /root/ /backup/.sync//
[2026-08-01T02:01:23] /usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded --link-dest=/backup/hourly.0// /etc/ /backup/.sync//
[2026-08-01T02:01:25] touch /backup/.sync/
[2026-08-01T02:01:25] rm -f /var/run/rsnapshot.pid
[2026-08-01T02:01:25] /usr/bin/rsnapshot -c /etc/rsnapshot.conf sync: completed successfully
Cada hora:
[2026-08-01T02:01:25] /usr/bin/rsnapshot -c /etc/rsnapshot.conf hourly: started
[2026-08-01T02:01:25] echo 57923 > /var/run/rsnapshot.pid
[2026-08-01T02:01:25] mv /backup/hourly.5/ /backup/_delete.57923
[2026-08-01T02:01:25] mv /backup/hourly.4/ /backup/hourly.5/
[2026-08-01T02:01:25] mv /backup/hourly.3/ /backup/hourly.4/
[2026-08-01T02:01:25] mv /backup/hourly.2/ /backup/hourly.3/
[2026-08-01T02:01:25] mv /backup/hourly.1/ /backup/hourly.2/
[2026-08-01T02:01:25] mv /backup/hourly.0/ /backup/hourly.1/
[2026-08-01T02:01:25] mv /backup/.sync/ /backup/hourly.0/
[2026-08-01T02:01:25] rm -f /var/run/rsnapshot.pid
[2026-08-01T02:01:25] /bin/rm -rf /backup/_delete.57923
[2026-08-01T02:01:50] /usr/bin/rsnapshot -c /etc/rsnapshot.conf hourly: completed successfully
Se hace desde atrás para adelante, para que se cumplan los tiempos que nosotros queremos entre los intervalos.
Si no usáramos el sync_first habilitado, no nos haría falta hacer el "/usr/bin/rsnapshot sync" antes del "/usr/bin/rsnapshot hourly", ya que normalmente solo corriendo cada intervalo, primero sincroniza y luego rota. Como ya comenté anteriormente, esto posibilita que se nos pueda romper la conexión de los intervalos del backup, que terminemos duplicando datos, y terminemos con un disco lleno…
Para el ejemplo de lo que vimos antes, pondremos los siguientes jobs en "/etc/cron.d/rsnapshot"
0 */2 * * * root /usr/bin/rsnapshot sync; /usr/bin/rsnapshot hourly
20 0 * * * root /usr/bin/rsnapshot daily
10 0 * * 6 root /usr/bin/rsnapshot weekly
0 0 1 * * root /usr/bin/rsnapshot monthly
Importante: Hay que dejar una línea vacía debajo de la línea mensual, para que cron lea bien el archivo
Para poder entender y ajustar a gusto estos cronjobs, recomiendo: https://crontab.guru
Bueno, finalmente reiniciamos el servicio: "systemctl restart cron" o, si sos chad, "/etc/init.d/cron restart"
Y listo! Podés monitorear el log luego de las horas configuradas.
Así, es como se hacen backups en serio.
>> Inicio