Eine Abfrage (oder Verbindung) in PostgreSQL beenden

Zwei Funktionen, ein Eskalationspfad: pg_cancel_backend(pid) bricht die laufende Abfrage ab und lässt die Verbindung am Leben; pg_terminate_backend(pid) schließt die gesamte Verbindung. Beginnen Sie mit Cancel.

-- 1. Die pid finden (mehr dazu im Guide "show running queries"):
SELECT pid, state, now() - query_start AS runtime, left(query, 100)
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY query_start;

-- 2. Abfrage abbrechen (sanft — die Sitzung bleibt verbunden):
SELECT pg_cancel_backend(12345);

-- 3. Wenn das nicht reicht, die Verbindung schließen:
SELECT pg_terminate_backend(12345);

Welches, wann

SituationVerwenden
Eine Abfrage ist langsam / blockiert andere, die Session ist ansonsten in Ordnungpg_cancel_backend
Session hängt idle in transaction und hält Sperren (nichts läuft, das abgebrochen werden könnte)pg_terminate_backend — Cancel bewirkt hier nichts: es gibt keine Abfrage zum Abbrechen, es ist die offene Transaktion, die schadet
Durchgehende Session, die sich neu verbindet und die Abfrage erneut absetztTerminate, dann den Client reparieren — es in einer Schleife zu killen ist keine Strategie

Beide geben true zurück, wenn das Signal gesendet wurde (keine Garantie, dass die Abfrage sofort starb — Abbruch wird an sicheren Punkten geprüft, sodass eine Abfrage, die in einem nicht unterbrechbaren Kernel-Aufruf feststeckt, einen Moment brauchen kann). Das Opfer erhält SQLSTATE 57014 („canceling statement due to user request") oder, wenn terminiert, sieht sein Client den Verbindungsabbruch.

Massenbereinigung, sorgfältig durchgeführt

-- Alle "idle in transaction"-Sitzungen älter als 10 Minuten beenden:
SELECT pid, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle in transaction'
  AND xact_start < now() - interval '10 minutes';

Führen Sie das SELECT zuerst ohne den pg_terminate_backend-Aufruf aus und lesen Sie die Liste — dann, und erst dann, fügen Sie das Kill hinzu. Für eine dauerhafte Lösung setzen Sie idle_in_transaction_session_timeout, statt dies bei jedem Zwischenfall von Hand auszuführen.

Was man niemals tun sollte

Killen Sie einen PostgreSQL-Backend-Prozess niemals mit kill -9 aus der Shell. Ein per SIGKILL beendetes Backend kann seinen Shared-Memory-Zustand nicht aufräumen, sodass der Postmaster Korruption annehmen muss und den gesamten Cluster neu startet, alle trennt und WAL erneut abspielt. Was wie das Killen einer einzelnen Abfrage aussah, wird zu einem vollständigen Ausfall. Ein einfaches kill <pid> (SIGTERM) entspricht pg_terminate_backend und ist akzeptabel, wenn Sie keine Verbindung bekommen — aber die SQL-Funktionen sind stets vorzuziehen, weil sie nicht den falschen Prozess treffen können.

Berechtigungen: Sie können Ihre eigenen Sessions stets abbrechen/terminieren; für die Sessions anderer Benutzer benötigen Sie Mitgliedschaft in pg_signal_backend (oder Superuser).

🔍 Killen Sie jede Woche dieselbe Abfrage? Visualisieren Sie ihren Plan mit dem EXPLAIN Visualizer und reparieren Sie sie ein für alle Mal — oder setzen Sie einen statement_timeout davor.