kill -9 un proceso de postgres

25

Una consulta SELECT de postgres se salió de control en nuestro servidor DB y comenzó a consumir toneladas de memoria e intercambio hasta que el servidor se quedó sin memoria. Encontré el proceso particular a través ps aux | grep postgresy corrí kill -9 pid. Esto mató el proceso y la memoria se liberó como se esperaba. El resto del sistema y las consultas de postgres parecían no verse afectadas. Este servidor ejecuta postgres 9.1.3 en SLES 9 SP4.

Sin embargo, uno de nuestros desarrolladores me criticó por matar un proceso de postgres kill -9, diciendo que eliminará todo el servicio de postgres. En realidad, no fue así. Lo he hecho antes varias veces y no he visto ningún efecto secundario negativo.

Dicho esto, y después de leer más, parece que kill pidsin las banderas es la forma preferida de matar un proceso de postgres fuera de control, pero por otros usuarios en la comunidad de postgres, también parece que los postgres han "mejorado" a lo largo de los años, de modo que kill -9en un proceso de consulta individual / hilo ya no es una sentencia de muerte.

¿Puede alguien iluminarme sobre la forma correcta de matar un proceso de postgres fuera de control, así como el uso desastroso (o benigno) kill -9con Postgres en estos días? Gracias por la perspicacia.

Banjer
fuente

Respuestas:

31

La respuesta de voretaq7 cubre los puntos clave, incluida la forma correcta de terminar los backends, pero me gustaría agregar un poco más de explicación.

kill -9(es decir SIGKILL) nunca, nunca, debería ser su opción predeterminada por primera vez . Debería ser su último recurso cuando el proceso no responde a sus solicitudes de apagado normales y a SIGTERM( kill -15) no ha tenido ningún efecto. Eso es cierto para Pg y casi todo lo demás.

kill -9 no le da ninguna oportunidad al proceso final de realizar ninguna limpieza.

Cuando se trata de PostgreSQL, Pg ve un respaldo que termina kill -9como un bloqueo respaldado . Sabe que el backend podría haber dañado la memoria compartida, porque podría haberlo interrumpido a mitad de camino al escribir una página en shm o modificar una, por ejemplo, por lo que termina y reinicia todos los demás backend cuando se da cuenta de que un backend se ha desvanecido repentinamente y salió con un código de error distinto de cero.

Verá esto informado en los registros.

Si parece no hacer daño, eso se debe a que Pg está reiniciando todo después del bloqueo y su aplicación se está recuperando limpiamente de las conexiones perdidas. Eso no lo hace una buena idea. Si nada más, los bloqueos del backend están menos probados que las partes de funcionamiento normal de Pg y son mucho más complicados / variados, por lo que las posibilidades de un error al acecho en el manejo y la recuperación del crash del backend son mayores.

Por cierto, si usted es kill -9el administrador de correo, elimínelo postmaster.pidy vuelva a iniciarlo sin asegurarse de que todos los postgresservidores hayan desaparecido, pueden suceder cosas muy malas . Esto podría suceder fácilmente si accidentalmente eliminó al administrador de correo en lugar de un servidor, vio que la base de datos se había caído, intentó reiniciarlo, eliminó el archivo .pid "obsoleto" cuando el reinicio falló e intentó reiniciarlo nuevamente. Esa es una de las razones por las que debe evitar agitar la página kill -9y no debe eliminarla postmaster.pid.

Una demostración:

Para ver exactamente qué sucede cuando kill -9un back-end, intente estos simples pasos. Abra dos terminales, abra psql en cada una y en cada ejecución SELECT pg_backend_pid();. En otro terminal, kill -9uno de los PID. Ahora ejecute SELECT pg_backend_pid();en ambas sesiones psql nuevamente. ¿Notan cómo ambos perdieron sus conexiones?

Sesión 1, que matamos:

$ 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)

Sesión 2, que fue daño colateral:

$ 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)

¿Ves cómo se rompieron ambas sesiones? Por eso no tienes kill -9un backend.

