Sévérité : ÉlevéePostgreSQL

Retard de réplication croissant et disque WAL qui se remplit

```text
WARNING: could not write to file "pg_wal/xlogtemp.1234": No space left on device
```

Détecter

Les lectures sur la réplique renvoient des données anciennes de plusieurs minutes ; sur le primaire, le répertoire pg_wal grossit rapidement.

Symptômes

Les lectures sur la réplique renvoient des données anciennes de plusieurs minutes ; sur le primaire, le répertoire pg_wal grossit rapidement.

Environnement

Primaire + réplique en streaming avec slot de réplication physique ; traitement batch nocturne de mise à jour massive.

Cause racine

La réplique rejoue plus lentement que le primaire ne produit de WAL (disque plus lent, requête longue sur la réplique bloquant le rejeu avec hot_standby_feedback/conflits). Le slot conserve tous les WAL non consommés sur le primaire, jusqu'à saturer le disque.

Diagnostic

-- primaire
SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retenu
FROM pg_replication_slots;
SELECT client_addr, state, pg_size_pretty(pg_wal_lsn_diff(sent_lsn, replay_lsn)) FROM pg_stat_replication;
-- réplique
SELECT now() - pg_last_xact_replay_timestamp();
SELECT pid, now() - query_start, query FROM pg_stat_activity WHERE state = 'active' ORDER BY 2 DESC;

Solution

  • Identifier et arrêter la requête longue sur la réplique si elle bloque le rejeu.
  • Si la réplique est hors service durablement : supprimer le slot pour protéger le primaire, puis reconstruire la réplique.
  • Fixer max_slot_wal_keep_size pour plafonner la rétention.

Commandes

SELECT pg_drop_replication_slot('replica1');
ALTER SYSTEM SET max_slot_wal_keep_size = '20GB';
SELECT pg_reload_conf();

Prévention

Alertes sur le retard (secondes et octets) et sur l'espace pg_wal, réplique dimensionnée comme le primaire, batchs massifs découpés en lots.