들어가며 — 200개를 더하고도 비는 자리

PostgreSQL은 매년 약 200개의 기능과 변경을 더한다. 그런데도 “이건 당연히 되겠지” 싶은 큰 기능 몇 개가 30년째 코어에 비어 있다. sharding, connection pooling, 내장 암호화(TDE) — 상용 DB라면 체크리스트에 들어가는 항목들이다. PostgreSQL을 쓰다 보면 어느 순간 “여기까지 다 되는데 왜 이건 안 되지” 하는 벽을 만난다.

Bruce Momjian(브루스 모미잔)은 2026년 발표 《What’s Missing in Postgres?》에서 이 빈칸들을 정면으로 다뤘다. 그가 발표 슬라이드를 쓰면서 깨달은 한 가지가 핵심이다 — 빠진 기능의 대다수는 기능(functionality)이 없어서가 아니라 성능(performance)을 위한 것이라는 점이다. 즉 PostgreSQL은 “못 하는” 게 아니라, “더 빨리 하기 위한 장치"가 아직 코어에 없는 쪽에 가깝다.

이 글은 그 빈칸을 항목별로 짚는다. 각 항목마다 무엇이 없나 → 왜 코어에 없나 → 지금은 무엇으로 메우나 → 코어 편입 전망 순으로 본다. Momjian의 발표 분류를 따라 단일 호스트(single host) 성능 항목과 다중 호스트(multi-host) 항목으로 나눈다.

한 장으로 보는 빈칸 지도

먼저 전체 그림을 표로 깔아둔다.

빈칸분류지금 메우는 도구코어 편입 전망
내장 암호화 (TDE)단일 호스트pg_tde, EDB(상용)논의 단계
내장 connection pooler단일 호스트PgBouncer, Pgpool-II, Supavisor패치 제안 반복
optimizer hints단일 호스트pg_hint_planPostgreSQL 19 1차 도입
columnar storage단일 호스트Citus columnar, Hydra 등미정
global index단일 호스트— (수동 우회)미정
direct I/O단일 호스트(PostgreSQL 18 AIO 기반)진행 중
server-side threading단일 호스트— (프로세스 모델)장기 과제
64-bit transaction ID단일 호스트Postgres Pro(fork)장기 논의
sharding다중 호스트Citus, Multigres미정
multi-master replication다중 호스트pgEdge/Spock, BDR(상용)미정
Oracle RAC 동급다중 호스트사실상 없음
DDL의 logical replication다중 호스트일부 extension부분 진행

표를 위에서 아래로 훑으면 패턴이 보인다 — 빈칸 대부분에 “지금 메우는 도구"가 있다. PostgreSQL은 코어를 작게 유지하고 extension·외부 프로세스로 확장하는 철학을 30년간 지켜 왔고, 빈칸은 그 철학의 그림자이기도 하다.

코어와 빈칸의 경계

PostgreSQL이 무엇을 코어에 두고 무엇을 바깥에 두는지, 영역을 그림으로 나눠 본다.

