Frage kill -9 ein Postgres-Prozess


Eine Postgres-SELECT-Abfrage lief auf unserem DB-Server außer Kontrolle und begann, viel Speicher zu verbrauchen und auszutauschen, bis der Server nicht mehr genügend Speicher hatte. Ich habe den bestimmten Prozess via gefunden ps aux | grep postgres und rannte kill -9 pid. Dadurch wurde der Prozess beendet und der Speicher wie erwartet freigegeben. Der Rest der System- und Postgres-Abfragen schien nicht betroffen zu sein. Auf diesem Server läuft postgres 9.1.3 auf SLES 9 SP4.

Einer unserer Entwickler hat mich jedoch dafür geküßt, einen Postgres-Prozess mit ihm zu beenden kill -9, sagen, dass es den gesamten postgres-Dienst herunternehmen wird. In Wirklichkeit hat es nicht. Ich habe das schon einige Male gemacht und habe keine negativen Nebenwirkungen gesehen.

Mit diesem gesagt, und nach weiterem Lesen, sieht es so aus kill pid Ohne die Flags ist der bevorzugte Weg, um einen außer Kontrolle geratenen Postgres-Prozess zu töten, aber für andere Benutzer in der Postgres-Community klingt es auch, als sei Postgres im Laufe der Jahre "besser geworden" kill -9 auf einen einzelnen Abfrageprozess / Thread ist kein Todesurteil mehr.

Kann jemand mich über den richtigen Weg aufklären, um einen außer Kontrolle geratenen Postgres-Prozess sowie die wie katastrophale (oder gutartige) Verwendung zu töten kill -9 ist mit Postgres in diesen Tagen? Danke für die Einsicht.


22
2017-08-07 17:09


Ursprung




Antworten:


voretaq7ist es Antworten umfasst die wichtigsten Punkte, einschließlich der korrekte Art und Weise, Back-Ends zu beenden aber ich möchte ein wenig mehr Erklärung hinzufügen.

kill -9 (dh SIGKILL) sollte niemals, immer, Ihre erste Wahl Standard sein. Es sollte Ihr letzter Ausweg sein, wenn der Prozess nicht auf seine normalen Shutdown-Anfragen reagiert und a SIGTERM (kill -15) hatte keine Wirkung. 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, Pg sieht ein Backed, das durch beendet wird kill -9 als Rückstoß. Es weiß, dass das Backend Shared Memory beschädigt haben könnte - weil Sie es auf halbem Weg durch das Schreiben einer Seite in shm oder das Modifizieren von einem zum Beispiel unterbrochen haben könnten - so beendet und startet alle anderen Backends neu wenn es bemerkt, dass ein Backend plötzlich verschwunden ist und mit einem Fehlercode ungleich null beendet wurde.

Sie werden dies in den Protokollen sehen.

Wenn es scheinbar keinen Schaden anrichtet, weil Pg nach dem Absturz alles neu startet und Ihre Anwendung sich sauber von den verlorenen Verbindungen erholt. Das ist keine gute Idee. Wenn nichts anderes als Backend-Abstürze weniger gut getestet werden als die normal funktionierenden Teile von Pg und viel komplizierter sind, so sind die Chancen, dass ein Bug in der Backend-Crash-Behandlung und -Wiederherstellung lauert, höher.

Übrigens, wenn du kill -9 der Postmaster dann entfernen postmaster.pid und fange wieder an, ohne sicherzugehen, dass alle postgres Backend ist weg, sehr schlimme Dinge können passieren. Dies könnte leicht passieren, wenn Sie versehentlich den Postmaster anstelle eines Backends getötet, die Datenbank heruntergefahren, versucht haben, sie neu zu starten, die "veraltete" .pid-Datei entfernt haben, als der Neustart fehlgeschlagen ist, und versucht haben, sie erneut zu starten. Das ist einer der Gründe, warum Sie vermeiden sollten zu winken kill -9um Pg, und sollte nicht löschen postmaster.pid.

Eine Demonstration:

Um genau zu sehen, was bei dir passiert kill -9 ein Backend, versuchen Sie diese einfachen Schritte. Öffnen Sie zwei Terminals, öffnen Sie psql in jedem und in jedem Lauf SELECT pg_backend_pid();. In einem anderen Terminal kill -9 eine der PIDs. Jetzt lauf SELECT pg_backend_pid(); in beiden psql Sitzungen wieder. Beachten Sie, wie sie beide ihre Verbindungen verloren?

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 Kollateralschäden 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)

