한 줄 요약

Christophe Pettus가 The Build에서 정리한 PostgreSQL 19 Beta Big 4는 모두 “피처 노트가 아닌, 운영 시나리오를 바꾸는 변경“이라는 공통점이 있다. 신규 syntax 한 줄로 끝나지 않고, 운영자의 메모리 계산식·장애 시나리오·튜닝 기본값을 다시 그리게 만든다.

PostgreSQL 19는 9월 정식 출시 예정이다. 이번 글은 Pettus의 Big 4 큐레이션을 출발점으로 삼아, 거기에 운영자 점검 항목 · 메모리 계산식 · SQL 예시 · 업그레이드 체크리스트를 보탠 글이다. 네 가지 선정은 Pettus의 시각이고, 운영 점검·메커니즘 해설·업그레이드 절차는 기존 PG19 시리즈 5편이 다루지 않은 자리를 채우는 보완·확장이다.

왜 이 Big 4인가

PostgreSQL 19의 변경 목록은 CommitFest 5회분의 수백 건이다. 그중 운영자가 실제로 체감하는 자리는 보통 둘 중 하나다.

  • 장애 회피 — 지금까지 운영 매뉴얼에 “이거 터지면 끝"으로 적혀 있던 시나리오가 사라진다.
  • 튜닝 기본값 변경 — 업그레이드 직후 워크로드 성격에 따라 plan 시간 · 메모리 · 비상 상황이 달라진다.

Pettus가 꼽은 Big 4는 정확히 그 두 축에 들어간다. 새 syntax · 새 알고리즘이 아니라, 기존 운영 매뉴얼을 다시 쓰게 만드는 변경들이다.

변경영향
64bit MultiXact members장애 회피“긴급 vacuum"이라는 운영 시나리오가 사라진다
병렬 autovacuum 인덱스 worker튜닝 기본값 변경최악 메모리 사용량 식이 달라진다
UPDATE/DELETE FOR PORTION OF신규 운영 영역row trigger · cascading FK 동작에 새 사각지대
jit = off (기본)튜닝 기본값 변경OLAP는 명시 활성화 안 하면 회귀

1. 64bit MultiXact members — “긴급 vacuum"이라는 운영 시나리오의 끝

무엇이 바뀌었나

MultiXact 멤버 카운터가 32bit에서 64bit로 확장됐다. 4 billion(약 40억) 멤버 공간 고갈 시나리오가 사실상 사라진다.

왜 운영자가 느끼나

PostgreSQL에는 운영자 사이에서 “이게 터지면 끝” 으로 통하는 시나리오가 몇 개 있다. MultiXact wraparound는 그 자리에 한참 머물러 있었다.

SELECT ... FOR SHARE, foreign-key check 같은 공유 row lock이 같은 행에 여러 트랜잭션에서 동시에 걸리면, PostgreSQL은 그 잠금 정보를 묶어서 MultiXact라는 별도 구조에 기록한다. 각 MultiXact는 멤버 슬롯을 소비한다. 그 멤버 카운터의 자료형이 PG 19에서 처음으로 확장됐다.

구분타입최대값
기존 (PG 18 이하)uint32 (32비트)약 42억 9천만
변경 (PG 19~)uint64 (64비트)약 1844경

42억은 운영 부하가 큰 워크로드(공유 lock + FK check 누적)에서 실제로 도달 가능한 수치다. 1844경은 — 단위 감각상 도달이 불가능한 영역으로 옮겨간다.

주의 — XID · mxid wraparound는 그대로다

운영자가 흔히 “wraparound"라고 묶어 부르는 자리는 사실 셋이다. 이번 변경은 그중 한 자리에 한정된다.

wraparound 종류PG 19에서 변경운영 영향
MultiXact members 카운터uint32uint64사실상 해결
MultiXact ID (mxid)변경 없음 (32bit)autovacuum 의존, anti-wraparound vacuum 그대로
Transaction ID (xid)변경 없음 (32bit)autovacuum의 freeze 책임 그대로

PostgreSQL의 오래된 숙제 — XID wraparound · mxid wraparound — 는 PG 19에서도 살아 있다. autovacuum이 주기적으로 freeze를 수행해야 하는 이유가 정확히 이것이다. 이번 글이 다루는 “해결된 wraparound"는 MultiXact members 카운터 하나뿐임을 분명히 해 둔다.

