타임아웃이 발생해도 PostgreSQL은 계속 작동합니다
요약
클라이언트 타임아웃이 발생하더라도 PostgreSQL 쿼리는 백엔드에서 계속 실행되어 자원을 점유할 수 있습니다. 따라서 AI 에이전트와 MCP 서버 환경에서는 계층별 타임아웃과 취소 체인을 철저히 테스트하고 데이터베이스 측의 제한 설정을 병행해야 합니다.
핵심 포인트
- 클라이언트 타임아웃이 DB 쿼리 중단을 보장하지 않음
- 계층별(에이전트, MCP, 풀, DB) 타임아웃 체인 확인 필요
- 의도적인 경합 상황을 통한 취소 메커니즘 테스트 권장
- statement_timeout 등 DB 레벨의 제한 설정이 최후의 보루
사용자가 AI 채팅을 종료합니다.
클라이언트에서 타임아웃 (timeout)이 발생합니다.
당신의 MCP 서버는 에러를 반환합니다.
모두가 데이터베이스 쿼리도 중단되었을 것이라고 가정합니다.
그 가정은 비용이 많이 듭니다.
PostgreSQL 쿼리는 그것을 생성한 요청보다 더 오래 지속될 수 있습니다. 사용자는 이미 다른 곳으로 이동했지만, 쿼리는 풀링된 연결 (pooled connection)을 계속 점유하고, 잠금 (locks)을 유지하며, 행을 스캔하고, 용량을 소비할 수 있습니다.
문제는 "타임아웃"이 여러 계층에 존재한다는 점입니다:
- AI 에이전트 (AI agent)에는 마감 기한 (deadline)이 있습니다.
- MCP 전송 계층 (MCP transport)에는 타임아웃이 있습니다.
- 도구 실행기 (tool runner)에는 또 다른 타임아웃이 있습니다.
- 연결 풀 (connection pool)에는 획득 타임아웃 (acquisition timeout)이 있습니다.
- PostgreSQL에는
statement_timeout과lock_timeout이 있습니다. - 프록시 (proxy)가 소켓 (socket)을 먼저 닫을 수도 있습니다.
가장 빠른 시계는 종종 자신의 계층만을 종료할 뿐입니다.
504 에러는 프록시가 기다리는 것을 멈췄음을 증명할 뿐입니다. 그것이 PostgreSQL이 작동을 멈췄음을 증명하지는 않습니다.
전체 취소 체인을 테스트하세요
유용한 운영 환경 테스트는 의도적으로 관찰 가능한 것부터 시작합니다:
SELECT pg_backend_pid(), pg_sleep(30);
실제 MCP 도구, 드라이버 (driver), 풀 (pool), 그리고 네트워크 경로를 통해 실행하세요. 클라이언트에게 2초의 마감 기한을 부여합니다.
그런 다음 네 가지 별개의 사실을 확인하십시오:
- 클라이언트가 취소 또는 마감 기한 에러를 받았는지 확인합니다.
- MCP 도구가 활성 작업 및 대기 중인 작업을 중단했는지 확인합니다.
pg_stat_activity에서 해당 백엔드 (backend)가 더 이상 문장 (statement)을 실행하고 있지 않은지 확인합니다.- 풀링된 연결 (pooled connection)이 다음 쿼리를 안전하게 실행할 수 있는지 확인합니다.
첫 번째 항목만 확인한다면, 당신은 UI를 테스트한 것이지 취소를 테스트한 것이 아닙니다.
까다로운 사례들이 더 중요합니다
깔끔한 타임아웃은 쉬운 설정입니다. 운영 환경에서는 경합 상황 (races)이 필요합니다:
- 행이 스트리밍 (streaming)되는 동안 연결 해제
- 풀링된 연결을 기다리는 동안 취소
- 잠금 (lock)에 의해 차단된 동안 중단
- 활성 문장 (active statement) 도중 워커 (worker) 종료
- PostgreSQL이 완료되는 바로 그 순간에 취소
- 취소 후 연결 재사용
대기 중인 작업 (Queued work)은 특별한 주의를 기울여야 합니다. 호출자가 풀을 기다리는 동안 취소한다면, 연결이 사용 가능해졌을 때 10초 후에 쿼리가 시작되어서는 안 됩니다.
데이터베이스 측 제한 사항이 최후의 보루입니다
애플리케이션 취소 (Application cancellation)는 실패할 수 있습니다. 프로세스가 충돌할 수도 있고, 중단 핸들러 (Abort handlers)에 버그가 있을 수도 있습니다.
데이터베이스 역할 (Database role)은 여전히 제한된 실행 정책을 가지고 있어야 합니다:
ALTER ROLE ai_readonly SET statement_timeout = '15s';
ALTER ROLE ai_readonly SET lock_timeout = '2s';
ALTER ROLE ai_readonly SET idle_in_transaction_session_timeout = '10s';
이 값들은 예시일 뿐, 보편적인 기본값은 아닙니다. 승인된 분석 워크로드 (Analytical workloads)는 별도의 역할과 더 큰 명시적 예산이 필요할 수 있습니다.
중요한 부분은 "타임아웃 지원"이 테스트 가능한 계약 (Contract)이 된다는 점입니다:
취소된 요청은 데이터베이스 측 예산을 초과하여 PostgreSQL 작업이 계속 실행되도록 방치할 수 없습니다. 대기 중인 작업은 절대 시작되지 않으며, 활성 작업은 취소되고, 풀링된 연결 (Pooled connections)은 알려진 상태로 반환되며, 그 결과는 감사 (Auditable) 가능해야 합니다.
데모는 AI 에이전트가 쿼리를 시작할 수 있음을 증명합니다.
프로덕션 준비 상태 (Production readiness)를 위해서는 시스템이 쿼리를 중단할 수 있다는 증명이 필요합니다.
pg_stat_activity 증거, 에러 카테고리, 잠금 대기 (Lock waits), 스트리밍, 그리고 풀 정리 (Pool cleanup)를 포함한 전체 테스트 계획을 여기에 작성했습니다:
MCP server for Postgres: test query cancellation all the way to the backend
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기