Files
obsidian/history/2026-04-16-pgcat-patroni-tcp-keepalive.md

3.7 KiB

date, topic, areas, tags
date topic areas tags
2026-04-16 pgcat + Patroni TCP keepalive 적용 (Step 1 옵션 B)
infra/postgresql-ha.md
history
pgcat
patroni
postgresql
tcp-keepalive

Patroni multi-host 마이그레이션 원래 Step 1 계획(pgcat Patroni REST API 연동)이 소스 재조사 결과 pgcat 1.2.0 에 해당 기능 미존재 판정 → kappa 결정에 따라 옵션 B(HAProxy 구조 유지 + TCP keepalive 추가)로 선회.

배경

2026-04-15 19:53 UTC Patroni TL5→6 재선출 후 n8n 이 24h 동안 1038건 "Database connection timed out" 에러. 조사 결과 n8n TypeORM 풀의 단일 소켓이 failover 2분 전 열린 채 7588초간 idle 유지 → pgcat 까지 요청 도달조차 못하는 좀비 상태 (230ec530-b8a6-406c-9165-35c9eb2d8282 조사 문서).

n8n rollout restart 로 즉시 정상화. 재발 방지를 위해 pgcat 와 Patroni 양쪽에 TCP keepalive 명시 활성화.

변경 내용

helm-charts (commit 7ebd7e3)

values/pgcat.yaml configMaps.pgcat-config.pgcat.toml [general] 섹션:

tcp_keepalives_idle = 60
tcp_keepalives_interval = 10
tcp_keepalives_count = 3

pgcat 1.2.0 에서 실제로 지원하는 정확한 키명 (pgcat.toml 예제 파일 및 src/config.rs 확인). 서버 소켓에 적용.

Patroni (DCS)

patronictl -c /etc/patroni.yml edit-config \
  -p tcp_keepalives_idle=60 \
  -p tcp_keepalives_interval=10 \
  -p tcp_keepalives_count=3 --force
patronictl reload nocodb-cluster --force

3노드 전체 postgresql.conf 에 반영, SIGHUP 으로 적용 (재시작 불필요). 새 TCP 연결부터 keepalive 옵션 적용.

주의: SHOW tcp_keepalives_idle 을 unix socket (psql local) 에서 실행하면 0으로 출력. TCP 세션 확인 필수:

PGPASSWORD=... psql -h 192.168.9.1 -p 5432 -U n8n -d n8n -c "SHOW tcp_keepalives_idle"
# → 60

검증 — Patroni switchover 재현 테스트

before: TL6 leader postgres-3 (10.100.1.83) action: patronictl switchover --leader postgres-3 --candidate postgres-2 --force after: TL7 leader postgres-2 (10.100.3.185)

pgcat → 새 leader 도달 시간

T1=22:24:37.696 UTC  switchover 커맨드 반환
t+0002ms  pgcat 경유 SELECT → "connection lost" (HAProxy 아직 구 leader 마크)
t+5175ms  여전히 connection lost
t+7331ms  10.100.1.83 응답 (구 leader, 이제 replica — SELECT 는 성공)
t+8461ms  10.100.3.185 응답 (새 leader)

write 가능 복구 시간: ~8.5초. HAProxy inter 3s fall 3 (9초 감지) 이론치와 일치. keepalive 와 독립 — HAProxy 헬스체크 파라미터가 결정.

애플리케이션 영향 (switchover 전후 ~150초 창)

서비스 에러 수 타입
NocoDB 1 "unexpected EOF" 1회
n8n 9 건 (7초 윈도우) SocketError/UnexpectedEof, Connection terminated, AllServersDown, Database connection timed out

이전 2026-04-15 failover (1038건, 2시간 지속) 대비 극적 대비. 좀비 소켓 없음.

롤백

  • values/pgcat.yaml 에서 tcp_keepalives_* 3줄 제거 → ArgoCD sync → pgcat rolling restart
  • Patroni: patronictl edit-config 에서 동일 3개 파라미터 제거 → reload

관측 기간

7일 (2026-04-23까지). 다음 Patroni failover 발생 시 app 에러 윈도우 < 10초 지속 여부 확인. 지속 시 원인 재조사.

관련 문서

  • infra/postgresql-ha.md — 「좀비 소켓 방지 — TCP keepalive」 섹션 신설
  • history/2026-04-16-pgcat-patroni-api-audit-correction.md — (별도 예정) pgcat Patroni API 미지원 정정, 원 감사 07497dd8 의 PR #944 cite 오류
  • helm-charts commit: https://gitea.inouter.com/kaffa/helm-charts/commit/7ebd7e3

후속

  • kappa 지시: PgPool-II PoC (이 작업 안정화 후 별도 지시 예정)