Saltar a contenido

Cómo Gestionar y Restaurar Backups Automatizados de PostgreSQL

Tipo: Diátaxis — How-To Guide
Ámbito: Infraestructura transversal (infra/)
Motor: PostgreSQL 17 (timeliber-postgres) + Restic (Deduplicación CDC + Cifrado AES-256)


1. Arquitectura del Sistema de Respaldo

El sistema de respaldo de TimeLiber utiliza Restic con deduplicación por bloques (Content-Defined Chunking) y cifrado simétrico AES-256.

  • Frecuencia: Diario a las 02:00:00 COT vía timeliber-backup.timer (systemd).
  • Almacenamiento: Solo almacena los bloques modificados (deltas). El 98% de los bloques idénticos se deduplican automáticamente.
  • Cifrado: Llave simétrica en /etc/timeliber/secrets/restic_password (permisos 600).
  • Ubicación del repositorio: /home/admin_/backups/restic-repo.
  • Retención: 14 snapshots diarios, 4 semanales y 12 mensuales.

2. Comandos Operativos Frecuentes

2.1 Ver el estado del timer de respaldo

systemctl list-timers timeliber-backup.timer

2.2 Ejecutar un respaldo manual inmediato

sudo systemctl start timeliber-backup.service
# O directamente el script:
/home/admin_/software/timeliber-workspace/infra/scripts/timeliber-backup-daemon.sh

2.3 Ver los logs de la última ejecución

journalctl -u timeliber-backup.service -n 50 --no-pager

3. Inspeccionar Snapshots y Fechas Disponibles

Para ver el historial de todas las copias por fecha y hora:

restic snapshots \
  --repo /home/admin_/backups/restic-repo \
  --password-file /etc/timeliber/secrets/restic_password

4. Cómo Restaurar una Base de Datos de un Día Específico

Paso 1: Elegir el snapshot y extraer los archivos a una carpeta temporal

# Reemplazar <SNAPSHOT_ID> con el ID de la fecha que necesitas (ej: 84306f88)
mkdir -p /tmp/restore
restic restore <SNAPSHOT_ID> \
  --repo /home/admin_/backups/restic-repo \
  --password-file /etc/timeliber/secrets/restic_password \
  --target /tmp/restore

Paso 2A: Restaurar una base de datos individual (Recomendado)

Para restaurar una sola vertical (ejemplo: gastro_db) sin tocar las demás:

docker exec -i timeliber-postgres pg_restore \
  -U timeliber_admin \
  -d gastro_db \
  --clean \
  --if-exists \
  < /tmp/restore/home/admin_/backups/staging/individual/gastro_db.dump

Paso 2B: Restaurar el clúster completo (Desastre total)

Si necesitas recrear todas las bases de datos, roles, permisos y políticas RLS:

gunzip -c /tmp/restore/home/admin_/backups/staging/all_databases_globals.sql.gz \
  | docker exec -i timeliber-postgres psql -U timeliber_admin -d template1

Paso 3: Limpiar el directorio temporal

rm -rf /tmp/restore

5. Verificar la Integridad del Repositorio

Para comprobar que ningún bloque esté dañado o alterado:

restic check \
  --repo /home/admin_/backups/restic-repo \
  --password-file /etc/timeliber/secrets/restic_password

6. Recuperación ante Desastre Total (Pérdida de este Servidor)

Si este servidor se pierde, se elimina o queda inaccesible, puedes restaurar todo el ecosistema en cualquier otro servidor o computador siguiendo estos pasos:

Lo que necesitas tener guardado fuera del servidor:

  1. Clave de cifrado de Restic: La clave simétrica de 256 bits (guardada en tu gestor de contraseñas seguro).
  2. Credenciales de Cloudflare R2: Token con acceso de lectura a timeliber-media.

Procedimiento en la nueva máquina:

  1. Instalar Restic y Docker

    sudo apt-get update && sudo apt-get install -y restic docker.io docker-compose-plugin
    

  2. Configurar las variables de entorno para R2

    export AWS_ACCESS_KEY_ID="TU_R2_ACCESS_KEY_ID"
    export AWS_SECRET_ACCESS_KEY="TU_R2_SECRET_ACCESS_KEY"
    export RESTIC_REPOSITORY="s3:https://324aefdd635471c2253a9c76a623e5d5.r2.cloudflarestorage.com/timeliber-media/backups-restic"
    export RESTIC_PASSWORD="TU_RESTIC_PASSWORD"
    

  3. Ver los snapshots en la nube

    restic snapshots
    

  4. Descargar y restaurar el snapshot más reciente (o de la fecha deseada)

    mkdir -p /tmp/restore
    restic restore latest --target /tmp/restore
    

  5. Levantar PostgreSQL e inyectar el volcado

    # Dentro del directorio donde descargaste el volcado:
    gunzip -c /tmp/restore/home/admin_/backups/staging/all_databases_globals.sql.gz \
      | docker exec -i timeliber-postgres psql -U timeliber_admin -d template1