Beta 2가 중요한 이유
2026년 7월 16일 PostgreSQL 19 Beta 2가 릴리스됐다. 이전 Beta 1(2026년 6월 4일)이 "이런 기능을 추가할 예정"이었다면, Beta 2는 피처 프리즈(Feature Freeze) 선언과 함께 "이것이 GA에 포함될 것들"을 확정했다. GA 예상 시점은 2026년 9~10월이다.
Beta 1 개요 챕터(database-frontier/3)에서 변화 전반을 다뤘다면, 이 챕터는 운영자가 GA 전에 테스트하고 결정해야 할 세 가지에 집중한다.
- SQL/PGQ 그래프 쿼리: 기존 릴레이션 테이블 위에서 그래프 쿼리를 실행하는 새 DDL/쿼리 유형.
- 내장 REPACK 명령: pg_repack 없이 온라인 테이블 재구성을 지원하는 첫 내장 기능.
- 기본값 변경: JIT 비활성·lz4 TOAST 압축·병렬 Autovacuum — 운영 환경에 조용히 영향을 미친다.
SQL/PGQ: 별도 그래프 DB 없이 관계형 테이블을 그래프로 조회
배경
소셜 네트워크 추천, 사기 탐지, 공급망 경로 분석처럼 "노드와 엣지 관계를 탐색"하는 쿼리는 관계형 SQL로 표현하기 어려웠다. 일반적으로 재귀 CTE(WITH RECURSIVE)로 우회하거나 별도의 그래프 DB(Neo4j 등)로 데이터를 복제했다.
PostgreSQL 19는 SQL/PGQ(Property Graph Queries) 표준을 구현해 이 문제를 데이터베이스 안에서 직접 해결한다. 핵심은 데이터 이전이 필요 없다: 기존 테이블 위에 그래프 뷰를 선언하고, 그래프 패턴 쿼리를 실행한다.
CREATE PROPERTY GRAPH
-- 기존 테이블: users, follows
CREATE PROPERTY GRAPH social_graph
VERTEX TABLES (
users
LABEL person
PROPERTIES (id, name, joined_at)
)
EDGE TABLES (
follows
SOURCE KEY (follower_id) REFERENCES users (id)
DESTINATION KEY (followee_id) REFERENCES users (id)
LABEL follows
);이 DDL은 social_graph라는 읽기 전용 뷰를 생성한다. 실제 데이터는 users와 follows 테이블에 그대로 있고, 데이터 복제나 마이그레이션이 없다. 그래프는 스냅샷이 아니라 기반 테이블에 실시간으로 바인딩된다.
GRAPH_TABLE 쿼리
-- "나를 팔로우하는 사람의 팔로워" — 2홉 탐색
SELECT *
FROM GRAPH_TABLE (social_graph
MATCH (a IS person)-[IS follows]->(b IS person)-[IS follows]->(c IS person)
WHERE a.name = '김철수'
COLUMNS (a.name AS requester, b.name AS intermediary, c.name AS follower_of_follower)
);MATCH 절에서 (노드)-[엣지]->(노드) 패턴으로 경로를 표현한다. 일반 SELECT 문과 조인할 수 있어, 기존 쿼리 결과와 혼용이 가능하다.
운영 고려사항
- 권한:
CREATE PROPERTY GRAPH는 스키마 소유자 또는 테이블에 대한 SELECT 권한이 필요하다. 그래프 조회는 기반 테이블의 SELECT 권한으로 접근 제어된다. - 성능:
GRAPH_TABLE은 내부적으로 기반 테이블을 조인으로 변환한다. 경로 탐색이 깊어질수록 일반 재귀 CTE와 비슷한 플래너 제약이 있다. 인덱스 설계는 기존 FK 열에 유지한다. - 읽기 전용: 그래프를 통한 쓰기는 지원되지 않는다. 기반 테이블에 직접 INSERT/UPDATE한다.
내장 REPACK: pg_repack 없이 온라인 재구성
기존의 문제
테이블 비대화(bloat)는 대용량 UPDATE/DELETE 후 VACUUM이 공간을 회수하지만 OS로 반환하지 않아 발생한다. 해결책은 세 가지였다.
| 방법 | 잠금 | 단점 |
|---|---|---|
VACUUM FULL | ACCESS EXCLUSIVE (전체 작업 동안) | 테이블이 쓰기 불가 |
CLUSTER | ACCESS EXCLUSIVE (전체 작업 동안) | 테이블이 쓰기 불가 |
pg_repack 확장 | 종료 시 짧은 잠금 | 외부 확장 관리 부담 |
PostgreSQL 19는 내장 REPACK 명령으로 세 번째 선택지를 표준 기능으로 흡수했다.
기본 문법
-- 비동시성: VACUUM FULL처럼 ACCESS EXCLUSIVE 잠금 (테이블 오프라인)
REPACK my_table;
-- 동시성: 온라인 재구성, 마지막에만 짧은 잠금
REPACK (CONCURRENTLY) my_table;
-- 인덱스 순서로 재구성 (CLUSTER 대체)
REPACK (CONCURRENTLY) my_table USING INDEX my_idx;
-- 분석 포함
REPACK (CONCURRENTLY, ANALYZE) my_table;CONCURRENTLY 내부 동작
pg_repack과의 차이
| 항목 | pg_repack (확장) | 내장 REPACK (PG19) |
|---|---|---|
| 설치 | 확장 별도 설치 | 없음 |
| 버전 관리 | PG 버전 맞춤 빌드 필요 | 내장 |
| 잠금 방식 | ACCESS EXCLUSIVE 최종에만 | 동일 |
| USING INDEX | 지원 | 지원 |
| RLS/Partition | 부분 지원 | 내장 지원 |
| superuser 필요 | 필요 | 테이블 소유자로 충분 |
기본값 변경: JIT·TOAST·Autovacuum
JIT 기본 비활성 (jit = off)
PostgreSQL 17부터 JIT(Just-In-Time 컴파일)는 비용 임계값 기반으로 활성화됐다. 문제는 플래너의 비용 추정이 부정확해 OLTP 쿼리에서도 JIT가 켜지고 오히려 응답 시간을 늘리는 경우가 잦았다는 점이다. PostgreSQL 19는 기본값을 off로 바꿔 이 불확실성을 제거했다.
영향 체크리스트:
-- 현재 JIT 설정 확인
SHOW jit;
-- 대용량 집계/분석 쿼리에서 JIT 효과 측정
SET jit = on;
EXPLAIN (ANALYZE, BUFFERS)
SELECT SUM(amount), category FROM orders GROUP BY category;- OLTP 위주 시스템: 변화 없음. 오히려 미세한 지연 감소를 기대할 수 있다.
- 대형 집계·OLAP 쿼리가 있는 시스템: 성능 저하 가능.
ALTER SYSTEM SET jit = on또는 세션 수준SET jit = on을 적용해야 한다. - pg_upgrade 이후 기존 설정 파일에
jit = on이 없으면 기본값off로 전환된다.
TOAST 기본 압축: pglz → lz4
default_toast_compression이 pglz에서 lz4로 바뀐다. 영향 범위는 새로 생성되는 테이블과 컬럼이다. 기존 데이터의 압축 방식은 변하지 않는다.
| 항목 | pglz | lz4 |
|---|---|---|
| 압축률 | 높음 | 보통 |
| 압축 속도 | 보통 | 빠름 |
| 압축 해제 속도 | 보통 | 매우 빠름 |
| 주 사용 케이스 | 저장 공간 절약 최우선 | 읽기 처리량 최우선 |
읽기가 많은 워크로드에서는 lz4가 유리하다. 쓰기가 많고 저장 공간이 중요하면 기존 pglz를 명시적으로 유지하면 된다.
-- 특정 컬럼에 pglz 유지
ALTER TABLE logs ALTER COLUMN payload SET COMPRESSION pglz;
-- 현재 기본값 확인
SHOW default_toast_compression;병렬 Autovacuum (autovacuum_max_parallel_workers)
Autovacuum이 하나의 테이블에서 여러 인덱스를 병렬로 vacuum할 수 있게 됐다. 새 파라미터 autovacuum_max_parallel_workers와 테이블 수준 스토리지 파라미터 vacuum_max_parallel_workers로 제어한다.
-- 테이블 수준으로 병렬 vacuum 허용
ALTER TABLE orders SET (vacuum_max_parallel_workers = 4);
-- 전역 기본값 (postgresql.conf)
-- autovacuum_max_parallel_workers = 2 (새 파라미터)또한 새로운 vacuum 우선순위 점수 시스템이 도입됐다. 비대화가 심하거나 트랜잭션 ID wrap-around 위험이 높은 테이블이 autovacuum 큐에서 더 빨리 처리된다.
GA 전 테스트 계획 체크리스트
Beta 2는 피처 프리즈가 선언됐으므로, 지금 환경을 구성하면 GA 출시 시 전환 위험을 줄일 수 있다.
환경 준비
- [ ] Beta 2를 스테이징 클러스터에 설치하고 프로덕션 덤프를 복원한다.
- [ ]
pg_upgrade --check로 호환성 사전 검사를 실행한다.
JIT 검증
- [ ] 대형 집계/리포팅 쿼리 10~20개를
EXPLAIN ANALYZE로 측정한다. - [ ] JIT 의존 여부를 확인 후, 필요한 경우
ALTER SYSTEM SET jit = on을 적용한다.
REPACK 검증
- [ ] 비대화 상위 테이블에
REPACK (CONCURRENTLY)실행 후 잠금 시간을 측정한다. - [ ] pg_repack 확장을 제거할 수 있는지 결정한다.
SQL/PGQ 검증
- [ ] 그래프 조회가 필요한 사용 사례에서
CREATE PROPERTY GRAPH+GRAPH_TABLE을 테스트한다. - [ ] 기존 재귀 CTE와 성능을 비교한다.
TOAST 변경 검증
- [ ] 새 테이블에서 lz4 기본 압축을 확인한다.
- [ ] 저장 공간 변화를 측정한다.
요약
PostgreSQL 19 Beta 2는 세 가지 의미 있는 변화를 GA로 확정했다. SQL/PGQ는 그래프 DB를 도입하지 않고 기존 릴레이션 테이블 위에서 경로 탐색 쿼리를 쓸 수 있게 해준다. 내장 REPACK은 pg_repack 확장 없이 온라인 테이블 재구성을 가능하게 한다. JIT 기본 비활성과 lz4 TOAST는 조용한 기본값 변경이지만, OLAP 쿼리와 저장 특성에 영향을 미칠 수 있으므로 업그레이드 전 검증이 필요하다.
References
- PostgreSQL 19 Beta 2 릴리스 공지: https://www.postgresql.org/about/news/postgresql-19-beta-2-released-3350/
- PostgreSQL 19 공식 릴리스 노트: https://www.postgresql.org/docs/19/release-19.html
- PostgreSQL 19 Property Graphs 문서: https://www.postgresql.org/docs/19/ddl-property-graphs.html
- PostgreSQL 19 REPACK 문서: https://www.postgresql.org/docs/19/sql-repack.html
- depesz: Waiting for PG19 — REPACK 명령: https://www.depesz.com/2026/03/19/waiting-for-postgresql-19-introduce-the-repack-command/
- depesz: Waiting for PG19 — REPACK CONCURRENTLY: https://www.depesz.com/2026/04/21/waiting-for-postgresql-19-add-concurrently-option-to-repack/
- The Build: REPACK Moves In: https://thebuild.com/blog/2026/04/29/repack-moves-in/
- Neon: PostgreSQL 19 SQL/PGQ 가이드: https://neon.com/postgresql/postgresql-19/sql-pgq-graph-queries
- JusDB: PostgreSQL 19 Beta 신기능 DBA 가이드: https://www.jusdb.com/blog/postgresql-19-beta-new-features-dba-guide
- Scaling Postgres: REPACK CONCURRENTLY 에피소드: https://www.scalingpostgres.com/episodes/414-repack-concurrently/