DBAtlas · 데이터베이스 운영 아틀라스

장시간 'idle in transaction' 세션을 통제된 방식으로 일괄 종료

PostgreSQL세션

명령어

-- 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();

하는 일

먼저 트랜잭션을 열어 둔 채 일정 시간 idle 상태인 세션을 나열한 후 종료한다. timeout 파라미터는 프로세스가 실제로 종료될 때까지(또는 timeout 만료까지) 대기한다.

사용 시점

락을 잡고 잊힌 세션이 블로킹을 일으키거나 xmin horizon을 붙잡아 VACUUM을 멈추게 할 때의 긴급 조치용.

주의

pg_cancel_backend는 'idle in transaction' 세션에는 아무 효과가 없다(취소할 실행 중 쿼리가 없음). pg_terminate_backend가 필요하며 커밋되지 않은 모든 변경이 롤백된다. usename/application_name으로 필터를 좁히고 복제, 백업, 모니터링 세션은 제외한다. 커넥션 풀은 종료된 연결을 다시 연다. timeout이 만료되면 함수는 경고를 내고 false를 반환한다. 영구 해결책으로 롤별 idle_in_transaction_session_timeout을 설정한다.

DBAtlas에서 열기 →

관련 항목