64bit XID 확장은 2018년부터 PostgreSQL hackers 메일링 리스트에서 논의돼 왔다. Postgres Pro가 PG 15 시기에 실험적 패치 시리즈로 동작 확인까지 갔지만, tuple 헤더 크기 증가 · 모든 index format 재설계 · WAL format 변경 같은 광범위한 ripple effect 때문에 main 브랜치 commit으로 이어지지 않았다. PG 19에서도 같은 상태다. PostgreSQL의 가장 오래된 숙제 중 하나가 한 라운드 더 미뤄진 자리고, 그 사이 운영자는 autovacuum freeze 튜닝과 pg_visibility · pg_class.relfrozenxid 모니터링을 손에서 놓을 수 없다.

운영 영향은 이렇게 정리된다.

항목PG 18까지PG 19 Beta
MultiXact members 고갈 시새 트랜잭션 거부 + offline emergency VACUUM사실상 도달 불가
XID · mxid wraparoundautovacuum freeze로 방어그대로 — 모니터링 유지
운영 매뉴얼 자리MultiXact members 항목은 “이거 터지면 끝” 목록의 한 자리members 항목만 삭제 후보. XID · mxid는 유지

42억 한계에 도달하면 운영자가 마주하는 그림은 단순했다. 새 트랜잭션이 거부되고, 복구 경로는 offline emergency VACUUM 하나. Pettus의 한 줄이 이 자리를 짚는다.

“When exhausted, the system would refuse new transactions, and the only recovery path was an emergency VACUUM.”

이론적으로 wraparound 수학은 2^64에서도 여전히 존재한다. 다만 같은 워크로드를 우주의 나이만큼 굴려도 도달이 어렵다. 32bit 공간 도달 사례는 운영 사고 보고서들에 종종 등장했지만, 64bit는 실무 카탈로그에서 제외할 수 있는 자리다.

운영자가 할 일

  • 운영 매뉴얼·런북에서 “MultiXact wraparound” 비상 절차 항목을 “PG 19부터는 도달 불가” 로 갱신
  • 단, PG 18 이하 운영 중인 클러스터는 그대로 이 시나리오가 살아 있다 — 모니터링 대시보드 유지

2. 병렬 autovacuum 인덱스 worker — 메모리 계산식의 변경

무엇이 바뀌었나

새 GUC autovacuum_max_parallel_workers가 추가된다. autovacuum이 단일 테이블의 인덱스 정리를 여러 worker로 병렬 처리한다. PG 17에서 도입된 manual VACUUM의 병렬 인덱스 정리가 autovacuum 경로까지 확장됐다.

왜 운영자가 느끼나

인덱스가 많이 붙은 wide table을 운영해 본 사람은 안다 — autovacuum이 돌면 heap 정리는 빠른데 인덱스 정리 단계에서 한참 멈춰 있다. 단일 worker가 인덱스 N개를 순차로 도는 구조였기 때문이다.

PG 19에서는 같은 자리에 worker가 동시에 들어간다. wide-and-many-indexes 테이블의 autovacuum 시간이 줄어들고, vacuum 누적 부담이 풀린다.

-- 새 GUC (값은 예시)
ALTER SYSTEM SET autovacuum_max_parallel_workers = 4;
SELECT pg_reload_conf();

주의 — 최악 메모리 식이 달라진다

같은 변경이 운영 부담을 새로 만드는 자리도 있다. 각 병렬 worker는 자기 몫의 maintenance_work_mem을 따로 잡는다.

항목PG 18까지PG 19 Beta
autovacuum 최악 메모리autovacuum_max_workers × maintenance_work_memautovacuum_max_workers × autovacuum_max_parallel_workers × maintenance_work_mem

autovacuum_max_workers=3, autovacuum_max_parallel_workers=4, maintenance_work_mem=1GB인 환경에서 최악 메모리 사용량은 3 × 4 × 1GB = 12GB가 된다. PG 18까지의 3GB와 4배 차이다.

