Consultar y finalizar los procesos activos en PostgreSQL

reset css

¿Cómo ver las consultas activas en PostgreSQL?

La información de los procesos que están en ejecución en postgres la podemos obtener de pg_stat_activity simplemente haciendo un select como este:


SELECT 
    datid, datname, pid, usesysid, usename,
    application_name, client_addr, client_hostname, client_port, 
    backend_start, xact_start, query_start, state_change, 
    wait_event_type, wait_event, state, backend_xid,
    backend_xmin, query, backend_type	
FROM pg_stat_activity 
WHERE state != 'idle' 
	AND datname = 'mi_bd';

No es necesario aplicar ningún filtro aunque normalmente no nos va a interesar ver las conexiones que están inactivas (state=’idle’) y si tenemos varias bases de datos probablemente también queramos quedarnos solo con la que nos interesa.

Esta consulta nos devuelve bastante información interesante sobre cada proceso ya que podemos ver la query que se está ejecutando (columna query), el estado en el que se encuentra (state), la fecha en la que empezo a ejecutarse (query_start), la ip desde la que se lanzó (client_addr), el usuario de BD (usename), … y con toda esta información podemos detectar si hay algún problema y cuál es la causa.

¿Cómo matar una consulta activa en PostgreSQL?

En un mundo ideal no deberíamos de tener la necesidad de terminar manualmente un proceso, pero es una circunstancia que nos puede ocurrir si detectamos que alguna consulta está bloqueada, va a tardar demasiado tiempo en terminar y está ralentizando el resto de consultas o simplemente nos hemos equivocado al hacer la query y no va a terminar nunca o sospechamos que va a consumir toda la memoria de la base de datos o cualquier otra cosa.

La consulta para terminar, matar, cancelar o como lo quieras llamar un proceso en postgres es SELECT pg_terminate_backend(pid);, el pid le podemos obtener de la consulta anterior o para hacerlo más rapido podemos utilizarla en combinación con la consulta anterior.


SELECT
    'SELECT pg_terminate_backend(' || pid ||');' AS matar_consulta, query_start, query, state, wait_event_type, usename, application_name, client_addr
FROM pg_stat_activity 
WHERE state != 'idle' 
	AND datname = 'mi_bd';

Y con el resultado obtenido pues ejecutamos la consultas para matar los procesos que consideremos, también se puede ejecutar directamente SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE ... aunque corremos el riesgo de finalizar procesos que no queramos si no filtramos correctamente.