DBAtlas · Atlas de operações de banco de dados

Encerrar em massa, de forma controlada, sessões 'idle in transaction' longas

PostgreSQLSessões

Comando

-- 1) Dry run first: who will be affected?
SELECT pid, usename, application_name, client_addr,
       now() - state_change AS idle_for, left(query, 80) AS last_query
FROM pg_stat_activity
WHERE state IN ('idle in transaction', 'idle in transaction (aborted)')
  AND now() - state_change > interval '15 minutes'
  AND backend_type = 'client backend'
  AND pid <> pg_backend_pid();

-- 2) Terminate; wait up to 5 s for each process to exit
SELECT pid, usename, now() - state_change AS idle_for,
       pg_terminate_backend(pid, 5000) AS terminated
FROM pg_stat_activity
WHERE state IN ('idle in transaction', 'idle in transaction (aborted)')
  AND now() - state_change > interval '15 minutes'
  AND backend_type = 'client backend'
  AND pid <> pg_backend_pid();

O que faz

Primeiro lista as sessões que deixaram uma transação aberta e ociosa por um tempo determinado e depois as encerra; o parâmetro timeout espera até que o processo tenha de fato saído (ou o timeout expire).

Quando usar

Para intervenção de emergência quando sessões esquecidas segurando locks causam bloqueio ou seguram o xmin horizon e travam o VACUUM.

Atenção

pg_cancel_backend não faz nada em uma sessão 'idle in transaction' (não há consulta em execução para cancelar); é necessário pg_terminate_backend, e todas as mudanças não confirmadas sofrem rollback. Restrinja o filtro por usename/application_name; exclua sessões de replicação, backup e monitoramento. Os pools de conexões reabrirão as conexões encerradas. Se o timeout expirar, a função emite um aviso e retorna false. Como correção permanente, defina idle_in_transaction_session_timeout por role.

Abrir no DBAtlas →

Relacionados