--- date: 2026-04-16 topic: pgcat + Patroni TCP keepalive 적용 (Step 1 옵션 B) areas: - infra/postgresql-ha.md tags: [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]` 섹션: ```toml tcp_keepalives_idle = 60 tcp_keepalives_interval = 10 tcp_keepalives_count = 3 ``` pgcat 1.2.0 에서 실제로 지원하는 정확한 키명 (`pgcat.toml` 예제 파일 및 `src/config.rs` 확인). 서버 소켓에 적용. ### Patroni (DCS) ```bash 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 세션 확인 필수: ```bash 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** (이 작업 안정화 후 별도 지시 예정)