veylant/docs/runbooks/database-full.md
2026-02-23 13:35:04 +01:00

5.6 KiB

Runbook — Base de Données Pleine / Pool de Connexions Épuisé

Alerte : VeylantDBConnectionsHigh (severity: warning) ou DiskFull (PVC AWS EBS) SLA impact : Dégradation progressive → interruption totale si espace disque épuisé Temps de résolution cible : < 30 minutes


Symptômes

  • Alerte VeylantDBConnectionsHigh : connexions actives > 20
  • Erreurs "connection pool exhausted" dans les logs du proxy
  • Requêtes lentes (> 500ms p99) sans cause upstream
  • Erreurs "no space left on device" dans les logs PostgreSQL
  • Alertmanager : PVCAlmostFull si configuré

Diagnostic

1. Vérifier l'état du pool de connexions

# Connexions actives en temps réel
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "
    SELECT state, count(*)
    FROM pg_stat_activity
    GROUP BY state
    ORDER BY count DESC;"

# Requêtes en attente (bloquées par verrou)
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "
    SELECT pid, query, state, wait_event_type, wait_event, now() - pg_stat_activity.query_start AS duration
    FROM pg_stat_activity
    WHERE state != 'idle' AND query_start < now() - interval '30 seconds'
    ORDER BY duration DESC;"

2. Vérifier l'espace disque

# Espace disque PostgreSQL (PVC AWS EBS)
kubectl exec -n veylant deploy/postgres -- df -h /var/lib/postgresql/data

# Taille des tables principales
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "
    SELECT relname, pg_size_pretty(pg_total_relation_size(relid)) AS size
    FROM pg_catalog.pg_statio_user_tables
    ORDER BY pg_total_relation_size(relid) DESC
    LIMIT 10;"

# Espace utilisé par les WAL (Write-Ahead Logs)
kubectl exec -n veylant deploy/postgres -- \
  du -sh /var/lib/postgresql/data/pg_wal/

3. Identifier les requêtes lentes

# Top 10 requêtes les plus lentes (pg_stat_statements requis)
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "
    SELECT substring(query, 1, 100) AS query,
           calls,
           mean_exec_time::int AS avg_ms,
           total_exec_time::int AS total_ms
    FROM pg_stat_statements
    ORDER BY mean_exec_time DESC
    LIMIT 10;"

Remédiation

A — Pool de connexions épuisé

A1. Terminer les connexions inactives (idle)

# Tuer les connexions idle depuis plus de 5 minutes
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "
    SELECT pg_terminate_backend(pid)
    FROM pg_stat_activity
    WHERE state = 'idle'
      AND query_start < now() - interval '5 minutes'
      AND pid <> pg_backend_pid();"

A2. Terminer les requêtes bloquées

# Identifier et tuer les requêtes qui bloquent depuis > 2 minutes
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "
    SELECT pg_terminate_backend(pid)
    FROM pg_stat_activity
    WHERE state = 'active'
      AND query_start < now() - interval '2 minutes'
      AND wait_event_type = 'Lock';"

A3. Ajuster la taille du pool (redémarrage nécessaire)

# Modifier la config du pool dans le ConfigMap
kubectl edit configmap veylant-proxy-config -n veylant

# Ajouter/modifier :
# database:
#   max_open_connections: 30  (augmenter temporairement)
#   max_idle_connections: 5

# Redémarrer le proxy
kubectl rollout restart deployment/veylant-proxy-blue -n veylant

B — Espace disque insuffisant

B1. VACUUM pour récupérer de l'espace

# VACUUM ANALYZE sur les tables les plus volumineuses
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "VACUUM ANALYZE audit_log_partitions;"

# VACUUM FULL (bloque les écritures — fenêtre de maintenance requise)
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "VACUUM FULL routing_rules;"

B2. Purger les vieux WAL (si excessifs)

# Vérifier les archives WAL obsolètes
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "SELECT pg_walfile_name(pg_current_wal_lsn());"

# Forcer un checkpoint pour libérer les WAL non nécessaires
kubectl exec -n veylant deploy/postgres -- \
  psql -U veylant -c "CHECKPOINT;"

B3. Étendre le PVC AWS EBS

# Vérifier le PVC actuel
kubectl get pvc -n veylant postgres-data

# Patcher la taille (EBS supporte l'expansion à chaud)
kubectl patch pvc postgres-data -n veylant \
  -p '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'

# Attendre la confirmation AWS EBS
kubectl describe pvc postgres-data -n veylant | grep -E "(Capacity|Conditions)"

# Redémarrer PostgreSQL pour reconnaître le nouvel espace (si nécessaire)
kubectl rollout restart statefulset/postgres -n veylant

Prévention

  • Alert VeylantDBConnectionsHigh configurée à 20 connexions (seuil conservateur)
  • VACUUM automatique activé (autovacuum PostgreSQL par défaut)
  • Backup quotidien S3 avec 7 jours de rétention (deploy/k8s/production/postgres-backup.yaml)
  • Monitoring PVC utilisation > 80% → PVCAlmostFull alerte (à configurer dans rules.yml)

Post-mortem Template

## Post-mortem — DB Issue [DATE]

**Type :** Pool épuisé / Espace disque / Requête lente
**Durée d'impact :** [X minutes]
**Erreurs utilisateurs :** [N requêtes rejetées]

### Timeline
- HH:MM — Alerte reçue
- HH:MM — Diagnostic : [cause identifiée]
- HH:MM — Action prise : [VACUUM / kill connections / PVC expansion]
- HH:MM — Service rétabli

### Root Cause
[Description]

### Actions correctives
- [ ] Augmenter le monitoring PVC
- [ ] Revoir les index manquants sur les requêtes lentes
- [ ] Planifier la prochaine expansion de stockage