Comment tuer une requête (ou une connexion) dans PostgreSQL

Deux fonctions, un chemin d'escalade : pg_cancel_backend(pid) annule la requête en cours et laisse la connexion active ; pg_terminate_backend(pid) ferme la connexion entière. Commencez par annuler.

-- 1. Trouvez le pid (voir le guide "show running queries" pour plus) :
SELECT pid, state, now() - query_start AS runtime, left(query, 100)
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY query_start;

-- 2. Annulez la requête (doux — la session reste connectée) :
SELECT pg_cancel_backend(12345);

-- 3. Si cela ne suffit pas, fermez la connexion :
SELECT pg_terminate_backend(12345);

Laquelle, et quand

SituationÀ utiliser
Une requête est lente / bloque les autres, mais la session est par ailleurs sainepg_cancel_backend
Session coincée en idle in transaction qui retient des verrous (rien à annuler qui tourne)pg_terminate_backend — annuler ne fait rien ici : il n'y a aucune requête à annuler, c'est la transaction ouverte qui pose problème
Session emballée qui se reconnecte et relance la requêteTerminez, puis corrigez le client — la tuer en boucle n'est pas une stratégie

Les deux renvoient true si le signal a été envoyé (ce n'est pas une garantie que la requête meure instantanément — l'annulation est vérifiée à des points sûrs, donc une requête bloquée dans un appel noyau non interruptible peut prendre un moment). La victime reçoit SQLSTATE 57014 (« canceling statement due to user request ») ou, lorsqu'elle est terminée, son client voit la connexion tomber.

Nettoyage en masse, fait avec précaution

-- Termine toutes les sessions "idle in transaction" de plus de 10 minutes :
SELECT pid, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle in transaction'
  AND xact_start < now() - interval '10 minutes';

Exécutez d'abord le SELECT sans l'appel à pg_terminate_backend et lisez la liste — puis, et seulement alors, ajoutez le kill. Pour une correction permanente, définissez idle_in_transaction_session_timeout plutôt que de lancer ceci à la main à chaque incident.

Ce qu'il ne faut jamais faire

Ne faites jamais kill -9 sur un processus backend PostgreSQL depuis le shell. Un backend tué par SIGKILL ne peut pas nettoyer son état en mémoire partagée, donc le postmaster doit supposer une corruption et redémarre tout le cluster, déconnectant tout le monde et rejouant les WAL. Ce qui ressemblait à tuer une seule requête devient une panne complète. Un simple kill <pid> (SIGTERM) équivaut à pg_terminate_backend et est acceptable quand vous n'arrivez pas à obtenir de connexion — mais les fonctions SQL restent toujours préférables car elles ne peuvent pas frapper le mauvais processus.

Permissions : vous pouvez toujours annuler/terminer vos propres sessions ; pour les sessions d'autres utilisateurs, vous devez être membre de pg_signal_backend (ou superutilisateur).

🔍 Vous tuez la même requête toutes les semaines ? Visualisez son plan avec l'EXPLAIN Visualizer et corrigez-la une bonne fois — ou placez un statement_timeout devant.