restic copy: duplicar un repositorio en otro destino y comprobar que es restaurable
restic copy pasó 2 snapshots (repo 52 292 KiB, copia 52 296 KiB); la segunda ejecución no copió nada (exit 0); check sin errores y restore idéntico al original.
Este artículo no contiene enlaces de afiliado.
Para tener una segunda copia (regla 3-2-1) no hace falta repetir el backup contra otro destino: restic copy pasa los snapshots de un repositorio a otro. Se probó que copia lo esperado, que repetirlo es inocuo y que la copia se restaura.
Condiciones: restic 0.16.4 en Linux arm64, dos repositorios locales, 50 MiB de datos aleatorios en dos snapshots, contraseñas desechables. No se probó con destinos remotos ni con repositorios de tamaño real. Script completo al final.
Pasos y resultado
| Paso | Resultado |
|---|---|
restic init -r B --from-repo A --copy-chunker-params |
repositorio B creado con los mismos parámetros de troceado que A |
restic -r B copy --from-repo A |
2 snapshots copiados |
| Segunda ejecución del mismo comando | sin salida, exit 0: no copia nada |
| Tamaño en disco | A 52 292 KiB, B 52 296 KiB |
restic -r B check |
"no errors were found" |
restic -r B restore latest y diff -r con el original |
idéntico |
Detalles que importan
--copy-chunker-params al crear B hace que los dos repositorios corten los ficheros igual, lo que permite deduplicar entre ellos. Según la documentación de restic, sin esa opción la deduplicación entre repositorios no funciona bien; no se probó aquí.
Si las contraseñas de A y B son distintas, restic copy necesita las dos: la del destino con RESTIC_PASSWORD y la del origen con RESTIC_FROM_PASSWORD (o --from-password-file). En un script desatendido, sin ellas restic se queda esperando una contraseña por la entrada estándar. Esto fue lo que pasó en las primeras pruebas.
La copia no es una prueba de que el origen esté sano: ejecuta restic check en el destino, como se hizo aquí. Relacionado: copia 3-2-1 con restic y restic con rclone.
Script completo
W=$1; rm -rf "$W"; mkdir -p "$W/data"
export RESTIC_PASSWORD=prueba-desechable RESTIC_FROM_PASSWORD=prueba-desechable
A="$W/repoA"; B="$W/repoB"
restic init -r "$A" >/dev/null; restic init -r "$B" --from-repo "$A" --copy-chunker-params >/dev/null
head -c 50M /dev/urandom > "$W/data/a.bin"
restic -r "$A" backup "$W/data" --quiet; echo hola > "$W/data/b.txt"; restic -r "$A" backup "$W/data" --quiet
echo "== 1) snapshots en A: $(restic -r "$A" snapshots --json | python3 -c 'import json,sys;print(len(json.load(sys.stdin)))')"
echo "== 2) copy A -> B"; restic -r "$B" copy --from-repo "$A" 2>&1 | grep -c "snapshot .* saved"
echo "== 3) segunda copia (idempotente)"; restic -r "$B" copy --from-repo "$A" 2>&1 | tail -2
echo "== 4) tamano A / B"; du -sk "$A" | cut -f1; du -sk "$B" | cut -f1
echo "== 5) check B"; restic -r "$B" check; echo "exit=$?"
echo "== 6) restore B y comparar"; restic -r "$B" restore latest --target "$W/out" >/dev/null; diff -r "$W/data" "$W/out$W/data" && echo IGUAL