기타개발지식/풀스택개발

[PostgreSQL 18][커넥션 풀 장애] OAuth validator가 느릴 때 신규 연결 폭주를 막는 법

Sophie_ 2026. 9. 7. 09:07

IT 리서치 노트

[PostgreSQL 18][커넥션 풀 장애] OAuth validator가 느릴 때 신규 연결 폭주를 막는 법

PostgreSQL 18에서 OAuth validator가 느려질 때 데이터베이스 CPU는 정상인데 애플리케이션만 연결 timeout으로 무너질 수 있다. 특히 커넥션 풀이 한꺼번에 재생성되면 신규 인증과 재시도가 겹친다. 2026년 9월 7일 KST 기준 공식 문서의 2회 연결 경계와 인증 timeout을 바탕으로 폭주를 끊는 순서를 정리한다.

1. 개요

먼저 기존 연결 쿼리와 신규 연결 인증을 분리한다. validator timeout을 가장 안쪽에서 짧게 두고, 풀 생성 속도와 재시도에 지수 backoff·jitter·상한을 둔다. 기존 연결을 불필요하게 폐기하지 않는 것도 중요한 완화책이다.

PostgreSQL 18 OAuth 전체 구성을 먼저 보고, issuer·scope 불일치는 OAuth 로그인 실패 진단 순서, 서버 검증 코드는 validate_cb 점검 기준과 연결해 확인할 수 있다.

2. 어디서 실제로 막히는가

대표 증상은 기존 풀의 쿼리는 성공하지만 새 인스턴스와 새 연결만 timeout이 나는 상황이다. health check가 신규 연결을 매번 만들면 실패 판정이 인스턴스 재시작으로 이어지고, 다시 풀 전체가 생성되면서 인증 서버와 DB에 더 큰 부하를 준다.

  • 모든 연결 오류를 DB 장애로 분류한다.
  • validator HTTP timeout이 요청 deadline보다 길다.
  • 풀 최소 연결을 모든 인스턴스가 동시에 채운다.
  • 실패 즉시 재시도하고 기존 정상 연결도 폐기한다.

특히 배포 직후 여러 인스턴스가 min_connections를 동시에 채우면 사용자 요청이 없어도 인증 트래픽이 급증한다. autoscaling과 재시작 정책이 함께 반응하면 IdP 지연이 풀 대기열을 늘리고, 늘어난 대기열이 health check 실패와 추가 재시작을 부르는 순환이 생긴다.

재현 기록에는 PostgreSQL과 libpq 버전, 운영체제, 실제 사용 드라이버, issuer와 scope의 이름만 남기고 토큰 값은 남기지 않는다. 같은 서버라도 클라이언트가 어떤 libpq를 포함했는지에 따라 지원 범위가 달라진다.

첫 실패 시각, 영향받은 클라이언트 수, 변경 전후 지연을 같은 표에 남긴다. 오류 문자열 하나만 저장하지 말고 어느 단계에서 시간이 소모됐는지 기록해야 다음 장애에서 바로 비교할 수 있다.

3. 실무에서 적용하는 순서

장애 시 기존 연결로 단순 쿼리를 실행하고, 별도 신규 연결의 단계별 지연을 측정한다. 신규 인증만 느리면 배포와 autoscaling을 멈추고 풀 생성률을 제한한다. validator timeout을 줄이고 재시도에 backoff와 jitter를 넣는다.

  1. 기존 연결과 신규 연결의 성공률·지연을 분리한다.
  2. validator timeout 횟수와 IdP 응답 시간을 확인한다.
  3. 풀의 동시 생성 수와 최소 연결 선충전을 낮춘다.
  4. 즉시 재시도를 지수 backoff와 jitter로 바꾼다.
  5. IdP 복구 뒤 점진적으로 풀 생성률을 올린다.
pool:
  min_connections: 0
  max_connection_creations_per_second: 5
  acquire_timeout: 3s
retry:
  base: 500ms
  max: 30s
  jitter: full

복구 검증은 한 번에 원래 크기로 돌리지 않는다. 연결 생성률을 단계적으로 높이며 validator timeout, pool waiters, authentication_timeout을 함께 보고, 어느 지점에서 다시 대기열이 늘어나는지 기록한다. 기존 연결의 쿼리 지연까지 같이 오르면 그때는 인증 경로만의 문제가 아닌 DB 전체 부하로 범위를 넓힌다.

