From 93d861d7a78ffe3d2d987db5d6d523d119a9aa16 Mon Sep 17 00:00:00 2001 From: deimo72 Date: Sat, 5 Sep 2026 21:29:45 -0400 Subject: [PATCH] docs: add recovery procedure documentation --- docs/recovery-procedure.md | 281 +++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 docs/recovery-procedure.md diff --git a/docs/recovery-procedure.md b/docs/recovery-procedure.md new file mode 100644 index 0000000..5c3e2ae --- /dev/null +++ b/docs/recovery-procedure.md @@ -0,0 +1,281 @@ +# Procedimiento de Recuperación – CNPG-Backup + +Este documento describe los pasos exactos para restaurar un cluster PostgreSQL usando los backups creados por la estrategia CloudNativePG definida en este repositorio. + +## Escenario común de recuperación + +| Evento | Acciones típicas | +|-------|----------------| +| **Corrupción del cluster** | Restaurar de un backup completo más WALs recientes | +| **Pérdida del nodo primario** | Escalar o restaurar en un nodo diferente | +| **Pérdida de datos accidental** | Point-In-Time Recovery (PITR) a un timestamp antes del incidente | +| **Migración a otro cluster** | Restaurar un backup completo (cold) sin WALs | + +## Requisitos previos + +- El plugin [Barman Cloud](https://cloudnative-pg.io/plugin-barman-cloud/) (`barman-cloud.cloudnative-pg.io`) debe estar instalado en el cluster: + ```bash + kubectl apply -f https://github.com/cloudnative-pg/cnpg-i/releases/download/v0.5.0/manifest.yaml + ``` +- Las credenciales de ObjectStore (`object-store-creds`) deben existir en el namespace donde se restaurará. +- El bucket (`cnpg-backups`) debe ser accesible desde el namespace del nuevo cluster. + +## Guía rápida de recuperación (comando único) + +Para recuperar un cluster de múltiples nodos completo: + +```bash +kubectl cnpg restore pg-backup \ + --backup=latest \ + --namespace=default \ + --target='2026-09-01 12:00:00' \ + --sudo-recovery +``` + +(El timestamp `--target` es opcional – omitirlo restaurará desde el backup más reciente) + +## Paso a paso + +### 1. Identificar un backup válido + +Listar todos los recursos `Backup` ordenados por CreationTimestamp. + +```bash +kubectl get backups -o wide +``` + +Salida esperada (columnas relevantes): + +``` +NAME AGE CLUSTER METHOD PHASE STARTED_AT COMPLETION DESTINATION +backup-1 2h pg-backup plugin completed 2026-09-06T02:00:00Z 2026-09-06T02:05:00Z s3://cnpg-backups/pg-backup/ +backup-2 30m pg-backup plugin completed 2026-09-06T01:00:00Z 2026-09-06T01:03:00Z s3://cnpg-backups/pg-backup/ +``` + +**¿Cómo usarlo?** +- `backup-1` – la restauración más reciente (recomendada para RTO mínimo). +- `backup-2` – una restauración intermedia para una recuperação al punto en el tiempo más antigua. + +### 2. Restaurar desde el backup completo más reciente + +Cuando se necesita un cluster nuevo (ej. reemplazo de nodos o reconstrucción post-falla) y no hay necesidad de recuperar un punto específico: + +```bash +# Opción A – Usar el comando cnpg RESTOURE (recomendado) + +kubectl cnpg restore pg-backup \ + --backup=backup-1 \ + --namespace=default \ + --recovery-conf='application_name=restored_cluster' + +# Opción B – Aplicar un recurso YAML de Cluster con bootstrap.recovery + +cat < -- psql -U -d +``` + +### 5. Verificación y pruebas de restauración + +Después de una restauración exitosa, realice estas verificaciones: + +1. **Conexión y datos básicos** + ```bash + kubectl exec -it $(kubectl get pod -l cnpg.io/cluster=pg-restored -o jsonpath='{.items[0].metadata.name}') -- psql -U app_user -d app_db -c "SELECT COUNT(*) FROM my_table;" + ``` + +2. **Corrupción de WALs** + ```bash + kubectl exec -it $(kubectl get pod -l cnpg.io/cluster=pg-restored -o jsonpath='{.items[0].metadata.name}') -- pg_verifybackup -D /var/lib/postgresql/data/temporary_backup_path + ``` + (El `pg_verifybackup` es provisto por CloudNativePG y puede ser ejecutado en un contenedor que acceda al backup) + +3. **Puntuación de disponibilidad** + ```bash + kubectl exec -it $(kubectl get pod -l cnpg.io/cluster=pg-restored -o jsonpath='{.items[0].metadata.name}') -- psql -U app_user -d postgres -c "SELECT pg_is_in_recovery();" + ``` + Debe devolver `f` (ya que el cluster restaurado estará en modo de recuperación hasta que se reanude el streaming de WALs). + +### 6. Limpiar un cluster restaurado innecesario + +Una vez verificado que el cluster restaurado está funcionando como se espera, se puede eliminar el cluster original si se planea reemplazarlo completamente: + +```bash +kubectl delete cluster pg-backup --timeout=300s +``` + +Luego, renombre o reemplace el cluster restaurado (`pg-restored`) en el DNS/servicio de la aplicación si es necesario. + +## Políticas de retención y cómo afectan a la recuperación + +- **Backups base (`data.retentionPolicy`)**: `7 days` → los backups más antiguos de 7 días serán eliminados automáticamente por Barman Cloud. Asegúrese de recuperar todo lo necesario antes de que la retención elimine el backup. +- **WAL archives (`wal.retentionPolicy`)**: `14 days` → los WALs más antiguos de 14 días serán eliminados. Si se necesita una restauración PITR más antigua, solicite una extensión temporal del backup del object store o mantenga una réplica secundaria separada en otro bucket. + +## Frecuencia de restauración recomendada + +| Tasa de cambio | Retención recomendada de WAL | Frecuencia de backup base | +|------------|----------------------|-------------------| +| Alta (< 5 min) | 7 días | Cada 6 h (opcional) | +| Media (15–30 min) | 14 días | Diario (midnight) | +| Baja (> 2 h) | 30 días | Diario (mediodía) | + +Los valores por defecto en este repositorio (`01-objectstore.yaml`) están configurados para una frecuencia media de cambio con retención diaria y de WALs. + +## Casos de error comunes y soluciones + +| Síntoma | Causa probable | Solución | +|---------|--------------|----------| +| `ERROR: file "pg_ident.conf" not found` | El backup se tomó de un cluster con configuración de autentificación personalizada | Copie `pg_ident.conf` desde el backup original en el nuevo cluster (o restaure el backup completo del cluster original) | +| `FATAL: password authentication failed for user "app"` | Las credenciales de autenticación no están presentes en el nuevo cluster | Aplique el `Secret` `postgresql-superuser` o cree una nueva contraseña con `kubectl create secret generic ...` | +| `RESTORE FAILED: WAL file not found in the object store` | El WAL necesario para la restauración PITR fue eliminado por la retención | Aumente el plazo de retención de WALs en `01-objectstore.yaml` o use un backup más reciente como punto de partida para la restauración. | + +## Resumen rápido (cheat-sheet) + +```bash +# Listar backups +kubectl get backups -o wide + +# Restaurar al backup más reciente +kubectl cnpg restore pg-backup --backup=latest + +# Restaurar al timestamp específico (PITR) +kubectl cnpg restore pg-backup --backup=backup-2 --target='2026-09-05 14:30:00' + +# Monitorear la restauración +kubectl get cluster pg-restored -w +kubectl describe cluster pg-restored + +# Probar la conexión después de la restauración +kubectl exec -it -- psql -U app_user -d app_db -c "SELECT version();" +``` + +## Referencias + +- [Documentación de CloudNativePG – Backups](https://cloudnative-pg.io/docs/current/backup/) +- [Documentación del plugin Barman Cloud – Retención](https://cloudnative-pg.io/plugin-barman-cloud/docs/retention/) +- [CloudNativePG – Recuperación PITR](https://cloudnative-pg.io/docs/current/recovery/) + +Este procedimiento se actualiza cuando se usan nuevas versiones del plugin Barman Cloud o del operador CloudNativePG. \ No newline at end of file