flowchart TD
    Core["PostgreSQL 코어"]
    Core --> Q["쿼리 처리 · MVCC"]
    Core --> R["streaming replication"]
    Core --> P["declarative partition"]
    Core --> E["extension 인터페이스"]

    E -.확장.-> Ext1["sharding
Citus / Multigres"] E -.확장.-> Ext2["암호화
pg_tde"] E -.확장.-> Ext3["hints
pg_hint_plan"] Proxy["외부 프로세스"] -.연결 앞단.-> Pool["pooler
PgBouncer"] App["애플리케이션"] --> Proxy Proxy --> Core

코어는 쿼리 처리, MVCC, streaming replication, declarative partition까지를 책임진다. 그 위로 sharding·암호화·hint 같은 빈칸은 extension이 메우고, connection pooling은 아예 별도 프로세스가 연결 앞단에서 받는다. 이제 각 빈칸을 풀어쓴다.

빈칸 1. 내장 암호화 — TDE

무엇이 없나

데이터 파일을 디스크에 암호화해 저장하는 Transparent Data Encryption(TDE)이 코어에 없다. 디스크나 백업 미디어를 통째로 탈취당해도 키 없이는 못 읽게 막는 data-at-rest 보호인데, Oracle·SQL Server는 오래전부터 내장한 기능이다.

왜 코어에 없나

암호화 자체는 어렵지 않다. 어려운 건 키 관리와 성능, 그리고 WAL·임시 파일·통계까지 빠짐없이 덮는 일관성이다. 코어에 넣으려면 KMS 연동 모델까지 표준화해야 하는데, 이 합의가 더디다. Momjian은 cluster file encryption을 단일 호스트 항목으로 분류하면서, 진행은 있되 코어 합의에는 이르지 못한 상태로 짚는다.

지금은 무엇으로 메우나

Percona의 pg_tde extension이 2025년에 production 궤도에 올랐다. 2025년에 WAL 암호화가 GA에 도달했고, 2025년 11월에는 pg_tde 2.1이 릴리스되며 PostgreSQL 18.1과 asynchronous I/O까지 지원한다. HashiCorp·Thales·Fortanix·OpenBao 같은 KMS 연동도 붙었다. pg_tde는 구독 뒤에 숨기지 않은 오픈소스라는 점을 내세운다. 한편 EDB도 TDE를 제공하지만, 이쪽은 EDB Postgres Advanced Server·Extended Server의 라이선스 제품에서만 쓸 수 있다.

pg_tde를 쓸 때 백업 도구와의 궁합은 따로 검증이 필요하다. 이 주제는 암호화된 PostgreSQL은 pgBackRest로 백업될까 글에서 한 편 다뤘다.

코어 편입 전망

당장은 어렵다. pg_tde가 사실상의 오픈소스 표준 자리를 먼저 굳히는 중이고, 코어 편입은 그 다음 논의가 될 가능성이 크다.

빈칸 2. 내장 connection pooler

무엇이 없나

PostgreSQL은 17까지도 내장 connection pooler가 없다. PostgreSQL은 연결 하나당 프로세스 하나(process-per-connection) 모델이라, 연결 수가 늘면 메모리와 context switch 비용이 가파르게 오른다. 수천 개의 짧은 연결을 받는 웹 백엔드에서 특히 아프다.

왜 코어에 없나

프로세스 모델 자체가 발목을 잡는다. 내장 pooler를 제대로 넣으려면 연결 처리 구조를 손봐야 하고, 이는 server-side threading 같은 더 깊은 과제와 얽힌다. 패치 제안은 여러 번 올라왔지만 코어 합의까지 가지 못했다.

지금은 무엇으로 메우나

외부 프로세스가 연결 앞단에서 받는다.

  • PgBouncer — 가장 널리 쓰이는 경량 pooler. transaction/session 단위 풀링을 지원하고, 사실상의 표준이다.
  • Pgpool-II — 풀링에 더해 load balancing·query routing까지 묶은 무거운 도구.
  • Supavisor — Supabase가 만든 Elixir 기반 멀티테넌트 pooler. 클라우드 규모를 노린다.

클라우드 사업자들은 이걸 관리형으로 흡수했다. Azure Database for PostgreSQL은 PgBouncer를 서버 단위 옵션으로 켤 수 있게 내장했다.

코어 편입 전망

논의는 살아 있다. 다만 process-per-connection 구조와 threading 과제가 함께 풀려야 본격적인 내장 pooler가 가능해진다. 단기간에 PgBouncer를 대체할 그림은 아니다.

빈칸 3. optimizer hints

무엇이 없나

쿼리 planner에게 “이 인덱스를 써라”, “이 조인 순서로 가라” 식으로 강제하는 optimizer hint가 코어에 없었다. Oracle 사용자가 PostgreSQL로 옮길 때 가장 먼저 당황하는 지점 중 하나다.

왜 코어에 없나

PostgreSQL 커뮤니티는 hint를 의도적으로 거부해 왔다. planner가 통계로 최적해를 찾게 두는 편이 장기적으로 낫고, hint는 잘못된 플랜을 영구히 고착시키는 부채가 된다는 철학이다. “hint가 필요하면 그건 planner나 통계를 고칠 신호"라는 입장이 오래 유지됐다.

지금은 무엇으로 메우나

pg_hint_plan extension이 그 자리를 메워 왔다. 주석 형태로 hint를 심어 planner 동작을 강제한다.

코어 편입 전망

여기서 흐름이 바뀌었다. optimizer hint의 1차 형태가 PostgreSQL 19에 들어온다. 오래 거부하던 기능이 코어에 발을 들이는 사례라, 빈칸 목록에서 가장 먼저 지워질 항목이다.

빈칸 4. 단일 호스트의 나머지 성능 항목

Momjian이 단일 호스트 묶음으로 짚은 나머지를 한 번에 정리한다. 이들의 공통점은 기능이 없는 게 아니라 더 빠르게 하기 위한 장치라는 점이다.

  • columnar storage — 분석 워크로드용 열 지향 저장. 코어에 없고, Citus의 columnar나 Hydra 같은 extension이 메운다. 코어 작업은 널리 알려진 활발한 움직임이 아직 없다.
  • global index — partition 테이블 전체를 가로지르는 인덱스. 여러 partition에 걸친 unique 보장을 한 인덱스로 처리하려는 것인데, 현재는 코어에 없어 수동 우회에 의존한다.
  • direct I/O — OS 페이지 캐시를 우회하는 I/O. PostgreSQL 18이 asynchronous I/O(AIO) 서브시스템을 들이며 기반이 깔렸고, 그 위에서 진행 중이다.
  • server-side threading — 프로세스 모델을 thread 모델로 바꾸는 장기 과제. connection pooler 빈칸과 뿌리가 같다.
  • 64-bit transaction ID — 32-bit XID는 wraparound 위험을 안고 산다. PostgreSQL은 epoch을 포함한 xid8 타입을 이미 갖췄지만, 내부 XID를 통째로 64-bit로 넓히는 작업은 on-disk 호환성 때문에 코어에 못 들어왔다. Postgres Pro fork는 내부 64-bit XID를 상용으로 돌리고 있어, 가능은 하되 코어 편입의 벽이 높다는 걸 보여준다.

빈칸 5. sharding

무엇이 없나

데이터를 여러 노드에 수평 분산하는 sharding이 코어에 없다. 단일 서버 용량을 넘어서는 순간 부딪히는 벽이다. MySQL 진영은 Vitess라는 검증된 sharding 시스템을 오래 가졌지만, PostgreSQL은 비교 대상이 없었다.

왜 코어에 없나

sharding은 distributed transaction, 분산 plan, 노드 간 일관성까지 묶인 거대한 과제다. PostgreSQL은 declarative partition으로 단일 노드 안의 분할까지는 코어에 들였지만, 노드를 가로지르는 분산은 extension·미들웨어의 몫으로 남겨 뒀다.

지금은 무엇으로 메우나

  • Citus — 분산 PostgreSQL extension. Microsoft가 인수해 Azure로 들어갔고, Azure의 Elastic Clusters가 이 오픈소스 기술 위에서 row/schema 단위 sharding을 제공한다. Citus 14가 PostgreSQL 18을 지원한다.
  • Multigres — 2025년 6월 Supabase가 Vitess 공동 창시자 Sugu(수구)를 영입해 시작한 “PostgreSQL용 Vitess”. PostgreSQL 앞단에 놓이는 proxy로, 표준 PostgreSQL 호환을 최우선에 둔다. Vitess와 같은 Apache 2.0 라이선스 오픈소스다.

Multigres는 분량이 커서 PostgreSQL에도 Vitess가 온다 글에서 따로 다뤘다.

코어 편입 전망

가까운 시일에는 어렵다. 코어가 분산 트랜잭션까지 흡수하기보다, Citus·Multigres 같은 미들웨어가 각자 자리를 잡는 그림이 현실적이다.

빈칸 6. 다중 호스트의 나머지 항목

다중 호스트 묶음의 나머지를 정리한다.

  • multi-master replication — 여러 노드가 동시에 write를 받는 구성. 코어의 replication은 단일 primary 기준이다. pgEdge의 Spock이 multi-master logical replication을 제공해 지리적으로 분산된 배치에 쓰이고, EDB의 BDR이 상용으로 그 자리를 채운다.
  • Oracle RAC 동급 — 공유 스토리지 위에서 여러 인스턴스가 같은 DB를 동시에 여는 RAC 모델. PostgreSQL에는 이에 직접 대응하는 코어 기능도, 널리 쓰이는 대체재도 사실상 없다. 빈칸 중 가장 비어 있는 자리다.
  • DDL의 logical replication — logical replication이 DML은 나르지만 CREATE TABLE 같은 DDL은 자동으로 나르지 못한다. PostgreSQL 19에서 sequence 복제 같은 주변부가 채워지며 부분적으로 전진하고 있다.

왜 비어 있는가 — 한 줄로 다시

빈칸들을 한 발 떨어져 보면 공통된 이유가 보인다.

  1. 철학 — 코어를 작게 두고 extension·외부 프로세스로 확장한다. optimizer hint를 오래 거부한 것이 대표적이다.
  2. 구조 — process-per-connection 모델이 connection pooler와 threading을 동시에 막는다. on-disk 포맷 호환성이 64-bit XID를 막는다.
  3. 합의 비용 — TDE의 키 관리, sharding의 분산 트랜잭션처럼 표준화 합의가 비싼 과제는 코어 진입이 더디다.

그리고 Momjian의 결론처럼, 이 빈칸들은 대부분 “PostgreSQL이 못 하는 일"이 아니라 “더 빠르게·더 크게 하기 위한 장치"다. 기능의 결핍이 아니라 성능과 규모의 천장에 가깝다. 그래서 대부분의 빈칸 옆에는 이미 그 천장을 뚫는 도구가 하나씩 서 있다.

닫으며 — 빈칸은 지도다

PostgreSQL의 빈칸 목록은 약점 목록이 아니라 지도에 가깝다. 어디까지가 코어이고 어디부터 extension·미들웨어의 영역인지, 그리고 다음 5년 동안 어느 칸이 먼저 채워질지를 보여준다. optimizer hint가 PostgreSQL 19에서 코어로 들어오는 것처럼, 빈칸은 고정된 게 아니라 천천히 메워진다.

DBA 입장에서 실무적으로 남는 건 단순하다 — 벽에 부딪히기 전에 어느 칸이 비어 있는지 미리 알아 두는 것. sharding이 필요하면 Citus나 Multigres를 일찍 검토하고, 연결 폭증이 보이면 PgBouncer를 처음부터 설계에 넣고, 규제 요건이 있으면 pg_tde를 미리 검증하면 된다. 빈칸은 막다른 길이 아니라, 무엇을 곁들여야 하는지 알려주는 표지판이다.

1차 출처

Momjian 발표:

암호화(TDE):

connection pooling:

optimizer hints:

sharding / multi-host:

64-bit XID: