Go로 PostgreSQL 프록시 만들기 (58) - SQL Redaction과 Safe Observability
들어가며
릴리즈 직전, tasks-next.md의 Must Have 항목을 점검했다. Admin API Auth, Health Check, Maintenance Mode, …
PostgreSQL 프록시 직접 구현하기 - 커넥션 풀링, R/W 분산, 쿼리 캐싱, TLS, Circuit Breaker, 무중단 리로드, LSN Causal Consistency, AST 파서, 쿼리 방화벽, Audit Logging, Helm Chart, Serverless Data API, OpenTelemetry, fsnotify, Prepared Statement Multiplexing, Query Mirroring, GitHub Actions CI/CD, Multi-Database Routing, Query Digest, Grafana Dashboard, Per-User Connection Limits, Query Timeout, Idle Client Timeout, SQL Redaction
“내 손으로 만드는 데이터베이스 프록시”
애플리케이션과 DB 사이에 위치하여 커넥션 풀링, 읽기/쓰기 자동 분산, 반복 쿼리 캐싱을 수행하는 프록시를 Go로 직접 구현하는 프로젝트입니다.
🔍 기술적 호기심
📚 학습 목표
프록시 통합 (Pool + Router + Cache)
Prometheus 메트릭
/metrics HTTP 엔드포인트 (Prometheus scrape)Transaction Pooling
DISCARD ALL로 세션 상태 완전 초기화TLS Termination + Front-end Auth
crypto/tls)Circuit Breaker + Rate Limiting
Zero-Downtime Reload
POST /admin/reload HTTP APILSN 기반 Causal Consistency
pg_current_wal_lsn() 추적pg_last_wal_replay_lsn() 주기적 폴링pgmux_reader_lsn_lag_bytes 메트릭AST 기반 쿼리 파서
쿼리 방화벽 (Query Firewall)
시맨틱 캐시 키
Audit Logging & Slow Query Tracker
Serverless Data API
POST /v1/query — HTTP REST → PG Wire Protocol → JSON 응답Helm Chart & Docker
OpenTelemetry 분산 추적
traceparent HTTP 헤더 전파enabled: false 시 noop (성능 영향 없음)설정 파일 자동 리로드 (fsnotify)
Prepared Statement Multiplexing
Query Mirroring
GitHub Actions CI/CD
v* 태그 push 시 multi-platform Docker 이미지 GHCR 자동 배포Multi-Database Routing
StartupMessage.database 필드로 DB 그룹 자동 분기?database= 쿼리 파라미터 지원Query Digest & Top-N 분석
GET /admin/digest/top Admin APIpg_stat_statements의 프록시 버전Grafana Dashboard 템플릿
__inputs 변수로 데이터소스 자동 연결Per-User/Per-DB 커넥션 제한
53300 (too_many_connections) 표준 에러 반환Query Timeout
time.AfterFunc + CancelRequest 프로토콜로 프록시 레벨 타임아웃/* timeout:5s */)pgmux_query_timeout_total 메트릭Admin API
/admin/health — DB별 백엔드 헬스 상태 조회/admin/stats — DB별 풀, 캐시 통계 JSON/admin/config — 현재 설정 (비밀번호 마스킹)/admin/cache/flush[/{table}] — 전체/테이블별 캐시 비우기/admin/reload — 무중단 설정 리로드/admin/mirror/stats — 쿼리 미러링 통계SQL Redaction / Safe Observability
none(원본), literals($1, $2 치환), full(fingerprint)pg_query.Normalize 기반 정확한 리터럴 제거 + regex fallback멀티 인스턴스 스케일링
커넥션 풀링
R/W 쿼리 자동 분산
/* route:writer */)반복 쿼리 캐싱
백엔드
Go # 고루틴 기반 동시성
PostgreSQL Wire Protocol # 바이트 레벨 프로토콜 직접 구현
YAML # 설정 파일
모니터링
Prometheus # 메트릭 수집 + /metrics 엔드포인트
테스트 환경
Docker Compose # PG Primary + Replica 2대
Go testing # 단위 테스트 + 통합 테스트 + 벤치마크
┌─────────────────┐
│ Application │
│ (psql, app) │
└────────┬────────┘
│ PG Wire Protocol
▼
┌──────────────────────────────────────────┐
│ pgmux │
│ │
│ ┌───────────┐ ┌──────────────────────┐ │
│ │ TLS Term. │ │ Front-end Auth │ │
│ │ (SSL/TLS) │ │ (MD5 Challenge) │ │
│ └─────┬─────┘ └──────────┬───────────┘ │
│ │ │ │
│ ┌─────▼────────────────────▼───────────┐ │
│ │ Rate Limiter (Token Bucket) │ │
│ └─────┬────────────────────────────────┘ │
│ │ │
│ ┌─────▼─────┐ ┌────────────────┐ │
│ │ Query │ │ Tx Pooling │ │
│ │ Parser │ │ (Acquire/ │ │
│ └─────┬─────┘ │ Release) │ │
│ │ └────────────────┘ │
│ ┌─────▼────────────────────┐ │
│ │ Router (R/W + Session) │ │
│ └─────┬───────────┬───────┘ │
│ │ │ │
│ ┌─────▼─────┐ ┌──▼──────────────┐ │
│ │ Cache │ │ Round Robin │ │
│ │ (LRU) │ │ Load Balancer │ │
│ └───────────┘ └──────────────────┘ │
│ │ │
│ ┌─────▼──────────────────────────┐ │
│ │ Circuit Breaker (per backend) │ │
│ └─────┬──────────────┬──────────┘ │
└────────┼──────────────┼──────────────────┘
│ │
┌────▼────┐ ┌────▼────┐
│ Writer │ │ Readers │
│(Primary)│ │(Replica)│
└─────────┘ └─────────┘
| 항목 | 성능 | 메모리 |
|---|---|---|
| Cache Key 생성 | 15 ns/op | 0 alloc |
| Cache Get (Hit) | 36 ns/op | 0 alloc |
| Cache Get (Miss) | 6 ns/op | 0 alloc |
| RoundRobin Next | 1.7 ns/op | 0 alloc |
| Query Classify | 1,222 ns/op | 45 alloc |
| ClassifyAST SELECT | ~7 µs/op | - |
| ClassifyAST Complex JOIN | ~32 µs/op | - |
| SemanticCacheKey | ~2 µs/op | - |
| CheckFirewall | ~5.5 µs/op | - |
프로젝트 개발 과정에서 배운 내용을 기록하고 있습니다.