TAR y los backups incrementales en GNU/Linux

Publicado por Diego Córdoba en

Veremos cómo utilizar la conocida herramienta de empaquetamiento tar para realizar backups incrementales, y por supuesto, cómo restaurarlos.

Motivación

El comando tar permite empaquetar y comprimir un archivo o serie de archivos, incluso hasta el sistema de archivos completo. Los formatos de compresión más utilizados y soportados por tar son gzip, bzip2, xz, o lzma.

Supongamos que tenemos un directorio en un servidor, y queremos realizar un backup diario del mismo, podríamos ejecutar algo así:

tar -cvzf /tmp/backup.tgz /ruta/al/directorio/en/cuestion

Donde:

  • -c permite crear el archivo.
  • -v es el modo «verbose» o explicativo, para ver lo que se está metiendo dentro del tarball.
  • -z para comprimir con gzip el backup (comprime bastante, y no consume demasiado tiempo de procesamiento. Igualmente podemos usar -j para bzip2, -J para XZ, etc.
  • -f para indicar que el archivo empaquetado y comprimido a crear será el especificado a continuación.

Esto muy bonito, pero si el directorio «pesa» 100 GiB, tendremos un archivo de unos cuantos GiB comprimidos por día, y seguramente la mayoría de los datos no hayan cambiado de un día al siguiente. Es decir, de de hoy para mañana puede que solamente una porción pequeña de esos datos se haya modificado.

¿No sería mejor, entonces, realizar un backup diario «solo de las diferencias» con el backup anterior?

Esto reduciría considerablemente el tamaño de los backups diarios, al realizar copias de seguridad sólo de las diferencias. Es lo que nos trae hoy a este artículo 🙂

Backups incrementales

Un backup incremental es aquel que almacena solamente las diferencias con respecto al backup anterior.

No entraremos en detalle sobre los tipos y políticas de backup que sean más convenientes en cada caso. Solamente hablaremos de qué es un backup incremental, y cómo crearlo y restaurarlo mediante tar.

Imaginemos que hacemos un backup completo el domingo, podríamos hacer el lunes un backup solamente de las diferencias respecto del domingo, y el martes solamente de las diferencias respecto del lunes, y así hasta el sábado. Al siguiente domingo podríamos hacer un backup completo nuevamente, y repetir el ciclo.

La longitud del ciclo depende de, creo yo, de la fiabilidad con la que podamos recuperar cada incremento para restaurar. Es decir, podríamos también hacer dos backups completos por mes, y el resto 15 días aproximadamente de incrementos.

Hay que considerar que para restaurar un backup hasta un día determinado debemos primero restaurar el backup completo, y luego todos los incrementales sucesivos. Por ejemplo, tomamos la política del backup completo del domingo, y el miércoles se rompió el disco, podríamos restaurar el backup del domingo, y los incrementales de lunes y martes para tener la información completa hasta el día anterior.

Backups incrementales con tar

Tar posee dos opciones que nos van a servir para trabajar con backups incrementales:

  • «--listed-incremental=file«, o «-g file«, que permite especificar un archivo de snapshot incremental.
  • «--incremental» o «-G«, que permite analizar un backup incremental y saber qué archivos del total están presentes en dicho backup.

El archivo de snapshot incremental almacenará metadatos que ayudará a la herramienta tar a determinar qué archivos han cambiado desde el último incremental, cuáles se han agregado, o cuales se han eliminado, de modo que tar podrá generar el siguiente backup incremental solamente de los cambios del anterior.

Veamos un ejemplo

He montado un pequeño directorio para ejemplificar el uso de backups incrementales de varios niveles.

Supongamos que tenemos un directorio llamado data en el que existen dos archivos, file1 y file2, cada uno con su contenido («hola» y «mundo» respectivamente en mi caso, como para no perder la costumbre 😛 ). y necesitamos realizar un backup completo dentro del directorio backup, con sus correspondientes backups incrementales de cambios:

tar gzip bzip2 lzma xz backup incremental snar snapshot

Creemos ahora el backup nivel 0, el primero, completo, dentro del directorio backup/ con el siguiente comando:

tar -cvzf backup/bkp0.tgz -g backup/snapshot.snar data/
tar gzip bzip2 lzma xz backup incremental snar snapshot

Como puede verse, nos ha creado, dentro del directorio backup, un archivo bkp0.tgz, el backup completo, y un archivo snapshot.snar, con metadatos de las diferencias para los siguientes backups.

Supongamos ahora que realizamos el backup incremental del siguiente día. Vamos a suponer que no se modifica nada… veamos qué ocurre. Llamémosle, bkp1.tgz al primer nivel de backup incremental:

tar -cvzf backup/bkp1.tgz -g backup/snapshot.snar data/
tar gzip bzip2 lzma xz backup incremental snar snapshot

Como nos muestra al ejecutar el comando tar, solamente se ha agregado el directorio data/ vacío al backup, puesto que no hay modificaciones en los archivos. Recordemos que el backup incremental del punto anterior agregó el directorio data/ y los archivos que contenía: file1 y file2.

Es importante aclarar en esta instancia que, si en un futuro necesitamos realizar un backup incremental que parte del mismo incremento anterior, es decir, por ejemplo, un backup nivel 1 y luego otro backup nivel 1, será necesario copiar con otro nombre el archivo de snapshot, puesto que de realizar un backup nivel 2 sobreescribirá el archivo snapshot y se perderán los cambios del nivel anterior.

Ahora vamos a modificar el archivo file1, por ejemplo, cambiando su contenido, y vamos a realizar el segundo nivel de backup: bkp2.tgz:

tar -cvzf backup/bkp2.tgz -g backup/snapshot.snar data/
tar gzip bzip2 lzma xz backup incremental snar snapshot

Se ha creado el archivo bkp2.tgz, cuyo contenido, como se puede ver, es solamente el archivo file1.

Hagamos lo mismo nuevamente, pero ahora modificando el archivo file2 y creando el siguiente nivel de backup:

tar gzip bzip2 lzma xz backup incremental snar snapshot

Como se ve, solo se agregó el segundo archivo. Repitamos el proceso modificando los dos archivos antes del backup:

tar gzip bzip2 lzma xz backup incremental snar snapshot

Ahora se han agregado los dos archivos, puesto que los dos han cambiado.

Analizando los backups…

Veamos, antes de proceder a restaurar todo, cómo podemos analizar qué contiene cada backup incremental.

Esto podemos llevarlo a cabo mediante la opción «--incremental« del comando tar, a la que debemos también agregar dos modificadores «--verbose« para ver la información completa. En mi caso he usado «-G« en vez de «--incremental«, y «-vv» en vez de «--verbose --verbose«:

Veamos el contenido de cada uno de los backups:

tar gzip bzip2 lzma xz backup incremental snar snapshot

Como puede verse, delante de cada nombre de archivo tenemos un «Y» o un «N». «Y» significa que el archivo está presente en dicho backup, y «N» que no lo está. El resultado es consistente con los cambios que hemos realizado sobre los archivos.

Y finalmente… restaurando

Supongamos ahora que perdemos todos los datos y que necesitamos recuperarlos desde el backup completo y los incrementales.

Para extraer todos los archivos en el mismo estado exacto en el que estaban a la hora de realizar el último backup incremental, debemos usar la opción «--extract« o «-x« junto con la opción «--listed-incremental«. Como la información de backup incremental está almacenada dentro del tarball, es decir, el tarball contiene solo los cambios respecto del último incremental, puede pasarse cualquier argumento al «--listed-incremental« o «-g«. Usualmente se utiliza /dev/null, o se usa directamente «--incremental« o «-G«.

Suponiendo que el directorio data no existe, vamos a proceder a restaurar todos los backups, desde el primero, completo, uno a uno hasta el último incremental disponible, para regenerar el directorio original y su contenido:

tar gzip bzip2 lzma xz backup incremental snar snapshot

Como puede verse, hemos restaurado paso por paso todos los backups que antes hicimos, y ahora tenemos dentro del directorio data/ toda la información de nuevo! Y sí, los archivos tienen el contenido original modificado tal y como quedaron en el último backup incremental:

tar gzip bzip2 lzma xz backup incremental snar snapshot

Conclusiones

Hemos aprendido a hacer backups incrementales con tar, y a restaurarlos para recuperar la información perdida.

Hemos realizado las practicas con backups comprimidos con gzip, pero el comportamiento es exactamente el mismo al utilizar bzip2, xz, lmza o cualquier otro formato soportado.

Esto podría combinarse otras herramientas para mover estos backups a otro medio, tal y como explicamos en https://juncotic.com/megafuse-realizando-backups-mega-linux/, o a un dispositivo externo, y por supuesto, puede programarse un script que, por ejemplo, genere los backups incrementales con un número de incremento y una fecha de creación que luego facilite la identificación.

Para otras opciones y usos de tar con otros dispositivos les recomiendo visitar el sitio oficial de documentación dentro del proyecto GNU:

https://www.gnu.org/software/tar/manual/html_node/index.html#SEC_Top

Espero que este contenido sea de utilidad! Y ya saben, si tienen alguna sugerencia que pueda agregarse al script no tienen mas que escribir aquí debajo, en la sección de comentarios, así queda documentado para todos! Gracias y hasta la próxima!


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!


Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador