프로그래밍/서버, DBMS

PostgreSQL idle_in_transaction_session_timeout 기준 정리

포도알77 2026. 6. 29. 11:47

PostgreSQL idle_in_transaction_session_timeout 기준 정리

idle_in_transaction_session_timeout은 트랜잭션을 연 채로 클라이언트 입력을 기다리는 세션을 일정 시간 뒤 종료하는 설정이다. 2026년 6월 29일 기준 PostgreSQL 공식 문서를 보면 기본값은 0이며, 단위를 적지 않으면 밀리초로 해석된다. 이 값은 단순히 오래 걸리는 쿼리를 끊는 용도가 아니라, 열린 트랜잭션이 락을 오래 잡거나 vacuum 진행을 방해해 테이블 bloat를 키우는 상황을 줄이는 데 목적이 있다.

실무에서 자주 헷갈리는 지점은 네 가지다. 실행 시간이 긴 쿼리를 막는 설정인지, 락 대기만 제한하는 설정인지, 트랜잭션 전체 시간을 제한하는 설정인지, 아니면 트랜잭션이 없는 유휴 세션에도 적용되는지다. 이 글은 idle_in_transaction_session_timeout의 의미와 statement_timeout, lock_timeout, transaction_timeout, idle_session_timeout과의 차이만 정리한다.

idle_in_transaction_session_timeout은 언제 동작할까?

이 설정은 세션이 열린 트랜잭션 안에서 아무 쿼리도 보내지 않은 채 대기 상태일 때만 동작한다. 즉, BEGIN 이후 애플리케이션이 다음 명령을 보내지 못하고 멈췄거나, 사용자가 트랜잭션을 열어 둔 채 세션을 방치한 상황이 대상이다.

반대로 현재 쿼리가 계속 실행 중이라면 이 설정이 아니라 statement_timeout이 관련 있고, 락을 기다리는 중이라면 lock_timeout 또는 statement_timeout이 먼저 의미를 가진다. 트랜잭션이 아예 열려 있지 않은 일반 idle 연결에는 이 설정이 적용되지 않는다.

왜 운영에서 신경 써야 할까?

PostgreSQL 공식 문서는 idle 상태의 열린 트랜잭션이 오랫동안 락을 보유할 수 있다고 설명한다. 또한 눈에 띄는 락이 없더라도, 아직 해당 트랜잭션에서 볼 수 있는 죽은 튜플을 vacuum이 정리하지 못해 테이블 bloat에 기여할 수 있다고 명시한다.

즉 문제의 핵심은 "아무 일도 안 하는 연결"처럼 보여도 데이터베이스 내부에서는 정리 작업과 동시성 제어를 오래 막을 수 있다는 점이다. 특히 커넥션 풀 뒤에 있는 애플리케이션에서 예외 처리 누락으로 트랜잭션이 열린 채 반환되면, 장애 징후가 천천히 쌓이는 형태로 나타날 수 있다.

비슷한 timeout과 무엇이 다를까?

설정 대상 끊는 시점 주된 목적
statement_timeout 개별 SQL 문 실행 문 실행 시간이 기준을 넘을 때 너무 오래 실행되는 쿼리 제한
lock_timeout 락 획득 대기 락 대기 시간이 기준을 넘을 때 블로킹 대기 제한
transaction_timeout 트랜잭션 전체 수명 트랜잭션 지속 시간이 기준을 넘을 때 너무 긴 트랜잭션 자체 제한
idle_in_transaction_session_timeout 열린 트랜잭션 안의 idle 세션 트랜잭션 안에서 유휴 시간이 기준을 넘을 때 idle 트랜잭션이 락과 vacuum을 방해하는 상황 제한
idle_session_timeout 트랜잭션이 없는 idle 세션 일반 idle 시간이 기준을 넘을 때 불필요하게 남은 연결 정리

운영에서 가장 중요한 구분은 idle_in_transaction_session_timeout이 "일하지 않는 트랜잭션"을 겨냥한다는 점이다. 오래 실행되는 분석 쿼리나 배치 쿼리를 막고 싶다면 이 값만으로는 부족하고, 그 경우에는 statement_timeout이나 현재 문서 기준의 transaction_timeout을 같이 검토해야 한다.

어떤 값부터 시작하는 편이 무난할까?

공식 문서는 기본값과 동작만 정의하고, 특정 숫자를 권장하지는 않는다. 따라서 안전한 출발점은 애플리케이션이 정상적으로 열어 둘 수 있는 트랜잭션 유휴 시간을 먼저 파악한 뒤 그보다 조금 긴 값으로 시작하는 것이다.

상황 출발점 이유
웹 애플리케이션의 일반 요청 처리 수십 초 ~ 수분 단위 검토 정상 요청에서 트랜잭션을 열고 오래 멈춰 있을 이유가 드묾
관리 콘솔, 수동 SQL 작업 조금 더 긴 값 또는 별도 역할 분리 사람이 직접 판단하며 중간에 멈출 가능성이 있음
배치, ETL, 마이그레이션 전역 기본값보다 역할별 예외 검토 긴 트랜잭션과 중간 대기가 설계상 필요할 수 있음

무난한 운영 방식은 전체 서버에 매우 공격적인 값을 바로 거는 대신, 먼저 애플리케이션 역할이나 사용자별로 보수적으로 적용해 보는 것이다. 정상 플로우에서 timeout이 자주 나면 값이 너무 낮거나, 애플리케이션이 트랜잭션 경계를 불필요하게 길게 잡고 있을 가능성을 같이 봐야 한다.

어디에 적용해야 할까?

이 설정은 세션 단위로도 바꿀 수 있고, 역할이나 데이터베이스 단위 기본값으로도 운영할 수 있다. 실무에서는 공용 서버 전체에 동일한 값을 강제하기보다, 애플리케이션용 역할과 수동 운영용 역할을 나눠 서로 다른 기준을 두는 방식이 더 다루기 쉽다.

예를 들어 애플리케이션 계정에는 보수적인 값을 두고, 운영자가 접속하는 계정은 더 긴 값이나 별도 정책을 쓰면 예기치 않은 세션 종료를 줄이기 쉽다. 반대로 psql로 수동 작업하는 계정까지 짧은 값을 공통 적용하면, 긴 검토 도중 세션이 끊기는 불편이 생길 수 있다.

이 설정만 넣으면 긴 트랜잭션 문제가 끝날까?

그렇지는 않다. 이 값은 "idle인 상태"만 겨냥한다. 긴 쿼리를 계속 실행하는 세션, 커밋하지 않은 채 활발히 작업하는 긴 트랜잭션, 락 경합으로 반복 재시도하는 애플리케이션 문제는 다른 timeout이나 애플리케이션 수정이 필요할 수 있다.

또한 현재 PostgreSQL 18 공식 문서 기준으로 transaction_timeout이 더 짧거나 같으면 더 긴 idle_in_transaction_session_timeout이나 statement_timeout은 무시된다. 여러 timeout을 함께 쓸 때는 어느 값이 먼저 발동할지 순서를 의도적으로 잡아야 한다.

자주 헷갈리는 질문

Q. 커넥션 풀을 쓰면 이 설정이 필요 없을까?

그렇게 볼 수는 없다. 오히려 풀 환경에서는 애플리케이션 버그로 열린 트랜잭션이 풀에 남아 재사용되는 문제가 더 위험할 수 있다. 이 설정은 그런 세션이 오래 남는 시간을 제한하는 안전장치 역할을 할 수 있다.

Q. 오래 실행되는 SELECT도 이 값으로 끊을 수 있을까?

아니다. 쿼리가 실제로 실행 중이면 idle 상태가 아니므로 idle_in_transaction_session_timeout 대상이 아니다. 오래 걸리는 문 실행은 statement_timeout을 봐야 한다.

Q. 락 대기만 오래 걸리는 경우에도 이 값이 먼저 동작할까?

일반적으로는 그렇지 않다. 락 대기는 idle이 아니라 문 실행 과정의 일부이므로 lock_timeout이나 statement_timeout이 더 직접적인 제어 수단이다.

Q. 트랜잭션이 없는 idle 연결도 같이 정리하고 싶다면?

그 경우에는 idle_session_timeout을 별도로 검토해야 한다. 두 설정은 이름이 비슷하지만 적용 대상이 다르다.

정리

idle_in_transaction_session_timeout은 느린 쿼리를 잡는 설정이 아니라, 열린 트랜잭션 안에서 멈춰 버린 세션이 락과 vacuum을 오래 방해하지 못하게 하는 장치다. 따라서 웹 애플리케이션이나 API 서버처럼 트랜잭션을 짧게 끝내야 하는 워크로드에서는 기본 검토 대상이 되지만, 수동 작업이나 장시간 배치가 많은 계정에는 같은 값을 그대로 적용하기 어렵다.

핵심 기준은 세 가지다. 정상 플로우에서 트랜잭션이 idle로 머무를 수 있는 시간이 얼마나 되는지, 긴 트랜잭션이 필요한 역할이 분리돼 있는지, 그리고 statement_timeout·lock_timeout·transaction_timeout과 어떤 순서로 맞물리게 할지다.

참고 자료

반응형
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사