idle_in_transaction_session_timeout
| 버전 | 기본값 | context | 타입 |
|---|---|---|---|
| 14 | — | user | integer |
| 15 | — | user | integer |
| 16 | — | user | integer |
| 17 | — | user | integer |
| 18 | — | user | integer |
| 19 | — | user | integer |
transaction을 열어 둔 채 idle 상태(client의 다음 쿼리를 기다리는 상태)로 지정한 시간보다 오래 머문 session을 강제 종료한다. 단위 없이 값을 주면 밀리초로 해석하며, 기본값 0은 timeout을 끈다.
열린 채 방치된 transaction이 위험한 이유는 두 가지다. 첫째, transaction이 잡아 둔 lock은 commit이나 rollback 전까지 풀리지 않는다. idle in transaction session이 테이블 lock을 쥔 채 멈춰 있으면 그 테이블을 기다리는 ALTER TABLE 같은 DDL이 대기하고, lock queue 특성상 그 뒤에 줄 선 평범한 쿼리들까지 연쇄적으로 막힐 수 있다. 둘째, 눈에 띄는 lock이 없더라도 열린 transaction은 자신에게 보일 수 있는, 최근에 지워진 row 버전을 vacuum이 제거하지 못하게 막는다. 이런 session이 오래 남아 있으면 vacuum이 계속 헛돌면서 table bloat가 누적된다.
이 timeout에 걸리면 쿼리만 취소되는 것이 아니라 session 자체가 종료된다는 점에 주의해야 한다. 애플리케이션 입장에서는 connection이 끊기는 것이므로 재접속 처리가 필요하다.
운영 노트: ORM이나 프레임워크가 transaction을 열고 commit을 잊는 사고는 생각보다 흔하다.
pg_stat_activity에서 state = 'idle in transaction'인 session의 지속 시간을 모니터링하고, 이 파라미터를 워크로드에 맞는 값(예: 수 분)으로 설정해 두면 bloat와 lock 대기 사고를 예방할 수 있다. 정상적으로 긴 transaction을 쓰는 배치 계정에는 role 단위로 다른 값을 주면 된다.출처: PostgreSQL 18 문서