Craig Ringer
fuente
1
Todas muy buenas respuestas aquí, y muy humillante, podría agregar. Podría marcarlos a todos como aceptados, pero @ Craig Ringer tiene algunos puntos extra aquí y realmente lo lleva a casa. Gracias de nuevo SF por limpiarme de mis malos hábitos.
Banjer
2
@ Craig: Qué excelente respuesta; e incluir una demostración, desearía poder votar este 100x. Soy un desarrollador de software que trabaja con PG diariamente y desde los 6.x días y su respuesta es acertada. ¡Agradable!
Kilo
2
Buena respuesta. Un apéndice: si tiene un proceso de backend que no morirá absolutamente pg_terminate_backend; no con un reinicio de la pila del servidor, ni con nada, puede eliminarlo como quiera, pero asegúrese de tener una copia de seguridad de su base de datos. Puede hacerlo de dos maneras: puede usar pg_basebackupo similar (o simplemente rsyncy pg_start\stop_backup) para hacer una copia de seguridad de su directorio de datos (pruebe las copias de seguridad antes de continuar), o puede usarlo pg_dump[all]para recuperar sus datos. Solo entonces debería considerar kill -9, o reiniciar, o lo que sea.
Zac B
1
@ZacB Sí, y si lo matas, asegúrate de que todos los backends mueran. Lo más importante, nunca borre postmaster.pid. Siempre.
Craig Ringer
29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
¡NO! ¡MALO! PASO LEJOS DEL FONDO!

En serio: no elimines los backends de Postgres de esa manera: pueden suceder cosas TERRIBLES (incluso con todas las mejoras de estabilidad que se han realizado desde los días 7.x) que pueden destruir toda tu base de datos, y tu desarrollador tiene toda la razón para masticar Estás fuera por hacer esto.

De hecho, hay una manera bendecida y aprobada de hacer esto desde Postgres : incluso en el manual de Postgres, esa publicación SO hace un mejor trabajo al explicarlo ...

SELECT pg_cancel_backend(pid)
Envía una SIGINTseñal cancel ( ) al backend especificado, que cancela la consulta actualmente en ejecución.

select pg_terminate_backend(pid)
Envía una SIGTERMseñal terminate ( ) al backend especificado, que cancela la consulta y aborta el backend (desconectando su conexión).

Los ID de backend se pueden obtener de la pg_stat_activitytabla (o ps)

voretaq7
fuente
44
En caso de que alguien se pregunte acerca de las cosas terribles, dado que kill -9no es diferente a apagar repentinamente el sistema en lo que respecta al proceso finalizado: Pg es muy tolerante con los bloqueos de fondo (como a kill -9) y nunca debe haber corrupción de datos. No habrá ser la corrupción si matas al jefe de correos , postmaster.pid de extraer, lo reinicia sin matar también todos los backend primero. Eso será destruir su base de datos, pero tiene mucho más que un simple kill -9a un backend. kill -9no le da tiempo al administrador de correo para matar los backends, por eso es peligroso.
Craig Ringer el
2
... como un caso de consulta de emergencia que tuve la semana pasada. Corrompió gravemente su base de datos, perdió dos días de trabajo porque sus copias de seguridad fallaban (y no probaron automáticamente sus restauraciones), estuvieron inactivas durante 48 horas. No elimine postmaster.pid.
Craig Ringer
8

Matar un proceso de cliente PostgreSQL debería estar bien. Matar un proceso de demonio PostgreSQL podría hacerte regañar.

Dado que los demonios SQL también tienen controles de proceso internos, la forma preferida es intentar usar ese canal primero.

Consulte Detener (larga) la ejecución de una consulta SQL en PostgreSQL ... desde StackOverflow.

Jeff Ferland
fuente
44
kill -9De todos modos, nunca debería ser su opción predeterminada, es un último recurso. Envíe un SIGTERMcon kill -TERMo simple killy si el destinatario no responde después de un tiempo, solo entonces debe considerar kill -KILL( kill -9).
Craig Ringer el