Copias de seguridad

restic "repository is already locked": cuándo es seguro usar unlock

Publicado el 27 de octubre de 2026Última revisión: 27 de octubre de 20262 min de lectura

Resultado de la prueba

tras un kill -9 queda 1 lock; backup sigue funcionando (exit 0), forget --prune falla (exit 1) hasta ejecutar restic unlock, que quitó 1 lock.

Contenido

Este artículo no contiene enlaces de afiliado.

Si un backup de restic se corta (reinicio, OOM, kill -9), el siguiente forget --prune puede negarse con "repository is already locked". Se probó qué pasa exactamente y cuándo restic unlock es seguro.

Condiciones: restic 0.16.4 en Linux arm64, repositorio local, un fichero aleatorio de 200 MiB, contraseña desechable. No se probó con repositorios remotos (S3, rclone) ni con dos máquinas escribiendo a la vez. Script completo al final.

Qué ocurre

Paso Resultado
Backup interrumpido con kill -9 a los 1,5 s queda 1 fichero en locks/
Nuevo restic backup exit 0: el backup usa un lock no exclusivo y convive con el viejo
restic forget --keep-last 1 --prune exit 1: "repository is already locked by PID ..."
restic unlock "successfully removed 1 locks", exit 0

Cuándo es seguro

restic unlock por defecto solo borra locks obsoletos, no los de procesos vivos. En esta prueba el lock era de la misma máquina y el PID ya no existía, así que restic lo consideró obsoleto. Antes de ejecutarlo, comprueba con restic list locks y restic cat lock <id> el host y el PID; si otra máquina está usando el repositorio, espera. No uses --remove-all salvo que estés seguro de que nada más escribe.

Aviso: si un lock de otra máquina lleva ahí más de 30 minutos sin renovarse, restic también lo trata como obsoleto. Esto no se probó aquí.

En un script desatendido, ejecutar restic unlock antes de forget --prune es razonable si un solo proceso usa el repositorio; con varios, mejor dejar que falle y avisar. Relacionado: códigos de salida de restic y forget y prune.

Script completo

#!/bin/bash
# restic locks after an interrupted backup. Usage: test-restic-unlock.sh WORKDIR
W=$1; rm -rf "$W"; mkdir -p "$W/data"
export RESTIC_PASSWORD=prueba-desechable
R="$W/repo"; restic init -r "$R" >/dev/null
head -c 200M /dev/urandom > "$W/data/big.bin"
echo "== 1) backup interrumpido con kill -9"
restic -r "$R" backup "$W/data" >/dev/null 2>&1 &
P=$!; sleep 1.5; kill -9 $P; wait $P 2>/dev/null
echo "locks en el repositorio: $(ls "$R/locks" | wc -l)"
echo "== 2) lista de locks"; restic -r "$R" list locks | wc -l
echo "== 3) nuevo backup (lock no exclusivo)"; restic -r "$R" backup "$W/data" --quiet; echo "exit=$?"
echo "== 4) forget --prune con lock viejo"; timeout 60 restic -r "$R" forget --keep-last 1 --prune 2>&1 | tail -4; echo "exit=${PIPESTATUS[0]}"
echo "== 5) unlock (solo locks obsoletos)"; restic -r "$R" unlock; echo "exit=$?"
echo "locks tras unlock: $(ls "$R/locks" | wc -l)"