운영자는 PG 19 업그레이드 전에 세 가지를 확인한다.

  1. maintenance_work_mem 현재 값
  2. autovacuum_max_workers 현재 값
  3. 위 두 곱에 새 GUC 곱을 더한 값이 시스템 메모리에 맞는가

maintenance_work_mem을 1GB 이상으로 키워 놓은 운영 환경(분석 워크로드 · 큰 인덱스 재정렬 빈도가 잦은 곳)은 특히 다시 계산해야 한다.

“명백한 이득"이 보이는 자리는 한정적 — serial 인덱스 정리가 vacuum의 병목이던 wide table에서 가장 큰 폭으로 줄어든다.

운영자가 할 일

  • 업그레이드 전 메모리 식 재계산. RAM이 빠듯하면 autovacuum_max_parallel_workers를 기본보다 낮춰 시작
  • wide table · 인덱스 다수 테이블에서 autovacuum 지속 시간 모니터링 (pg_stat_progress_vacuum)
  • 한꺼번에 너무 많은 worker가 깨어나 I/O 포화되지 않도록 autovacuum_vacuum_cost_limit 검토

3. UPDATE ... FOR PORTION OF — SQL:2011 시간 범위가 PostgreSQL로

무엇이 바뀌었나

시간 범위(period) 컬럼을 가진 테이블에서 부분 범위만 UPDATE 또는 DELETE할 수 있게 됐다. SQL:2011 표준 syntax다.

-- 가격 이력 테이블 (period 컬럼 사용 가정)
CREATE TABLE price_history (
    product_id int,
    price numeric,
    valid_period daterange,
    PERIOD FOR valid_period (valid_from, valid_to)
);

-- 2026-06-01 ~ 2026-06-15 구간만 가격 변경
UPDATE price_history
FOR PORTION OF valid_period
FROM DATE '2026-06-01' TO DATE '2026-06-15'
SET price = price * 0.9
WHERE product_id = 42;

이전에는 운영자가 직접 row를 자르고 새 row를 끼워 넣는 SQL을 손으로 썼다. PG 19부터는 한 문장으로 끝난다. 건드리지 않은 범위의 row는 자동으로 보존된다.

왜 운영자가 느끼나

가격 이력, 직원 직책 이력, 권한 이력, 보험료 이력 — 시간 범위 컬럼을 두는 모델은 흔하다. 매번 손으로 자르는 SQL을 짜는 대신 syntax 한 줄로 정리되는 자리가 늘어난다.

다만 — 새 운영 사각지대도 함께 생긴다.

주의 — row trigger · cascading FK

Pettus가 직접 짚는다.

“a FOR PORTION OF update can fire row triggers on rows that did not exist when the statement started.”

(FOR PORTION OF UPDATE는 문이 시작될 때 존재하지 않던 row에 대해서도 row trigger를 발화시킬 수 있다.)

내부적으로 FOR PORTION OF는 원본 row를 잘라 새 row 두 개(또는 세 개)로 분리하고, 그중 하나에 UPDATE를 적용한다. 그 결과 — DELETE 트리거가 원본 row에, INSERT 트리거가 새 보존 row 둘에, UPDATE 트리거가 갱신된 부분 row에 각각 발화한다.

cascading foreign-key 동작은 한 단계 더 복잡해진다. parent 행의 시간 범위가 잘리면 child의 FK 동작이 어떻게 따라가는지 production에서 테스트하지 않고 올리면 사고 가능성이 크다. parent의 부분 UPDATE가 child를 DELETE해야 하는가, CASCADE해야 하는가, RESTRICT해야 하는가 — 운영 정책 결정이 SQL 한 줄 안에 묻혀 들어간다.

운영자가 할 일

  • FOR PORTION OF를 production에 올리기 전에 row trigger · FK · audit trigger 동작을 staging에서 전부 확인
  • 트리거가 row 단위로 카운트를 세는 코드(예: audit row 개수 검증)는 PG 19에서 결과가 다를 수 있다 — 재검토

4. jit = off 기본값 — PG 12부터 처음으로 다시 꺼지는 자리

무엇이 바뀌었나

Just-in-time compilation 기본값이 off로 바뀐다. PG 12에서 jit = on이 기본값으로 들어온 이후 처음 있는 방향 전환이다.