Siehe wie beide Sitzungen wurden gebrochen? Deshalb tust du es nicht kill -9 ein Backend.


29
2017-08-08 23:57



Alles sehr gute Antworten hier, und sehr demütigend könnte ich hinzufügen. Ich könnte sie alle als akzeptiert markieren, aber @Craig Ringer hat hier einige Extrapunkte und treibt es wirklich homw. Nochmals vielen Dank SF für die Reinigung meiner schlechten Gewohnheiten! - Banjer
@Craig: Was für eine großartige Antwort; und um eine Demonstration zu haben, 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 deine Antwort genau richtig! Nett! - Kilo
Gute Antwort. Ein Addendum: Wenn Sie einen Backend-Prozess haben, der absolut nicht stirbt - nicht mit pg_terminate_backend, nicht mit einem Server-Stack-Neustart, nicht mit irgendetwas, Sie können es töten, wie Sie wollen, aber stellen Sie sicher, dass Sie eine funktionierende Sicherung Ihrer Datenbank haben. Sie können das auf verschiedene Arten tun: Sie können es verwenden pg_basebackup oder ähnlich (oder einfach rsync und pg_start\stop_backup), um Ihr Datenverzeichnis zu sichern (Testen Sie die Backups, bevor Sie fortfahren!), oder Sie können verwenden pg_dump[all] um Ihre Daten zu retten. Nur dann solltest du darüber nachdenken kill -9oder ein Neustart oder was auch immer. - Zac B
@ ZacB Ja, und wenn Sie es töten, stellen Sie sicher alles die Backends sterben. Am wichtigsten, noch nie löschen postmaster.pid. Je. - Craig Ringer


I found the particular process via ps aux | grep postgres and ran kill -9 pid.
NEIN! SCHLECHT! WEG VON DER RÜCKSEITE!

Ernsthaft - töte Postgres-Backends nicht so - es können schreckliche Dinge passieren (sogar mit all den Stabilitätsverbesserungen, die seit den 7.x Tagen gemacht wurden), die deine gesamte DB zerstören können, und dein Entwickler ist völlig richtig zu kauen Sie dafür aus.

Es gibt tatsächlich Eine gesegnete und bewährte Art, dies innerhalb von Postgres zu tun - Es ist sogar in der Postgres-Handbuch obwohl diese SO-Post sie besser erklären kann ...

SELECT pg_cancel_backend(pid)
Sendet einen Abbruch (SIGINT) Signal an das angegebene Backend, das die gerade laufende Abfrage abbricht.

select pg_terminate_backend(pid)
Sendet ein Ende (SIGTERM) Signal an das angegebene Backend, welches die Anfrage abbricht und das Backend abbricht (Verbindung wird abgebrochen).

Backend-IDs erhalten Sie von der pg_stat_activity Tabelle (oder ps)


28
2017-08-07 17:43



Falls sich jemand über die schrecklichen Dinge wundern sollte kill -9 Es ist nicht unähnlich, das System plötzlich auszuschalten, soweit es den getöteten Prozess betrifft: Pg ist sehr tolerant gegenüber Backend - Abstürzen (wie ein kill -9) und es sollte nie zu Datenkorruption kommen. Dort werden sei Korruption, wenn du das tötest Postmeisterentferne postmaster.pid und starte es neu, ohne vorher auch jedes Backend zu beenden. Das werden zerstören Sie Ihre Datenbank, aber nimmt viel mehr als nur ein kill -9 zu einem Backend. kill -9 gibt dem Postmeister nicht die Zeit, die Backends zu töten, weshalb es gefährlich ist. - Craig Ringer
... wie eine Notfallberatung, die ich letzte Woche gemacht habe. Ihre Datenbank wurde stark beschädigt, zwei Arbeitstage gingen verloren, weil ihre Sicherungen fehlgeschlagen waren (und ihre Wiederherstellungen wurden nicht automatisch getestet). Sie waren 48 Stunden lang inaktiv. Löschen Sie nicht postmaster.pid. - Craig Ringer


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

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

Sehen Stoppen Sie (lange) SQL-Abfrage in PostgreSQL ... von StackOverflow.


8
2017-08-07 17:20



kill -9 sollte sowieso nie deine Standardwahl sein, es ist ein letzter Ausweg. Sende ein SIGTERM mit kill -TERM oder einfach kill und wenn der Empfänger nach einer Weile nicht mehr reagiert, sollten Sie nur nachdenken kill -KILL (kill -9). - Craig Ringer