umzzil nng Posted on May 30 • Originally published at oraerror.com PostgreSQL 08003 오류 원인과 해결 방법 완벽 가이드 # postgres # database # dba # sql 08003 connection does not exist 는? PostgreSQL 에러 코드 08003 은 클라이언트가 이미 존재하지 않는 데이터베이스 연결을 통해 쿼리나 트랜잭션 명령을 실행하려 할 때 발생합니다. 쉽게 말해, 연결이 서버 측에서 이미 종료되었거나 끊어진 상태인데 클라이언트는 그 사실을 인지하지 못한 채 해당 연결을 계속 사용하려는 상황입니다. 주로 커넥션 풀 환경, 장시간 유휴 상태의 연결, 또는 PREPARE TRANSACTION 과 관련된 2단계 커밋(Two-Phase Commit) 흐름에서 자주 목격되는 에러입니다. 주요 발생 원인 1. 커넥션 풀에서 이미 끊어진 유휴 연결 재사용 PgBouncer, HikariCP, pg_pool 등 커넥션 풀러는 내부적으로 연결을 캐싱해두고 재사용합니다. PostgreSQL 서버 측에서 idle_in_transaction_session_timeout 또는 tcp_keepalives_idle 설정에 의해 해당 연결이 강제로 끊겼더라도, 풀러는 연결이 살아있다고 착각하고 애플리케이션에 해당 연결을 넘겨줄 수 있습니다. 이때 클라이언트가 쿼리를 실행하려 하면 08003 에러가 즉시 발생합니다. 2. 2단계 커밋(Two-Phase Commit)에서 잘못된 트랜잭션 ID 참조 PREPARE TRANSACTION 으로 준비된 트랜잭션은 고유한 식별자(GID)를 가지며, 이후 별도의 세션에서 COMMIT PREPARED 또는 ROLLBACK PREPARED 를 통해 완료해야 합니다. 이미 커밋되거나 롤백된 prepared 트랜잭션 GID를 다시 참조하거나, 해당 세션 자체가 사라진 뒤 연결을 통해 명령을 보내면 서버는 대응할 연결 컨텍스트가 없기 때문에 08003 을 반환합니다. 분산 트랜잭션 처리 코드에서 예외 처리 미흡 시 특히 자주 발생합니다. 3. 네트워크 장애 또는 서버 재시작 후 연결 상태 불일치 방화벽 타임아웃, 네트워크 순단(intermittent failure), PostgreSQL 서버 재시작 등으로 인해 TCP 연결이 물리적으로 끊어졌음에도 클라이언트 소켓은 여전히 연결된 것처럼 보이는 "half-open" 상태가 될 수 있습니다. 이 상태에서 클라이언트가 명령을 전송하면, 서버는 해당 연결 슬롯이 더 이상 존재하지 않으므로 08003 을 반환하거나 연결 자체가 즉시 drop됩니다. 해결 방법 원인 1 해결: 커넥션 풀 유효성 검사(Validation Query) 설정 커넥션 풀에서 연결을 재사용하기 전에 반드시 연결 유효성을 검사하도록 설정합니다. -- 연결 유효성 검사용 경량 쿼리 (validation query로 사용) SELECT 1 ; -- 현재 유휴 연결 상태 확인 SELECT pid , state , query_start , state_change , query FROM pg_stat_activity WHERE state = 'idle' AND state_change < NOW () - INTERVAL '10 minutes' ; -- 오래된 유휴 연결 강제 종료 (DBA 수동 처리) SELECT pg_terminate_backend ( pid ) FROM pg_stat_activity WHERE state = 'idle' AND state_change < NOW () - INTERVAL '30 minutes' AND pid <> pg_backend_pid (); Enter fullscreen mode Exit fullscreen mode HikariCP를 사용하는 경우 connectionTestQuery=SELECT 1 과 keepaliveTime=30000 (30초)을 설정하고, PgBouncer를 사용하는 경우 server_check_query=select
LIVE