왜 운영자가 느끼나

이 변경은 워크로드 성격에 따라 정반대 결과를 만든다.

워크로드PG 18까지PG 19 Beta
OLTP (짧은 쿼리 다수)JIT plan 오버헤드가 매 쿼리마다 누적plan 시간 단축, 응답성 개선
OLAP (긴 분석 쿼리)JIT 컴파일 후 실행 가속명시적으로 jit = on 안 켜면 회귀

Pettus는 OLAP 회귀의 크기를 한 줄로 묘사한다.

“a six-minute report now takes nineteen.”

(6분짜리 리포트가 19분 걸리게 된다.)

3배 회귀 사례를 예고하는 자리다. OLAP 클러스터를 PG 19로 올리면서 jit = on을 명시 설정하지 않으면, 출시 직후 가장 먼저 받는 분기 보고서가 평소보다 한참 늦게 도착한다.

운영자가 할 일

  • OLTP 클러스터: 그대로 두면 자연스럽게 plan 효율 개선. 별도 설정 불필요.
  • OLAP · 분석 클러스터: 업그레이드 직후 ALTER SYSTEM SET jit = on; 실행. 또는 분석 사용자의 ALTER ROLE ... SET jit = on;으로 user-level 지정.
  • 혼합 워크로드: pgBouncer 등의 connection pool에서 분석 트래픽 분리한 뒤 그쪽만 jit = on 적용

왜 방향이 바뀌었는가

PG 12에서 JIT를 기본 활성화한 동기는 “분석 쿼리에서 측정 가능한 가속이 있다"였다. 하지만 운영 통계가 쌓이면서 — OLTP가 절대 다수인 PostgreSQL 운영 현실에서 plan 시간 오버헤드 손실이 컴파일 가속 이득을 자주 초과한다는 점이 드러났다. 6년 만에 측정 기반으로 기본값이 복귀하는 자리다.

PG 19 업그레이드 체크리스트 (이번 Big 4 자리)

업그레이드 전 다음을 점검한다.

점검 항목명령 / 확인
maintenance_work_mem 현재 값SHOW maintenance_work_mem;
autovacuum_max_workers 현재 값SHOW autovacuum_max_workers;
최악 메모리 사용량 재계산autovacuum_max_workers × autovacuum_max_parallel_workers × maintenance_work_mem
OLAP/혼합 워크로드 식별분석 ETL · BI 도구 사용 여부
시간 범위 컬럼 사용 테이블 식별\d+ 로 PERIOD 컬럼 점검
MultiXact 모니터링 운영 매뉴얼“PG 19부터 도달 불가” 주석

업그레이드 직후에는 다음을 즉시 확인.

-- 1. autovacuum 동작 확인
SELECT * FROM pg_stat_progress_vacuum;

-- 2. JIT 설정 확인 (OLAP면 명시 on)
SHOW jit;

-- 3. 새 GUC 확인
SHOW autovacuum_max_parallel_workers;

정리

변경운영자가 얻는 것운영자가 새로 봐야 하는 것
64bit MultiXact members최악 wraparound 시나리오 제거PG 18 이하 클러스터 모니터링은 유지
병렬 autovacuum 인덱스 workerwide table autovacuum 시간 단축최악 메모리 사용량 식이 달라진다
UPDATE/DELETE FOR PORTION OF시간 범위 SQL 한 줄로 정리row trigger · cascading FK 동작 재검증
jit = off (기본)OLTP plan 시간 단축OLAP는 명시 활성화 안 하면 회귀

PostgreSQL 19는 화려한 신기능이 아니라 운영 매뉴얼을 다시 쓰게 만드는 릴리스다. 운영자 입장에서 이번 Big 4는 9월 정식 출시 전에 staging에서 한 번 돌려 보고, 메모리 식·튜닝 기본값·운영 매뉴얼 세 자리를 같이 갱신해야 한다.

기존 PG 19 새 기능 총정리PG 19 시리즈 4편“어떤 기능이 들어오는가” 시각이었고, 이번 글은 “어떤 운영이 달라지는가” 시각이다. 두 글을 같이 두면 PG 19를 올리기 전 점검할 자리가 한 자리에 모인다.

참고