변경 뒤에는 정상 토큰뿐 아니라 만료 토큰, 잘못된 issuer, 부족한 scope를 넣은 음성 테스트를 함께 실행한다. 성공 연결 하나만 확인하면 검증기가 실패를 거절하는지 알 수 없다.

검증 결과는 정상·실패 입력을 같은 버전과 설정에서 반복해 확인한다. 한 항목만 바꾸고 연결 성공률, p95 지연, 거절 사유가 예상대로 바뀌는지 본다.

4. 공식 문서와 예시 화면으로 확인하기

내장 흐름에서 토큰 캐시가 없을 때 연결 교환이 어떻게 늘어나는지 확인한다. 화면의 강조 문장을 현재 설정의 같은 이름 항목과 대조한다.

libpq 기본 흐름은 캐시된 토큰이 없으면 discovery와 토큰 전송에 두 연결을 사용할 수 있다.
libpq 기본 흐름은 캐시된 토큰이 없으면 discovery와 토큰 전송에 두 연결을 사용할 수 있다.

풀 재시작이 동시에 일어나면 평소보다 많은 인증 작업이 짧은 시간에 몰릴 수 있다. 확인 결과와 적용 버전을 변경 기록에 남긴다.

검증기의 외부 의존성이 인증 가용성에 미치는 경계를 본다. 화면의 강조 문장을 현재 설정의 같은 이름 항목과 대조한다.

온라인 검증은 OAuth 서비스의 가용성과 응답 시간에 의존한다.
온라인 검증은 OAuth 서비스의 가용성과 응답 시간에 의존한다.

DB가 정상이어도 새 연결만 실패하는 부분 장애가 가능하다. 확인 결과와 적용 버전을 변경 기록에 남긴다.

PostgreSQL의 인증 완료 제한도 함께 확인한다. 화면의 강조 문장을 현재 설정의 같은 이름 항목과 대조한다.

authentication_timeout 안에 인증 프로토콜이 끝나지 않으면 서버가 연결을 닫는다.
authentication_timeout 안에 인증 프로토콜이 끝나지 않으면 서버가 연결을 닫는다.

풀 timeout, validator timeout, DB 인증 timeout의 순서가 뒤집히면 재시도 폭주가 길어진다. 확인 결과와 적용 버전을 변경 기록에 남긴다.

세 timeout은 독립 숫자가 아니라 안쪽부터 짧게 배치한다. 화면의 강조 문장을 현재 설정의 같은 이름 항목과 대조한다.

validator·pool·DB 인증 timeout 예산 예시다.
validator·pool·DB 인증 timeout 예산 예시다.

실제 값은 지연 분포에 맞추되 재시도 하나가 이전 요청보다 먼저 끝나지 않게 한다. 확인 결과와 적용 버전을 변경 기록에 남긴다.

장애 때는 DB 부하와 인증 부하를 분리해 본다. 화면의 강조 문장을 현재 설정의 같은 이름 항목과 대조한다.

신규 연결 실패를 분류할 관찰 항목이다.
신규 연결 실패를 분류할 관찰 항목이다.

기존 연결 쿼리가 정상이고 새 연결만 느리면 validator 경로를 우선한다. 확인 결과와 적용 버전을 변경 기록에 남긴다.

5. 주의사항과 리스크

인증 장애를 피하려고 만료 토큰을 무기한 재사용하거나 검증 실패를 허용하면 안 된다. 풀을 너무 작게 줄이면 정상 트래픽도 대기하므로 생성률 제한과 최대 풀 크기를 구분한다. health check는 가능하면 기존 연결 상태와 앱 준비 상태를 보고, 외부 IdP의 짧은 장애가 즉시 전체 재시작으로 번지지 않게 한다.

6. 결론

OAuth validator 장애는 DB 쿼리 장애가 아니라 신규 연결 경로의 부분 장애로 시작한다. 관측 지표와 timeout 순서, 풀 생성률, 재시도 규칙을 미리 나누면 인증 서버 지연이 전면 장애로 증폭되는 것을 막을 수 있다.

7. 참고 링크

  1. https://www.postgresql.org/docs/18/sasl-authentication.html
  2. https://www.postgresql.org/docs/18/oauth-validator-design.html
  3. https://www.postgresql.org/docs/18/runtime-config-connection.html