레퍼런스·설명레퍼런스

DB 연결 계약

역할별 연결 예산과 timeout을 확인한다

계약

PostgreSQL 16을 사용한다. 연결 포화·느린 문장·잠금 조사는 DB 지연 진단을 따른다.

역할별 연결 수

모든 역할은 같은 방식으로 DB 풀을 만든다. 풀 상한은 역할마다 다르다.

역할풀 상한이유
api10 + readiness probe 1 + LISTEN 1요청을 동시에 처리한다. probe는 자기 풀(상한 1)을 써서 요청과 연결을 다투지 않는다. 이벤트 알림을 받는 LISTEN 연결(werft:api-listen)은 풀 밖에 하나 둔다
metrics10scrape 한 번이 집계 7개를 동시에 읽는다
scheduler4pass가 문장을 하나씩 낸다. pass lock이 연결 하나를 더 쥔다
reconciler4pass가 문장을 하나씩 낸다
slack4inbox와 outbox를 차례로 비운다
checkpoint GC, session archive, upgrade check, migrate, 운영자 CLI(keys·grants 등)10한 번 실행하고 종료한다. 기본값(DEFAULT_POOL_MAX)을 쓴다
운영자 CLI profile-backfill2한 번 실행하고 종료한다. 코드가 기본값 대신 2로 정한다
운영자 CLI profile-migration4한 번 실행하고 종료한다. 코드가 기본값 대신 4로 정한다

Helm 기본값(api 2개, slack 1개, scheduler·reconciler 1개, metrics 꺼짐)으로 늘 열려 있을 수 있는 연결은 api 24 + scheduler 4 + reconciler 4 + slack 4 = 36개다. metrics.enabled를 켜면 10개가 더 붙는다. checkpoint GC(기본 일요일 04:00)와 session archive(기본 일요일 05:00)는 CronJob이고 concurrencyPolicy: Forbid라 각각 하나씩만 돈다. upgrade check와 migrate는 Helm hook이라 하나가 끝나야 다음이 시작하므로 동시에 하나뿐이다. 이 셋이 겹치면 최대 30개가 더 붙는다. 기본 일정에서는 GC가 한 시간 넘게 돌거나 일정을 바꿔야 GC와 session archive가 겹친다. compose는 api 12 + scheduler 4 + reconciler 4 + slack 4 = 24개다. PostgreSQL 기본 max_connections는 100이고 그중 3개는 superuser 몫이다. api나 slack replica를 늘리면 replica 하나에 12개(slack은 4개)씩 더해서 max_connections와 견준다. 관리형 DB는 인스턴스 크기에 따라 max_connections가 100보다 작을 수 있으니 그 값을 확인한다.

연결마다 거는 세션 설정

createEnforcedPool이 연결을 열 때 건다. DATABASE_URL에 같은 이름의 query parameter가 있어도 timeout은 코드 값이 이긴다.

설정api·job 값migrate 값뜻
연결 대기(connectionTimeoutMillis)5초5초풀이 비지 않으면 이 시간 뒤에 실패한다. api는 503으로 답한다
statement_timeout10초300초서버가 문장을 취소한다. 잠금을 기다리는 시간도 여기에 든다
응답 읽기(query_timeout)20초330초서버가 답하지 않는 소켓을 클라이언트가 버린다
idle_in_transaction_session_timeout30초30초트랜잭션을 연 채 30초 동안 문장을 내지 않은 연결을 서버가 끊는다. 그 연결이 쥔 잠금도 풀린다
application_namewerft:<역할>werft:migratepg_stat_activity와 서버 로그에서 역할을 가른다. DATABASE_URL에 application_name이 있으면 그 값을 쓴다

migration이 잠그는 시간

오래된 main 설치에서 오는 경우 0127_session_provider_tokens는 사용량 INSERT trigger를 만든 뒤 기존 사용량을 backfill한다. 0129_session_provider_tokens_cap는 합계가 JavaScript 안전 정수 상한을 넘지 않도록 trigger를 교체한다. 0169_usage_breakdown_rollup은 사용량 INSERT를 SHARE lock으로 멈춘 상태에서 세션·모델 집계를 backfill하므로 데이터가 많으면 쓰기 중단이 길어진다. 이 세 migration이 이미 적용된 설치에는 다시 적용하지 않는다. 미적용 설치는 유지보수 창과 DB 데이터량을 확인하고 변경 기록의 버전별 작업을 따른다.

migrate job은 문장마다 최대 300초를 쓴다. migrate가 둘 겹치면(손으로 돌린 db:migrate와 Helm hook Job 등) 뒤의 것은 앞의 것이 끝날 때까지 기다린 뒤 남은 migration만 적용한다. Helm hook Job은 migrate.activeDeadlineSeconds(기본 600초)가 지나면 끝난다. 커지는 표에 인덱스를 만드는 migration은 CREATE INDEX CONCURRENTLY로 쓰기를 막지 않고 만든다. 표가 커서 300초를 넘길 것 같으면 그 migration의 릴리스 노트가 따로 알린다. CONCURRENTLY 인덱스는 시작할 때 열려 있던 트랜잭션이 모두 끝나기를 기다리므로, 오래 열린 운영자 세션(psql의 열린 BEGIN)이 있으면 그만큼 늦어진다.

이 페이지