# Runbook: Database Down / DB Pool Exhausted

## Signal

**Alertes déclenchées**:
- `VezaDBPoolHighUsage` - DB pool > 80% (20/25 connexions)
- `VezaDBPoolExhausted` - DB pool épuisé (wait count augmente)
- `/readyz` retourne `503 Service Unavailable` avec `status: "not_ready"`

**Symptômes observables**:
- Erreurs 5xx sur endpoints nécessitant la DB
- Logs: `database connection failed`, `connection pool exhausted`
- Métriques: `veza_db_pool_open_connections` proche de 25, `veza_db_pool_wait_count_total` augmente

## Hypothèses

1. **DB down** - PostgreSQL ne répond plus
2. **DB pool saturé** - Trop de connexions ouvertes, pool épuisé
3. **Réseau** - Problème de connectivité entre app et DB
4. **DB lente** - Requêtes bloquantes, connexions non libérées

## Vérifications

### 1. Vérifier l'état de la DB

```bash
# Depuis le serveur DB
sudo systemctl status postgresql
# ou
docker ps | grep postgres

# Tester connexion directe
psql -h localhost -U veza -d veza_db -c "SELECT 1;"
```

### 2. Vérifier métriques Prometheus

```bash
# Pool connexions
curl -s http://localhost:9090/api/v1/query?query=veza_db_pool_open_connections

# Wait count (doit être stable, pas augmenter)
curl -s http://localhost:9090/api/v1/query?query=rate(veza_db_pool_wait_count_total[5m])

# Connexions en cours d'utilisation
curl -s http://localhost:9090/api/v1/query?query=veza_db_pool_in_use
```

### 3. Vérifier logs application

```bash
# Chercher erreurs DB
grep -i "database\|connection\|pool" /var/log/veza-backend-api/*.log | tail -50

# Chercher requêtes lentes (si logging activé)
grep "slow query" /var/log/veza-backend-api/*.log
```

### 4. Vérifier connexions actives DB

```sql
-- Depuis psql
SELECT count(*) FROM pg_stat_activity WHERE datname = 'veza_db';
SELECT pid, usename, application_name, state, query_start, query 
FROM pg_stat_activity 
WHERE datname = 'veza_db' 
ORDER BY query_start;
```

## Actions Correctives

### Si DB down

1. **Redémarrer PostgreSQL**:
   ```bash
   sudo systemctl restart postgresql
   # ou
   docker restart veza-postgres
   ```

2. **Vérifier logs PostgreSQL**:
   ```bash
   tail -100 /var/log/postgresql/postgresql-*.log
   # ou
   docker logs veza-postgres --tail 100
   ```

3. **Vérifier espace disque**:
   ```bash
   df -h /var/lib/postgresql
   ```

4. **Vérifier mémoire**:
   ```bash
   free -h
   ```

### Si DB pool saturé

1. **Identifier requêtes bloquantes**:
   ```sql
   SELECT pid, usename, application_name, state, wait_event_type, wait_event, query_start, query
   FROM pg_stat_activity
   WHERE datname = 'veza_db' AND state != 'idle'
   ORDER BY query_start;
   ```

2. **Tuer requêtes bloquantes** (si nécessaire):
   ```sql
   SELECT pg_terminate_backend(pid) 
   FROM pg_stat_activity 
   WHERE datname = 'veza_db' 
   AND state = 'active' 
   AND query_start < NOW() - INTERVAL '5 minutes';
   ```

3. **Augmenter pool temporairement** (si configurable):
   - Modifier `internal/config/config.go:446` (MaxOpenConns)
   - Redémarrer application
   - **⚠️ Attention**: Augmenter le pool peut masquer le problème réel

4. **Vérifier connexions non fermées**:
   - Auditer code pour `defer db.Close()` manquants
   - Vérifier transactions non commitées/rollbackées

### Si réseau

1. **Tester connectivité**:
   ```bash
   telnet <DB_HOST> 5432
   # ou
   nc -zv <DB_HOST> 5432
   ```

2. **Vérifier firewall**:
   ```bash
   sudo iptables -L -n | grep 5432
   ```

3. **Vérifier DNS**:
   ```bash
   nslookup <DB_HOST>
   ```

## Post-Mortem Notes

### À documenter après résolution

- **Cause racine**: DB down / Pool saturé / Réseau / Autre
- **Durée de l'incident**: De [heure début] à [heure fin]
- **Impact**: Endpoints affectés, utilisateurs impactés
- **Actions prises**: Liste des actions correctives
- **Actions préventives**:
  - [ ] Augmenter monitoring DB pool
  - [ ] Ajouter alertes sur requêtes lentes
  - [ ] Auditer code pour connexions non fermées
  - [ ] Configurer connection pooling côté DB (PgBouncer)

### Métriques à surveiller post-incident

- `veza_db_pool_open_connections` - Doit rester < 20
- `veza_db_pool_wait_count_total` - Doit rester stable
- `veza_db_pool_in_use` - Doit être < `open_connections`
- `/readyz` - Doit retourner `200 ready`

## Références

- Configuration DB pool: `internal/config/config.go:446` (MaxOpenConns: 25)
- Health check: `internal/handlers/health.go:124-140`
- Métriques DB: `internal/metrics/db_pool.go`
