# 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

```bash
# 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

```bash
# 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

```bash
# 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)

```bash
# 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

```bash
# 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)

```bash
# 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

```bash
# 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)

```bash
# 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

```bash
# 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

```markdown
## 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
```
