Erreur PostgreSQL : canceling statement due to conflict with recovery

FATAL:  terminating connection due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.

Cette erreur n'existe que sur les réplicas hot standby. Le réplica doit appliquer le WAL du primaire pour rester synchronisé ; votre requête avait besoin de versions de ligne que le WAL entrant (typiquement le nettoyage par vacuum) supprime. Après avoir suspendu le rejeu pendant max_standby_streaming_delay, le réplica a choisi la réplication plutôt que votre requête et l'a annulée.

Ce que signifie cette erreur

Le réplica sert des lectures tout en rejouant continuellement le WAL du primaire — deux tâches qui entrent en conflit quand le rejeu veut modifier ou supprimer des données qu'une requête en cours peut encore voir. PostgreSQL retarde d'abord le rejeu pour laisser la requête se terminer (jusqu'à max_standby_streaming_delay, par défaut 30 s), puis annule la requête. C'est un compromis délibéré entre la fraîcheur du réplica et la survie de la requête, et chaque bouton ne fait que se déplacer le long de cet axe.

Causes fréquentes

Comment la diagnostiquer

-- Sur le réplica : compteurs de conflits par type et par base
SELECT * FROM pg_stat_database_conflicts;

confl_snapshot est le cas du nettoyage par vacuum ; confl_lock pointe vers du DDL sur le primaire. Corrélez avec les charges de travail qui s'exécutent sur le réplica à ces moments-là.

Comment la corriger

Choisissez le compromis explicitement :

🔍 À lire aussi : VACUUM & bloat — hot_standby_feedback fait retenir le nettoyage par les requêtes du réplica exactement comme les transactions locales longues.