2026년 여름, PostgreSQL이 바뀌는 방향
2026년 7월 16일, PostgreSQL 개발팀은 PostgreSQL 19 Beta 2를 공개하며 기능 동결(feature freeze)을 선언했다. 이제 GA(2026년 9월~10월 예정)까지는 안정성 개선에만 집중한다는 뜻이다.
이번 릴리스에서 DBA와 플랫폼 엔지니어가 주목할 변화는 크게 세 가지다. 첫째, 별도 그래프 DB 없이 기존 관계형 테이블에 그래프 패턴 매칭 쿼리를 실행할 수 있는 SQL/PGQ. 둘째, pg_repack과 pg_squeeze를 코어로 흡수한 REPACK CONCURRENTLY. 셋째, 오토베이큠이 대형 테이블을 병렬로 처리하는 병렬 오토베이큠. 이 외에도 플래너 제어를 위한 pg_plan_advice, 시퀀스 논리 복제, 기본값 변경 등 운영 관점에서 점검해야 할 사항들이 있다.
SQL/PGQ: 그래프 쿼리를 관계형 테이블 위에서
배경
소셜 네트워크 분석, 추천 엔진, 권한 경로 탐색 같은 그래프 패턴 쿼리를 PostgreSQL로 처리하려면 지금까지는 복잡한 CTE나 재귀 쿼리를 작성해야 했다. 관계를 그래프로 표현하기 위해 Neo4j 같은 전용 그래프 DB를 추가 운영하는 팀도 있었다.
PostgreSQL 19는 SQL:2023 표준의 SQL/PGQ(Property Graph Queries) 를 코어에 구현한다. 기존 관계형 테이블을 프로퍼티 그래프로 선언하고, 표준 SQL 문법으로 노드와 엣지를 순회하는 쿼리를 실행할 수 있다. 별도 그래프 엔진 없이 PostgreSQL 하나로 처리된다.
작동 방식
-- 1단계: 프로퍼티 그래프 정의
CREATE PROPERTY GRAPH social_graph
VERTEX TABLES (
users LABEL Person PROPERTIES (id, name, age)
)
EDGE TABLES (
follows SOURCE KEY (follower_id) REFERENCES users (id)
DESTINATION KEY (followee_id) REFERENCES users (id)
LABEL Follows
);
-- 2단계: GRAPH_TABLE로 패턴 매칭 쿼리
SELECT p1.name AS follower, p2.name AS following
FROM GRAPH_TABLE(social_graph
MATCH (p1 IS Person)-[IS Follows]->(p2 IS Person)
WHERE p1.age > 25
COLUMNS (p1.name, p2.name)
);CREATE PROPERTY GRAPH는 뷰처럼 동작한다. 실제 데이터는 기존 테이블(users, follows)에 그대로 있고, 그래프 정의는 이 테이블들을 노드/엣지로 해석하는 메타데이터다. GRAPH_TABLE 함수는 이 정의를 참조해 MATCH 패턴을 일반 관계형 쿼리로 번역한 뒤 실행한다.
현재 제한
Beta 2 기준으로 고정 깊이 패턴 매칭만 지원한다. ->*, ->+, ->{2,5} 같은 가변 길이 경로 순회는 지원하지 않는다. 최단 경로나 도달 가능성 같은 전형적인 그래프 알고리즘은 PostgreSQL 19 범위 밖이며, 향후 버전에서 다룰 예정이다.
기존 테이블 구조를 바꾸지 않고 그래프 정의를 얹는 방식이므로, 이미 관계형 스키마로 설계된 데이터에 그래프 질의를 추가하는 용도로 가장 적합하다.
REPACK CONCURRENTLY: 온라인 테이블 재구성의 표준화
핵심 메커니즘
REPACK CONCURRENTLY는 내부적으로 다음 순서로 동작한다.
- SHARE UPDATE EXCLUSIVE 잠금 하에 원본 테이블의 MVCC 스냅샷을 기준으로 섀도 테이블에 데이터를 복사한다. VACUUM, ANALYZE와 같은 잠금 수준이므로 서비스 트래픽은 계속 처리된다.
- 내부적으로 논리 복제 슬롯을 생성해 복사 진행 중 발생한 INSERT/UPDATE/DELETE를 포착하고 섀도 테이블에 반영한다.
- 섀도 테이블 기준으로 새 인덱스 파일을 생성한다.
- 섀도 테이블과 원본의 변경 격차가 줄어들면 ACCESS EXCLUSIVE를 짧게 획득해 파일 포인터를 교체한다. 교체 자체는 테이블 크기와 무관하게 빠르게 완료된다.
REPACK(CONCURRENTLY 없이)은 처음부터 끝까지 ACCESS EXCLUSIVE를 유지하므로, 프로덕션에서는 항상 CONCURRENTLY 옵션을 써야 한다.
pg_repack 사용자 마이그레이션 경로
PostgreSQL 19로 업그레이드하면 REPACK CONCURRENTLY가 코어 명령으로 제공된다. 기존에 pg_repack이나 pg_squeeze 확장을 사용하던 팀은 REPACK CONCURRENTLY로 전환할 수 있다. 내부 메커니즘이 pg_squeeze 로직을 코어로 가져온 것이라 동작 방식은 본질적으로 동일하다.
병렬 오토베이큠
문제
대형 테이블에서 오토베이큠이 한 번 실행되면 단일 워커가 처음부터 끝까지 처리한다. 수억 행 규모의 테이블에서는 오토베이큠 한 라운드가 수십 분 걸리고, 그 사이 dead tuple이 계속 쌓인다.
PostgreSQL 19의 해결
-- 오토베이큠 병렬 워커 수 설정
ALTER SYSTEM SET autovacuum_max_parallel_workers = 4;
SELECT pg_reload_conf();
-- 테이블별 세밀한 제어도 가능
ALTER TABLE orders SET (autovacuum_max_parallel_workers = 2);autovacuum_max_parallel_workers GUC로 오토베이큠이 사용할 최대 병렬 워커 수를 설정한다. 각 테이블 처리 시 지정된 수의 워커가 협력해 블록을 나누어 처리한다.
처리 우선순위 조정: 새 GUC autovacuum_freeze_score_weight와 autovacuum_vacuum_score_weight로 freeze 긴급도와 일반 vacuum 긴급도에 각각 가중치를 부여할 수 있다. 기존에는 단순한 임계값 기반이었던 테이블 우선순위 결정이 점수 기반 시스템으로 바뀐다.
운영 시 주의
병렬 워커가 늘어난 만큼 I/O 압력도 커진다. autovacuum_vacuum_cost_delay와 autovacuum_vacuum_cost_limit 설정을 함께 조정해 쓰기 부하가 높은 프로덕션 환경에서 autovacuum이 서비스 성능을 잠식하지 않도록 해야 한다.
pg_plan_advice: 플래너 힌트의 공식화
배경
PostgreSQL 플래너가 잘못된 실행계획을 선택하는 경우, 기존에는 공식적인 힌트 메커니즘이 없었다. pg_hint_plan 같은 외부 확장을 사용하거나, enable_seqscan = off 같은 전역 GUC를 임시로 변경하는 우회법을 써야 했다.
pg_plan_advice 확장
PostgreSQL 19는 pg_plan_advice 확장을 번들로 제공한다.
-- 확장 활성화
CREATE EXTENSION pg_plan_advice;
-- 쿼리 실행계획 분석 및 어드바이스 생성
SELECT * FROM pg_get_advice('SELECT * FROM orders WHERE customer_id = 12345');
-- 어드바이스를 쿼리 식별자 기반으로 자동 적용
SELECT * FROM pg_stash_advice(query_id := 'abc123', advice := '...');플래너가 비효율적인 계획을 택할 때 어드바이스를 생성·저장하고, 이후 동일 쿼리 식별자로 실행되는 요청에 자동으로 적용한다. 전역 GUC 변경 없이 특정 쿼리에만 힌트를 줄 수 있다.
Oracle의 SQL Plan Management(SPM), MySQL의 optimizer_hints와 유사한 방향이지만, PostgreSQL 방식으로 확장 형태로 제공한다.
시퀀스 논리 복제
PostgreSQL 18까지 논리 복제(logical replication)는 테이블 행만 복제했다. 시퀀스의 현재 값은 복제 대상이 아니었기 때문에, 페일오버 후 스탠바이를 프라이머리로 승격하면 시퀀스 값이 페일오버 시점 이전에 머물러 있었다.
PostgreSQL 19에서는 시퀀스 값도 논리 복제로 동기화된다. Publication에 시퀀스를 포함시키고 Subscription 쪽에서 동기화하는 방식이다.
-- Publisher: 시퀀스 포함
CREATE PUBLICATION my_pub FOR ALL TABLES, SEQUENCES;
-- Subscriber: 시퀀스 즉시 동기화
ALTER SUBSCRIPTION my_sub REFRESH PUBLICATION WITH (copy_data = true);이로써 페일오버 후 중복 키(duplicate key) 오류가 발생하는 흔한 문제를 논리 복제 설정 하나로 방지할 수 있다.
기타 주목할 변화
GROUP BY ALL
-- 기존: 집계 아닌 컬럼을 수동으로 열거해야 함
SELECT region, category, SUM(sales)
FROM orders
GROUP BY region, category;
-- PostgreSQL 19: ALL이 집계 아닌 컬럼을 자동 포함
SELECT region, category, SUM(sales)
FROM orders
GROUP BY ALL;GROUP BY ALL은 SELECT 목록에서 집계 함수에 포함되지 않은 컬럼을 자동으로 GROUP BY에 추가한다. 분석 쿼리 작성 시 오류를 줄이고 타이핑을 줄여주는 문법 편의 기능이다.
새 모니터링 뷰
pg_stat_lock: 잠금 타입별 통계를 집계한다. 어떤 잠금 유형이 얼마나 자주 획득되고 대기 중인지 확인할 수 있다.pg_stat_autovacuum_scores: 새 점수 기반 오토베이큠 우선순위 시스템의 내부 점수를 노출한다. 어떤 테이블이 왜 오토베이큠 대상으로 선택되는지 추적할 수 있다.
기본값 변경
| 설정 | PostgreSQL 18 기본값 | PostgreSQL 19 기본값 |
|---|---|---|
| TOAST 압축 | pglz | lz4 |
| JIT(Just-in-Time) | on | off |
TOAST 압축 기본값 lz4 전환: lz4는 pglz보다 압축률은 약간 낮지만 압축/해제 속도가 훨씬 빠르다. 대용량 텍스트나 JSONB 컬럼이 많은 데이터베이스에서 I/O가 줄어들면서 전체 성능이 올라가는 경우가 많다. 단, pg_dump로 백업한 데이터를 PostgreSQL 17 이하로 복구할 때 lz4로 압축된 TOAST 값을 처리하지 못할 수 있으므로 버전 간 마이그레이션 계획에서 확인이 필요하다.
JIT 기본 비활성화: JIT는 복잡한 집계 쿼리에서 이득이 있지만 소규모 쿼리에서 컴파일 오버헤드로 지연이 생기는 경우가 있었다. 기본값 off로 바꿔 대다수 OLTP 워크로드에서 일관성을 확보하고, JIT가 효과적인 OLAP 워크로드에서만 명시적으로 활성화하도록 유도한다.
DBA 체크리스트 (GA 대비)
- REPACK CONCURRENTLY 전환 계획: pg_repack/pg_squeeze 사용 중이라면 PostgreSQL 19 GA 이후 코어 명령으로 전환 일정을 수립한다.
- lz4 TOAST 호환성 검토: PostgreSQL 17 이하와 pg_dump/restore 경로가 있는 환경에서는
default_toast_compression = pglz로 유지하거나 복구 절차를 업데이트한다. - JIT 재평가: OLAP 쿼리가 많은 환경에서는
jit = on을 명시적으로 설정해야 한다. - 병렬 오토베이큠 I/O 영향: 워커 수 증가가 스토리지 I/O에 미치는 영향을 테스트 환경에서 확인한 뒤 적용한다.
- 시퀀스 복제 설정: 논리 복제를 사용하는 환경에서는 Publication에 SEQUENCES를 추가하는 시점을 계획한다.
- SQL/PGQ 적용 범위 파악: 그래프 패턴 쿼리가 필요한 기존 Neo4j/AgensGraph 사용 사례를 목록화하고, 고정 깊이 패턴만으로 커버 가능한지 평가한다.
Open question: pg_plan_advice가 프로덕션에서 얼마나 안정적으로 동작하는지는 GA 이후 커뮤니티 피드백을 통해 확인이 필요하다. Beta 2 단계에서 확장을 바로 프로덕션에 적용하기보다 테스트 환경에서 동작을 검증하는 것을 권장한다.
References
- PostgreSQL 19 Beta 2 Released (공식 발표)
- PostgreSQL 19 Beta 2: Native Graph Queries, Unified REPACK and Feature Freeze — Linux Compatible
- REPACK CONCURRENTLY: pg_squeeze Gets a Promotion — The Build
- SQL/PGQ in PostgreSQL 19: Graph Queries Without the Graph Database — The Build
- PostgreSQL 19 SQL/PGQ — Neon Documentation
- PostgreSQL 19 REPACK Command — Neon Documentation
- PostgreSQL 19: Logical replication of sequences — dbi services
- Waiting for PostgreSQL 19 – SQL/PGQ — depesz
- What's New in PostgreSQL 19 — pEdge Blog
- PostgreSQL 19 Beta available in Amazon RDS Preview — AWS