1. Qué es un respaldo
Un respaldo o copia de seguridad es una copia de los datos, guardada aparte y conservada en el tiempo, que permite recuperarlos tal como estaban en un momento anterior. Las dos últimas condiciones son las que importan: una copia en el mismo disco no sobrevive a su falla, y una copia que siempre refleja el estado actual no sirve para volver atrás.
Por eso hay cosas que parecen respaldos y no lo son. Un disco en espejo (RAID) protege de que un disco se rompa, pero si se borra un archivo, se borra en los dos al mismo tiempo. Una carpeta sincronizada con un servicio en la nube copia también los errores: si un programa cifra tus documentos, la sincronización sube con diligencia las versiones cifradas. Un respaldo de verdad conserva varias versiones del pasado, y al menos una de ellas fuera del alcance de lo que pueda pasarle al original.
Una regla práctica muy difundida es la 3-2-1: tres copias de los datos, contando el original; en dos medios distintos, como el disco del equipo y un disco externo; y una de ellas en otro lugar físico, como otro edificio o un servidor remoto. Este tema se ocupa de cómo producir las copias; el tema 38, de algo igual de importante: comprobar que sirven para restaurar.
2. Completos, incrementales y diferenciales
Copiar todo cada día es lo más simple, pero ocupa mucho y tarda. Las alternativas copian solo lo que cambió, aunque difieren en respecto de qué:
| Tipo | Copia | Espacio y tiempo | Para restaurar el viernes |
|---|---|---|---|
| Completo | Todo, cada vez. | El máximo. | Solo la copia del viernes. |
| Incremental | Lo que cambió desde la copia anterior, de cualquier tipo. | El mínimo. | El completo del domingo y todos los incrementales hasta el viernes, en orden. |
| Diferencial | Lo que cambió desde el último completo. | Intermedio, y crece con los días. | El completo del domingo y el diferencial del viernes. |
Los incrementales son los más económicos, pero restaurar exige la cadena entera, y si falta un eslabón, lo posterior se pierde. Por eso se combinan con un completo periódico, que corta la cadena: lo habitual es un completo semanal o mensual e incrementales diarios. Las instantáneas de rsync de la sección 7 ofrecen lo mejor de ambos mundos: cada copia ocupa como un incremental, pero se restaura como un completo.
3. Un respaldo completo con tar
tar reúne un árbol de directorios en un solo archivo, conservando permisos, dueños y fechas, y opcionalmente lo comprime. El curso de Terminal presentó lo básico; en un script de respaldo, la forma típica es esta:
destino=/mnt/copias
archivo="$destino/casa-$(date +%F).tar.gz"
tar --create --gzip --file="$archivo" \
--directory=/home --one-file-system \
--exclude-caches --exclude='ana/.cache' --exclude='*.tmp' \
ana
- La fecha en el nombre, con
date +%F, identifica cada copia y hace que el orden alfabético sea el cronológico, lo que simplifica la rotación. --directory(-C) entra en/homeantes de empezar, de modo que el archivo contieneana/…y no/home/ana/…. Al restaurar, se elige dónde extraer.--one-file-systemno entra en otros sistemas de archivos montados dentro del directorio, como un disco externo o una carpeta de red.--exclude-cachessalta los directorios marcados como caché con un archivoCACHEDIR.TAG, que crean muchos programas;--exclude, los patrones que se indiquen.
La compresión es un equilibrio entre tamaño y tiempo. Para respaldos nocturnos, zstd suele ser la mejor elección, si está disponible:
| Opción | Extensión | Características |
|---|---|---|
--gzip (-z) | .tar.gz | Disponible en todas partes; compresión moderada y rápida. |
--xz (-J) | .tar.xz | La mejor compresión, pero muy lenta. |
--zstd | .tar.zst | Compresión similar a xz rápido, a velocidad mayor que gzip; usa varios procesadores. |
| sin compresión | .tar | Para datos ya comprimidos, como fotos y videos: comprimirlos de nuevo no ahorra nada. |
$ tar --list --file=/mnt/copias/casa-2026-10-15.tar.gz | head -n 3
ana/
ana/documentos/
ana/documentos/informe.odt
$ mkdir /tmp/rescate
$ tar --extract --file=/mnt/copias/casa-2026-10-15.tar.gz --directory=/tmp/rescate ana/documentos/informe.odt
Una buena costumbre al restaurar: extraer en un directorio aparte y desde allí copiar lo que haga falta, en lugar de extraer encima de los datos actuales.
4. Los códigos de salida de tar
GNU tar distingue dos tipos de problema, y en un script con el modo estricto del tema 23 la diferencia importa:
| Código | Significa | Ejemplo |
|---|---|---|
| 0 | Todo bien. | — |
| 1 | Algunos archivos cambiaron mientras se leían. | tar: ana/.local/share/historial: file changed as we read it |
| 2 | Error grave: el respaldo no está completo. | tar: ana/privado: Cannot open: Permission denied |
Respaldar un directorio en uso es casi garantía de que algún archivo cambie durante la copia, y con set -e ese código 1 detendría el script como si fuera un desastre. Lo razonable es tratar el 1 como un aviso y el 2 como un error, con la técnica del tema 10:
codigo=0
tar --create --gzip --file="$archivo" --directory=/home ana || codigo=$?
case "$codigo" in
0) ;;
1) echo "aviso: algunos archivos cambiaron durante la copia" >&2 ;;
*) rm -f -- "$archivo"; echo "error: tar terminó con código $codigo" >&2; exit 1 ;;
esac
Ante un error grave, el archivo a medio escribir se borra, para que nadie lo confunda con un respaldo válido. La sección 9 vuelve sobre esa idea.
5. Incrementales con tar
GNU tar hace respaldos incrementales con la opción --listed-incremental, que recibe un archivo de instantánea (.snar): una lista de los archivos copiados y sus fechas. Si el archivo no existe, tar hace un respaldo completo, llamado de nivel 0, y lo crea; si existe, copia solo lo que cambió desde entonces, y lo actualiza.
$ tar --listed-incremental=copias/datos.snar -czf copias/datos-0.tar.gz datos
# … se modifica notas.txt, se crea agenda.txt y se borra informe.txt
$ tar --listed-incremental=copias/datos.snar -czvf copias/datos-1.tar.gz datos
datos/
datos/fotos/
datos/agenda.txt
datos/notas.txt
El incremental contiene solo los dos archivos que cambiaron, y los directorios, que tar guarda siempre junto con la lista de lo que contenían. Esa lista es la que permite algo que un incremental ingenuo no logra: reproducir los borrados. Para restaurar se extraen todos los niveles en orden, con --listed-incremental=/dev/null, que indica que se trata de un respaldo incremental sin usar ninguna instantánea:
$ mkdir restaurado && cd restaurado
$ tar --listed-incremental=/dev/null -xzf ../copias/datos-0.tar.gz
$ tar --listed-incremental=/dev/null -xzvf ../copias/datos-1.tar.gz
datos/
tar: Deleting 'datos/informe.txt'
datos/fotos/
datos/agenda.txt
datos/notas.txt
El resultado es exactamente el estado del segundo respaldo, con informe.txt eliminado. Como el .snar se actualiza en cada ejecución, usarlo siempre da incrementales. Para obtener diferenciales se guarda una copia del .snar del nivel 0, y cada día se trabaja sobre una copia nueva de él, de modo que todos los días se compara con el completo:
cp -- copias/datos-0.snar copias/hoy.snar # siempre respecto del completo
tar --listed-incremental=copias/hoy.snar -czf "copias/datos-dif-$(date +%F).tar.gz" datos
6. rsync
rsync sincroniza un directorio con otro, local o en otra máquina por SSH. Su gran ventaja es que solo transfiere lo que cambió: compara tamaño y fecha de cada archivo, y de los que cambiaron, solo las partes distintas. La segunda ejecución sobre los mismos datos tarda segundos. Las opciones más usadas en respaldos:
| Opción | Efecto |
|---|---|
-a | Modo archivo: recursivo, y conserva permisos, fechas, enlaces simbólicos, dueños y grupos. |
-H, -A, -X | Conservar además enlaces duros, listas de control de acceso y atributos extendidos. |
--delete | Borrar del destino lo que ya no existe en el origen. |
-n (--dry-run) | Simular: muestra qué haría, sin hacerlo. |
-i (--itemize-changes) | Una línea por cada cambio, con un código que indica qué cambió. |
--exclude=, --exclude-from= | Patrones a excluir, en la línea o en un archivo. |
-R (--relative) | Conservar la ruta completa del origen en el destino: /home/ana se copia como home/ana. |
rsync -a fotos copias/ copia el directorio: el resultado es copias/fotos/…. rsync -a fotos/ copias/ copia su contenido: el resultado es copias/…, sin el directorio. Con --delete, confundirlas puede borrar todo lo que había en copias/. Antes de usar --delete sobre un destino nuevo, ejecuta siempre la misma línea con -n.
$ rsync -an --delete --itemize-changes ~/documentos/ /mnt/copias/documentos/
>f.st...... informe.odt
>f+++++++++ presupuesto-2027.ods
*deleting borrador-viejo.txt
$ rsync -a --delete ~/documentos/ /mnt/copias/documentos/
$ rsync -a --delete ~/documentos/ copias.example.com:/srv/copias/ana/documentos/ # por SSH
En la salida de --itemize-changes, >f indica un archivo que se transfiere; +++++++++, que es nuevo; s y t, que cambiaron su tamaño y su fecha. Como tar, rsync tiene códigos de salida que no son fallos graves: el 24 indica que algunos archivos desaparecieron entre que se listaron y se copiaron, algo normal en un directorio en uso, y el 23, que algunos no se pudieron copiar, que sí merece atención.
Una sincronización con --delete es un espejo, no un respaldo: tiene el problema de la sección 1, porque refleja los borrados y los daños en la siguiente ejecución. La sección siguiente lo convierte en un respaldo con historia.
7. Instantáneas con --link-dest
La opción --link-dest de rsync permite tener una copia completa por día ocupando poco más que los cambios. Funciona con enlaces duros: en Linux, un mismo archivo, es decir, los mismos datos en el disco, puede tener varios nombres en distintos directorios, y sus datos solo se liberan cuando se borra el último de ellos.
Al copiar con --link-dest=DIRECTORIO, rsync compara cada archivo con el que está en ese directorio, normalmente la instantánea de ayer. Si no cambió, en lugar de copiarlo crea un enlace duro al de ayer, que no ocupa espacio; si cambió, lo copia. Cada día se crea un directorio nuevo, completo y navegable, que comparte con los anteriores todo lo que no cambió:
rsync -aH --delete --link-dest=/mnt/copias/2026-10-14 \
/home/ana/ /mnt/copias/2026-10-15/
$ du -sh /mnt/copias/2026-10-1[345]
41G /mnt/copias/2026-10-13
212M /mnt/copias/2026-10-14
198M /mnt/copias/2026-10-15
$ ls -li /mnt/copias/2026-10-1[45]/fotos/playa.jpg
1835017 -rw-r--r-- 21 ana ana 4194304 ago 3 18:20 /mnt/copias/2026-10-14/fotos/playa.jpg
1835017 -rw-r--r-- 21 ana ana 4194304 ago 3 18:20 /mnt/copias/2026-10-15/fotos/playa.jpg
du cuenta cada archivo una sola vez aunque tenga varios nombres, de modo que muestra lo que agrega cada instantánea: la primera ocupa todo, y las siguientes, solo lo que cambió ese día. ls -li confirma que la foto es el mismo archivo en las dos instantáneas: el mismo número de nodo, 1835017, y 21 nombres, uno por cada instantánea en que aparece.
Las ventajas son grandes: para restaurar no hace falta ninguna cadena, porque cada instantánea es completa y basta con copiar desde ella con cp o rsync; y borrar una instantánea vieja es un simple rm -rf, que no afecta a las demás, porque los datos que comparten siguen teniendo otros nombres. Es la técnica que usan herramientas conocidas como rsnapshot, y la del script de este tema. Su límite es que necesita un sistema de archivos de Linux en el destino, que admita enlaces duros, y que un archivo que cambia aunque sea un byte se copia entero.
8. Rotación y retención
Si cada día se agrega un respaldo, el disco de destino terminará lleno. La política de retención decide cuáles conservar, y la rotación borra los demás. La política más simple es conservar los últimos N días, lo que en un directorio de archivos tar se resuelve con find, como en el tema 32:
find /mnt/copias -maxdepth 1 -name 'casa-*.tar.gz' -mtime +30 -delete
Pero treinta días de historia a veces no alcanzan: un archivo que se dañó hace dos meses y nadie lo notó ya no tiene ninguna copia sana. La política más usada, llamada abuelo-padre-hijo, conserva más copias recientes y menos copias antiguas: por ejemplo, las últimas 7 diarias, una por semana de las últimas 4 semanas y una por mes de los últimos 12 meses. Con 20 instantáneas cubre un año entero.
| Instantánea | Se conserva como |
|---|---|
| 2026-10-09 … 2026-10-15 | Diarias: las 7 más recientes. |
| 2026-10-04, 2026-09-27 | Semanales: la más reciente de cada semana anterior (la de esta semana y la pasada ya están entre las diarias). |
| 2026-09-30, 2026-08-31, … 2025-11-30 | Mensuales: la más reciente de cada mes. |
| Todas las demás | Se borran. |
El algoritmo es sencillo con los arrays asociativos del tema 8: se recorren las instantáneas de la más nueva a la más vieja, y cada una se conserva si está entre las primeras D, o si es la primera que aparece de su semana o de su mes, mientras no se hayan juntado S semanas o M meses. La semana se calcula con date -d FECHA +%G-%V, el año y el número de semana ISO, y el mes es el comienzo del nombre. El script de la sección 11 lo implementa.
9. Que un respaldo fallido no cuente
El peor respaldo no es el que falla, sino el que falla en silencio y parece bueno. Un script de respaldo tiene que garantizar que solo exista con su nombre definitivo una copia terminada, y que un fallo no destruya las buenas:
- Copiar a un nombre provisional, como
.incompleta-2026-10-15, y renombrarlo al nombre definitivo solo cuando la copia terminó bien. Unmvdentro del mismo disco es instantáneo y atómico, como la escritura del tema 24. Si la copia se interrumpe, la siguiente ejecución retoma la provisional, yrsyncsolo copia lo que falta. provisional - Rotar solo después de un respaldo bueno. Si la copia de hoy falló, el script se detiene antes de borrar nada: no tiene sentido eliminar la copia de hace un mes justo cuando no hay una nueva. rotar después
- Impedir dos ejecuciones a la vez sobre el mismo destino, con
flock(tema 27). bloqueo - Registrar y avisar, con
ejecutar-tarea(tema 34) o un temporizador de systemd (tema 35): un respaldo que falla tiene que llegar a los ojos de alguien. aviso - Verificar, que es el tema del tema 38: que el respaldo se haya hecho no significa que se pueda restaurar. verificar
10. Lo que no se copia bien
- Las bases de datos en uso. Copiar los archivos de una base de datos mientras funciona produce, casi siempre, una copia inconsistente. Antes del respaldo se genera un volcado con su herramienta, como
pg_dumppara PostgreSQL omysqldumppara MySQL, y se respalda el volcado. - Los archivos que cambian durante la copia. Los códigos 1 de
tary 24 dersynclo indican. Para datos donde importa la coherencia entre archivos, la solución es una instantánea del sistema de archivos, con LVM, Btrfs o ZFS, y copiar desde ella. - Los dueños y los permisos. Para conservarlos, la copia tiene que hacerla root;
--numeric-idsguarda los números de usuario en lugar de los nombres, que pueden no existir o ser otros en la máquina de destino. - La privacidad. Un respaldo contiene todo lo que había en el original, y casi siempre más de lo que cualquier otra persona debería ver.
umask 077al comienzo del script hace que los archivos creados solo los pueda leer su dueño. Si las copias salen del equipo, conviene cifrarlas, por ejemplo congpg, o usar herramientas que cifran por sí mismas, como restic o BorgBackup. - El propio respaldo. Si el destino está montado siempre y con permiso de escritura, lo que dañe el original puede dañar también las copias. Lo más seguro es que el servidor de respaldos tome los datos, en lugar de que el equipo los empuje, o que el destino solo admita agregar.
11. Un script completo
Este script hace instantáneas diarias con rsync --link-dest y aplica la rotación abuelo-padre-hijo. Recibe uno o varios orígenes y el directorio de destino, y puede simular tanto la copia como la rotación.
#!/usr/bin/env bash
#
# respaldar — instantáneas diarias con rsync --link-dest, con rotación:
# conserva las últimas D diarias, la más reciente de cada una de las últimas
# S semanas y la más reciente de cada uno de los últimos M meses.
#
# Uso: respaldar [-n] [-x EXCLUSIONES] [-d D] [-s S] [-m M] ORIGEN... DESTINO
# -n muestra qué se copiaría y qué se borraría, sin hacerlo
# -x archivo con patrones a excluir, uno por línea
# -d, -s, -m instantáneas diarias, semanales y mensuales (7, 4 y 12)
#
set -euo pipefail
shopt -s nullglob
export LC_ALL=C
umask 077
prog="${0##*/}"
diarias=7 semanales=4 mensuales=12 simular=0 exclusiones=""
uso() { echo "Uso: $prog [-n] [-x EXCLUSIONES] [-d D] [-s S] [-m M] ORIGEN... DESTINO" >&2; exit 2; }
error() { echo "$prog: $*" >&2; exit 1; }
registro() { echo "$(date '+%F %T') $*"; }
while getopts ":nx:d:s:m:" opcion; do
case "$opcion" in
n) simular=1 ;;
x) exclusiones="$OPTARG" ;;
d) diarias="$OPTARG" ;;
s) semanales="$OPTARG" ;;
m) mensuales="$OPTARG" ;;
*) uso ;;
esac
done
shift $(( OPTIND - 1 ))
(( $# >= 2 )) || uso
for n in "$diarias" "$semanales" "$mensuales"; do
[[ "$n" =~ ^[0-9]+$ ]] || uso
done
(( diarias >= 1 )) || error "hay que conservar al menos una instantánea diaria"
origenes=("${@:1:$#-1}")
destino="${!#}"
for o in "${origenes[@]}"; do
[[ -e "$o" ]] || error "no existe el origen: $o"
done
[[ -d "$destino" ]] || error "no existe el destino: $destino"
[[ -z "$exclusiones" || -r "$exclusiones" ]] || error "no se puede leer: $exclusiones"
destino=$(readlink -f -- "$destino") # --link-dest necesita una ruta absoluta
exec 9> "$destino/.respaldar.lock"
flock -n 9 || error "ya hay un respaldo en marcha en $destino"
hoy=$(date +%F)
nueva="$destino/$hoy"
temporal="$destino/.incompleta-$hoy"
instantaneas() { # las instantáneas existentes, de la más vieja a la más nueva
find "$destino" -mindepth 1 -maxdepth 1 -type d \
-name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' -printf '%f\n' | sort
}
# 1. La copia
if [[ -d "$nueva" ]]; then
registro "ya existe la instantánea de hoy, $hoy; no se copia de nuevo"
else
opciones=(-aHR --numeric-ids --delete --delete-excluded)
[[ -n "$exclusiones" ]] && opciones+=(--exclude-from="$exclusiones")
anterior=$(instantaneas | tail -n 1)
[[ -n "$anterior" ]] && opciones+=(--link-dest="$destino/$anterior")
(( simular )) && opciones+=(--dry-run --itemize-changes)
registro "copiando ${origenes[*]} en $hoy${anterior:+, a partir de $anterior}"
codigo=0
rsync "${opciones[@]}" -- "${origenes[@]}" "$temporal/" || codigo=$?
case "$codigo" in
0) ;;
24) registro "aviso: algunos archivos desaparecieron durante la copia" ;;
*) error "rsync terminó con código $codigo; la copia incompleta queda en $temporal" ;;
esac
if (( ! simular )); then
mv -- "$temporal" "$nueva" # recién ahora la instantánea existe
ln -sfn -- "$hoy" "$destino/ultima"
fi
fi
# 2. La rotación: qué instantáneas conservar
declare -A conservar=() semanas=() meses=()
quedan_diarias="$diarias"
while IFS= read -r i; do
semana=$(date -d "$i" +%G-%V)
mes="${i:0:7}"
if (( quedan_diarias > 0 )); then
conservar[$i]="diaria"
quedan_diarias=$(( quedan_diarias - 1 ))
fi
if [[ -z "${semanas[$semana]:-}" ]] && (( ${#semanas[@]} < semanales )); then
semanas[$semana]="$i"
conservar[$i]="${conservar[$i]:-semanal}"
fi
if [[ -z "${meses[$mes]:-}" ]] && (( ${#meses[@]} < mensuales )); then
meses[$mes]="$i"
conservar[$i]="${conservar[$i]:-mensual}"
fi
done < <( { instantaneas; echo "$hoy"; } | sort -ru )
# 3. Borrar las demás, y las copias incompletas de otros días
while IFS= read -r i; do
[[ -n "${conservar[$i]:-}" ]] && continue
if (( simular )); then
registro "se borraría $i"
else
registro "borrando $i"
rm -rf -- "${destino:?}/$i"
fi
done < <(instantaneas)
for vieja in "$destino"/.incompleta-*; do
[[ "$vieja" == "$temporal" ]] && continue
if (( simular )); then registro "se borraría ${vieja##*/}"; else rm -rf -- "$vieja"; fi
done
registro "listo: ${#conservar[@]} instantáneas (diarias $diarias, semanales $semanales, mensuales $mensuales)"
/home/ana/.cache/
/home/ana/Descargas/
/home/ana/.local/share/Trash/
node_modules/
*.tmp
$ sudo respaldar -n -x /home/ana/.config/respaldar/excluir /home/ana /etc /mnt/copias
2026-10-15 10:12:03 copiando /home/ana /etc en 2026-10-15, a partir de 2026-10-14
>f.st...... home/ana/documentos/informe.odt
>f+++++++++ home/ana/documentos/presupuesto-2027.ods
>f.st...... etc/hosts
2026-10-15 10:12:09 se borraría 2026-10-08
2026-10-15 10:12:09 listo: 20 instantáneas (diarias 7, semanales 4, mensuales 12)
$ sudo respaldar -x /home/ana/.config/respaldar/excluir /home/ana /etc /mnt/copias
2026-10-15 10:12:31 copiando /home/ana /etc en 2026-10-15, a partir de 2026-10-14
2026-10-15 10:13:40 borrando 2026-10-08
2026-10-15 10:13:41 listo: 20 instantáneas (diarias 7, semanales 4, mensuales 12)
$ ls /mnt/copias
2025-11-30 2026-02-28 2026-05-31 2026-08-31 2026-10-04 2026-10-11 2026-10-14
2025-12-31 2026-03-31 2026-06-30 2026-09-27 2026-10-09 2026-10-12 2026-10-15
2026-01-31 2026-04-30 2026-07-31 2026-09-30 2026-10-10 2026-10-13 ultima
$ ls /mnt/copias/ultima/
etc home
- La instantánea solo existe cuando está completa:
rsynccopia a.incompleta-FECHA, y elmval nombre definitivo ocurre después de comprobar su código. Si falla, el modo estricto detiene el script antes de la rotación, de modo que no se borra ninguna copia buena; y como la provisional se conserva, la siguiente ejecución del mismo día la retoma. - Los códigos de
rsyncse interpretan: el 24 es un aviso y no impide terminar la instantánea; cualquier otro distinto de cero es un error. - La instantánea de ayer es la base:
--link-destapunta a la más reciente, con ruta absoluta, porque una relativarsyncla interpretaría respecto del destino. La primera vez no hay ninguna, y la copia es completa. -Rconserva las rutas, de modo que varios orígenes no se mezclan:/home/anay/etcquedan comohome/anayetcdentro de cada instantánea.--delete-excludedborra de la nueva instantánea lo que se haya agregado a las exclusiones.- Es idempotente en el día: si ya existe la instantánea de hoy, no copia de nuevo, y la rotación vuelve a dar el mismo resultado. Así puede ejecutarse a mano además de por el temporizador, sin efectos indeseados.
- La rotación decide antes de borrar, en un recorrido de la más nueva a la más vieja que marca cada instantánea conservada con su motivo, y en un segundo recorrido borra las que no tienen marca. En la simulación, la de hoy se cuenta aunque todavía no exista, para que el resultado coincida con el real.
- Protecciones contra el desastre: se exige al menos una diaria, para que la rotación nunca borre la copia recién hecha;
"${destino:?}"hace fallar elrm -rfsi la variable estuviera vacía, la protección del tema 6; y el bloqueo impide que dos ejecuciones se pisen. ultimaes un enlace simbólico a la instantánea más reciente, cómodo para restaurar y para los scripts de verificación del tema siguiente.
Para programarlo cada noche basta una línea con cualquiera de las herramientas del bloque anterior; por ejemplo, con el script del tema 35, en el systemd de root: OnCalendar=02:30, Persistent=true, y ExecStart=/usr/local/bin/respaldar -x /etc/respaldar/excluir /home /etc /mnt/copias.
12. Errores frecuentes
| Escribiste | Qué pasa | Corrección |
|---|---|---|
Un espejo con rsync --delete como único respaldo | Los borrados y los daños se copian en la siguiente ejecución. | Instantáneas con --link-dest, o varias versiones. |
rsync -a --delete fotos/ copias/ queriendo copias/fotos/ | Se copia el contenido, y se borra lo que había en copias/. | Cuidar la barra final, y simular con -n. |
tar … || exit 1 sin distinguir códigos | Un archivo que cambió durante la copia anula el respaldo entero. | Tratar el 1 de tar y el 24 de rsync como avisos. |
| Escribir directamente el nombre definitivo | Una copia interrumpida parece un respaldo válido. | Nombre provisional y mv al terminar. |
| Rotar antes de copiar | Si la copia falla, se borró una buena y no hay una nueva. | Rotar solo después de un respaldo exitoso. |
--link-dest=../2026-10-14 | La ruta relativa se toma respecto del destino; no se enlaza nada y la copia es completa. | Ruta absoluta. |
| Instantáneas en un disco con formato FAT o exFAT | No admite enlaces duros: cada instantánea ocupa todo. | Un sistema de archivos de Linux, como ext4. |
| Respaldar los archivos de una base de datos en uso | Copia inconsistente, que puede no abrir. | Respaldar un volcado, como el de pg_dump. |
rm -rf "$destino/$viejo" | Con una variable vacía por un error, borra lo que no debía. | "${destino:?}/$viejo", y nombres validados. |
| Respaldar sin probar nunca una restauración | Se descubre que no sirven el día que hacen falta. | Restaurar periódicamente, como en el tema 38. |
13. Resumen
- Un respaldo es una copia aparte y con historia; un espejo o un RAID no lo son. La regla 3-2-1 pide tres copias, en dos medios, una en otro lugar.
- Un completo copia todo; un incremental, lo cambiado desde la copia anterior; un diferencial, lo cambiado desde el último completo. Restaurar un incremental exige toda la cadena.
tar --createcon--directory,--one-file-systemy exclusiones hace un completo; su código 1 es un aviso y el 2 un error.tar --listed-incremental=archivo.snarhace incrementales que reproducen también los borrados; se restauran en orden con--listed-incremental=/dev/null.rsync -acopia solo lo que cambió; la barra final del origen decide si se copia el directorio o su contenido;-n -isimula;--deleterefleja los borrados.rsync --link-destcrea instantáneas completas que comparten, con enlaces duros, todo lo que no cambió.- La rotación abuelo-padre-hijo conserva copias diarias, semanales y mensuales; se decide primero qué conservar y después se borra el resto.
- Una copia se hace con un nombre provisional y se renombra al terminar; la rotación va después de un respaldo exitoso, con un bloqueo y un aviso si algo falla.
- Las bases de datos se respaldan con su volcado; los permisos requieren root y
--numeric-ids; las copias se protegen conumask 077y, si salen del equipo, con cifrado.
14. Preguntas de repaso
Intenta responder cada una antes de abrir la respuesta.
1. ¿Por qué una carpeta sincronizada o un disco en espejo no son un respaldo?
Porque reflejan el estado actual: si un archivo se borra o se daña, el cambio se copia enseguida. Un respaldo conserva versiones anteriores, a las que se puede volver.
2. ¿Qué diferencia hay entre un respaldo incremental y uno diferencial?
El incremental copia lo que cambió desde la copia anterior, sea cual sea; el diferencial, lo que cambió desde el último completo. Para restaurar, el incremental necesita el completo y todos los incrementales siguientes; el diferencial, solo el completo y el último diferencial.
3. ¿Qué indica el código de salida 1 de GNU tar, y cómo conviene tratarlo?
Que algunos archivos cambiaron mientras se copiaban. El respaldo está completo, aunque esos archivos pueden haber quedado en un estado intermedio, de modo que se trata como un aviso y no como un error.
4. ¿Para qué sirve el archivo .snar de --listed-incremental?
Guarda la lista de archivos copiados y sus fechas. Con él, tar sabe qué cambió desde el respaldo anterior; si no existe, hace un completo y lo crea.
5. ¿Qué diferencia hay entre rsync -a fotos copias/ y rsync -a fotos/ copias/?
La primera copia el directorio, y el resultado es copias/fotos/. La segunda copia su contenido directamente en copias/.
6. ¿Cómo logra --link-dest que cada instantánea sea completa sin ocupar todo el espacio?
Para cada archivo que no cambió respecto de la instantánea de referencia, crea un enlace duro al archivo de esa instantánea en lugar de copiarlo. Los datos están una sola vez en el disco, con un nombre en cada instantánea.
7. Con instantáneas de --link-dest, ¿qué pasa con las demás si se borra una?
Nada: los datos que comparte con las otras siguen teniendo sus otros nombres, y solo se libera el espacio de lo que estaba únicamente en la borrada.
8. ¿Qué conserva una política de 7 diarias, 4 semanales y 12 mensuales?
Las 7 instantáneas más recientes; además, la más reciente de cada una de las 4 últimas semanas; y la más reciente de cada uno de los 12 últimos meses. Con unas 20 copias se cubre un año.
9. ¿Por qué respaldar copia primero a .incompleta-FECHA?
Para que una copia interrumpida nunca tenga el nombre de una instantánea válida. Solo cuando rsync terminó bien se renombra, con un mv atómico; y si falla, la siguiente ejecución retoma la copia provisional.
10. ¿Por qué el script rota después de copiar, y no antes?
Porque si la copia falla, el script se detiene sin borrar nada. Rotar antes podría eliminar una copia buena justo el día en que no se pudo hacer una nueva.
Para practicar
- Haz un respaldo completo de un directorio de prueba con
tar, y luego dos incrementales, modificando, creando y borrando archivos entre ellos. Restaura la cadena en otro directorio y compara condiff -r. - Prueba la diferencia de la barra final de
rsynccon-n -i, con y sin--delete, sobre un directorio de destino que tenga archivos propios. - Crea tres instantáneas con
--link-desten días simulados, cambiando un archivo entre ellas, y comprueba condu -shyls -liqué se comparte. - En un directorio de prueba, crea con
mkdirdirectorios con las fechas de los últimos 400 días y ejecutarespaldar -n. ¿Cuáles se conservarían con-d 3 -s 2 -m 6? - Haz fallar la copia, por ejemplo con un origen sin permiso de lectura, y comprueba que no se borra ninguna instantánea y que la siguiente ejecución retoma la copia provisional.
- Agrega a
respaldaruna comprobación del espacio libre en el destino, condf --output=avail, que se niegue a empezar si queda menos de un porcentaje dado.