töte -9 einen Postgres-Prozess

25

Eine SELECT-Abfrage nach Gres ist auf unserem DB-Server außer Kontrolle geraten und hat damit begonnen, Tonnen von Arbeitsspeicher zu verbrauchen und auszutauschen, bis dem Server der Arbeitsspeicher ausgeht. Ich fand den bestimmten Prozess über ps aux | grep postgresund lief kill -9 pid. Dies hat den Prozess abgebrochen und den Speicher wie erwartet freigegeben. Der Rest der System- und Postgres-Abfragen schien nicht betroffen zu sein. Auf diesem Server wird postgres 9.1.3 unter SLES 9 SP4 ausgeführt.

Einer unserer Entwickler hat mich jedoch dafür herausgekaut kill -9, dass ich einen Postgres-Prozess mit beendet habe und sagte, dass dadurch der gesamte Postgres-Service heruntergefahren wird. In Wirklichkeit war das nicht der Fall. Ich habe das schon einige Male gemacht und keine negativen Nebenwirkungen gesehen.

kill pidVor diesem Hintergrund und nach weiterem Lesen sieht es so aus, als wäre es die bevorzugte Methode, einen außer Kontrolle geratenen Postgres-Prozess abzubrechen, aber für andere Benutzer in der Postgres-Community scheint es auch so, als ob Postgres im Laufe der Jahre "besser geworden" ist kill -9Bei einem einzelnen Abfrageprozess / Thread ist kein Todesurteil mehr zu verhängen.

Kann mir jemand erklären, wie man einen außer Kontrolle geratenen Postgres-Prozess richtig beendet und wie katastrophal (oder harmlos) die Verwendung kill -9von Postgres heutzutage ist? Danke für den Einblick.

Banjer
quelle

Antworten:

31

Die Antwort von voretaq7 deckt die wichtigsten Punkte ab, einschließlich der korrekten Beendigung von Backends, aber ich möchte noch eine Erklärung hinzufügen.

kill -9(dh SIGKILL) sollte niemals Ihre erste Wahl sein . Dies sollte Ihr letzter Ausweg sein, wenn der Prozess nicht auf seine normalen Anforderungen zum Herunterfahren reagiert und a SIGTERM( kill -15) keine Auswirkung hat. Das gilt für Pg und so ziemlich alles andere.

kill -9 gibt dem getöteten Prozess keine Chance, überhaupt aufzuräumen.

Wenn es um PostgreSQL geht, sieht Pg einen gesicherten Fehler, der durch kill -9einen gesicherten Absturz beendet wird . Es ist bekannt, dass das Backend den gemeinsam genutzten Speicher möglicherweise beschädigt hat, da Sie es möglicherweise während des Schreibens einer Seite in shm oder des Änderns einer Seite unterbrochen haben. Daher werden alle anderen Backends beendet und neu gestartet, wenn festgestellt wird, dass ein Backend plötzlich verschwunden ist und mit einem Fehlercode ungleich Null beendet.

Sie sehen dies in den Protokollen.

Wenn es keinen Schaden zu verursachen scheint, weil Pg nach dem Absturz alles neu startet und Ihre Anwendung sich sauber von den verlorenen Verbindungen erholt. Das macht es nicht zu einer guten Idee. Wenn nichts anderes als die normal funktionierenden Teile von Pg weniger gut getestet und viel komplizierter / abwechslungsreicher sind, ist die Wahrscheinlichkeit eines Fehlers, der bei der Behandlung und Wiederherstellung von Back-End-Abstürzen lauert, höher.

Übrigens, wenn Sie kill -9den Postmaster entfernen postmaster.pidund erneut starten, ohne sicherzustellen, dass jedes postgresBackend nicht mehr vorhanden ist, können sehr schlimme Dinge passieren . Dies kann leicht passieren, wenn Sie versehentlich den Postmaster anstelle eines Backends beendet haben, festgestellt haben, dass die Datenbank ausgefallen ist, versucht haben, sie neu zu starten, die "veraltete" PID-Datei entfernt haben, als der Neustart fehlgeschlagen ist, und erneut versucht haben, sie neu zu starten. Das ist einer der Gründe, warum Sie vermeiden sollten, kill -9um Pg zu winken , und nicht löschen sollten postmaster.pid.

Eine Demonstration:

Probieren Sie kill -9diese einfachen Schritte aus, um genau zu sehen, was bei einem Backend passiert . Öffnen Sie zwei Terminals, öffnen Sie psql in jedem und in jedem Lauf SELECT pg_backend_pid();. In einem anderen Terminal kill -9eine der PIDs. Führen Sie nun SELECT pg_backend_pid();beide psql-Sitzungen erneut aus. Beachten Sie, wie sie beide ihre Verbindungen verloren haben?

Sitzung 1, die wir getötet haben:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6357
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6463
(1 row)

Sitzung 2, die Kollateralschaden war:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6283
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6464
(1 row)

Sehen Sie, wie beide Sitzungen unterbrochen wurden? Deshalb gibt es kein kill -9Backend.

Craig Ringer
quelle
1
Alles sehr gute Antworten hier und sehr demütigend, möchte ich hinzufügen. Ich könnte sie alle als akzeptiert markieren, aber @Craig Ringer hat ein paar Extrapunkte und treibt es wirklich nach Hause. Nochmals vielen Dank, SF, dass du mich von meinen schlechten Gewohnheiten befreit hast!
Banjer
2
@Craig: Was für eine großartige Antwort; und um eine Demonstration aufzunehmen, wünschte ich, ich könnte diese 100x abstimmen. Ich bin ein Softwareentwickler, der täglich mit PG arbeitet und seit den 6.x Tagen ist Ihre Antwort genau richtig! Nett!
Kilo
2
Gute Antwort. Ein Nachtrag: Wenn Sie einen Backend-Prozess haben, der absolut nicht zum Erliegen kommt - nicht mit pg_terminate_backend, nicht mit einem Neustart des Server-Stacks, nicht mit irgendetwas, können Sie ihn beenden, wie Sie möchten, aber stellen Sie sicher, dass Sie eine funktionierende Sicherung Ihrer Datenbank haben. Sie können dies auf verschiedene Arten tun: Sie können Ihr Datenverzeichnis mit pg_basebackupo.ä. (oder einfach rsyncund pg_start\stop_backup) sichern (die Sicherungen testen, bevor Sie fortfahren!) Oder Sie können pg_dump[all]Ihre Daten retten. Nur dann sollten Sie überlegen kill -9, einen Neustart oder was auch immer.
Zac B
1
@ZacB Ja, und wenn Sie es töten, stellen Sie sicher, dass alle Backends sterben. Am wichtigsten ist, niemals löschen postmaster.pid. Je.
Craig Ringer
29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
NEIN! SCHLECHT! SCHRITT VOM BACKEND ENTFERNT!

Ernsthaft - Töte Postgres-Backends nicht so - SCHRECKLICHE Dinge können passieren (trotz all der Stabilitätsverbesserungen, die seit den 7.x Tagen vorgenommen wurden), die deine gesamte Datenbank zerstören können, und dein Entwickler hat völlig Recht, darauf zu kauen Sie dafür aus.

Tatsächlich gibt es eine gesegnete und anerkannte Möglichkeit, dies von Postgres aus zu tun - es steht sogar im Postgres-Handbuch, obwohl SO post dies besser erklärt ...

SELECT pg_cancel_backend(pid)
Sendet ein cancel ( SIGINT) -Signal an das angegebene Backend, wodurch die aktuell ausgeführte Abfrage abgebrochen wird.

select pg_terminate_backend(pid)
Sendet ein terminate ( SIGTERM) -Signal an das angegebene Backend, wodurch die Abfrage abgebrochen und das Backend abgebrochen wird (die Verbindung wird getrennt).

Backend-IDs können der pg_stat_activityTabelle (oder ps) entnommen werden.

voretaq7
quelle
4
Falls sich irgendjemand über die schrecklichen Dinge wundert, da dies kill -9nicht unähnlich ist , wenn das System plötzlich ausgeschaltet wird, was den getöteten Prozess betrifft: Pg ist sehr tolerant gegenüber Abstürzen des Backends (wie a kill -9) und es sollte niemals zu Datenkorruption kommen. Es wird Korruption, wenn Sie die töten Postmeister , entfernen postmaster.pid, und es neu starten , ohne auch zuerst jedes Backend zu töten. Das wird Ihre Datenbank zerstören, aber es braucht viel mehr als nur kill -9ein Backend. kill -9gibt dem Postmaster keine Zeit, die Backends zu töten, weshalb es gefährlich ist.
Craig Ringer
2
... wie ein Notfall-Beratungsfall, den ich letzte Woche hatte. Die Datenbank wurde stark beschädigt, zwei Arbeitstage gingen verloren, weil die Sicherungen fehlschlugen (und die Wiederherstellungen nicht automatisch getestet wurden). Sie waren 48 Stunden lang inaktiv. Nicht löschen postmaster.pid.
Craig Ringer
8

Das Beenden eines PostgreSQL-Client-Prozesses sollte in Ordnung sein. Wenn Sie einen PostgreSQL-Daemon-Prozess beenden, werden Sie möglicherweise geschimpft.

Da SQL-Dämonen auch über interne Prozesssteuerungen verfügen, sollten Sie zuerst versuchen, diesen Kanal zu verwenden.

Weitere Informationen finden Sie unter Beenden (langer) Ausführung von SQL-Abfragen in PostgreSQL über StackOverflow.

Jeff Ferland
quelle
4
kill -9sollte sowieso nie deine Standardwahl sein, es ist ein letzter Ausweg. Senden Sie ein SIGTERMwith kill -TERModer plain killund wenn der Empfänger nach einer Weile nicht antwortet, sollten Sie nur überlegen kill -KILL( kill -9).
Craig Ringer