LLM WikiAccess-protected knowledge portal
← 스터디 홈
69편 · 약 19분

PostgreSQL 18 DBA 가이드: 비동기 I/O·uuidv7·OAuth로 달라진 운영 기준

이 챕터를 쓰는 이유

PostgreSQL 18.0은 2025년 9월 25일 GA가 됐고, 18.4 보안 패치는 2026년 5월 14일에 배포됐다(CVE 11개 포함). 이 챕터는 18.4 패치 배포를 계기로 PostgreSQL 18 시리즈가 현재 프로덕션에서 운영되고 있다는 사실을 바탕으로, DBA가 반드시 이해해야 할 운영 변화를 정리한다.

18.x의 변화는 기능 추가 수준이 아니다. 비동기 I/O 서브시스템 도입은 PostgreSQL 25년 역사에서 가장 큰 I/O 아키텍처 변화 중 하나다. 이를 이해하지 못하면 클라우드 스토리지에서 2~3배의 성능 향상을 놓치거나, 반대로 잘못된 설정으로 문제를 일으킬 수 있다.

기준 버전: PostgreSQL 18.4 (2026-05-14 기준). 릴리스 날짜: PostgreSQL 18.0 GA 2025-09-25, 18.4 보안 패치 2026-05-14.


PostgreSQL 18 이전의 I/O 한계

PostgreSQL 17까지 모든 I/O는 동기 방식으로 처리됐다. 백엔드 프로세스가 디스크에서 페이지를 읽을 때 운영체제가 응답할 때까지 해당 프로세스는 완전히 블로킹된다. 단일 프로세스가 단일 I/O 요청만 처리하는 구조였다.

이 방식은 로컬 NVMe처럼 레이턴시가 낮은 스토리지에서는 문제가 없다. 하지만 클라우드 환경(AWS EBS, GCP Persistent Disk, Azure Managed Disk)에서는 I/O 레이턴시가 수백 마이크로초~수 밀리초 수준이다. 시퀀셜 스캔은 수백만 개의 블록을 순서대로 읽는데, 각 요청을 기다리는 동안 CPU가 놀고 있었다.

해결책은 비동기 I/O: 여러 I/O 요청을 동시에 발행하고, 각 응답이 올 때마다 처리하는 방식이다.


비동기 I/O 서브시스템: io_method

PostgreSQL 18은 io_method GUC(Grand Unified Configuration)를 도입해 세 가지 I/O 방식 중 하나를 선택할 수 있게 했다.

PostgreSQL 18 io_method 비교 io_method = sync (레거시 동기 방식) Backend 블로킹 대기 OS / Disk 요청 1개 응답 받기까지 블로킹 한 번에 I/O 1개 CPU 낭비 큼 cloud 스토리지에서 느림 문제 진단용 fallback 운영에서는 비권장 io_method = worker (기본값 — 모든 플랫폼) Backend I/O Worker Pool (백그라운드 프로세스) 요청 큐 → 비동기 처리 계속 실행 비블로킹! OS / Disk 비동기 I/O, 모든 OS worker 프로세스 오버헤드 있음 cloud storage: 2~3× 향상 프로덕션 기본값 (권장) 빠른 NVMe도 효과 있음 io_method = io_uring (Linux 5.1+, --with-liburing) Backend Ring Buffer (공유) SQ: 제출 큐 (Postgres) CQ: 완료 큐 (Kernel) 시스템 콜 없음 계속 실행 Linux Kernel / Disk 최저 레이턴시 syscall 오버헤드 제거 cloud storage: 최대 3× 향상 cloud/HDD 환경 추천 로컬 NVMe도 small gain pg_aios 시스템 뷰: 현재 in-flight I/O 핸들 수 모니터링 — SELECT count(*) FROM pg_aios WHERE state = 'in_progress';
PostgreSQL 18 비동기 I/O: io_method별 동작 비교

io_method 설정 방법

postgresql.conf에서 설정하며 재시작이 필요하다. 런타임 변경은 불가능하다.

# io_method는 postgresql.conf에서만 설정
io_method = worker          # 기본값, 모든 플랫폼
io_method = io_uring        # Linux 5.1+, --with-liburing 빌드 필요
io_method = sync            # 레거시/디버그용

io_uring을 사용하려면 PostgreSQL이 --with-liburing 옵션으로 빌드됐는지 먼저 확인한다.

-- liburing 지원 빌드 확인
SELECT pg_config_setting('with_liburing');
-- 또는
SHOW io_method;

어떤 워크로드에서 효과가 있는가

AIO는 현재 읽기 연산에만 적용된다: 시퀀셜 스캔(Seq Scan), 비트맵 힙 스캔(Bitmap Heap Scan), VACUUM 읽기 단계. 쓰기와 WAL은 여전히 동기 방식이다.

효과가 큰 환경:

  • 클라우드 네트워크 연결 스토리지(EBS, GCP PD, Azure Disk)
  • 디스크에서 읽어야 하는 cold data 비율이 높은 분석 쿼리
  • VACUUM이 자주 필요한 대형 테이블

효과가 제한적인 환경:

  • 데이터 대부분이 shared_buffers에 캐시된 경우
  • 로컬 NVMe SSD (레이턴시가 낮아 비동기 효과가 작음, 단 small gain은 있음)
  • CPU 바운드 쿼리 (조인, 집계 등)

새로운 모니터링 포인트: effective_io_concurrency 파라미터가 이제 실질적인 의미를 가진다. worker/io_uring 모드에서 동시 발행 I/O 요청 수를 제어한다.


uuidv7: B-트리 인덱스 단편화 해결

PostgreSQL 18은 uuidv7() 함수를 내장했다.

UUIDv4 vs UUIDv7의 차이

특성UUIDv4UUIDv7
생성 방식완전 무작위타임스탬프 + 무작위
정렬무작위 순서시간 순서 정렬
B-트리 인덱스심각한 단편화순차 삽입 패턴
INSERT 성능페이지 분리 빈번훨씬 낮은 분리 빈도
전역 고유성보장보장 (ts+random)

UUIDv4로 기본 키 인덱스를 만들면 각 INSERT가 B-트리의 무작위 위치에 들어가 페이지 분리(page split)가 자주 발생한다. 페이지 분리는 쓰기 증폭과 인덱스 블로트의 주원인이다.

UUIDv7은 48비트 밀리초 타임스탬프로 시작해 새 레코드가 인덱스의 오른쪽(최신) 부분에 삽입되도록 보장한다. 순차 삽입 패턴이어서 SERIAL이나 BIGSERIAL과 유사한 인덱스 효율을 내면서 전역 고유성도 유지한다.

-- uuidv7 사용 예시 (PostgreSQL 18+)
CREATE TABLE events (
    id UUID DEFAULT uuidv7() PRIMARY KEY,
    created_at TIMESTAMPTZ DEFAULT now(),
    payload JSONB
);

-- 타임스탬프 추출 (uuidv7에서 생성 시각 복원 가능)
SELECT uuidv7_to_timestamptz('0191f5c7-1234-7abc-bdef-000000000001');

가상 생성 열(Virtual Generated Columns)

PostgreSQL 18에서 GENERATED ALWAYS AS ... STORED 대신 기본값이 가상 생성 열로 바뀌었다.

STORED vs VIRTUAL 비교

구분STOREDVIRTUAL
저장 위치디스크에 실제 저장저장 없음
계산 시점INSERT/UPDATE 시SELECT 시
쓰기 오버헤드있음 (계산 + 저장)없음
읽기 오버헤드없음있음 (매번 계산)
인덱스 생성가능Open question (제한적)
-- VIRTUAL generated column (PostgreSQL 18 기본)
CREATE TABLE products (
    price NUMERIC,
    tax_rate NUMERIC,
    -- VIRTUAL: 디스크에 저장 안 됨, 쿼리 시 계산
    total_price NUMERIC GENERATED ALWAYS AS (price * (1 + tax_rate)) VIRTUAL,
    -- STORED: 이전 방식, 명시적으로 선언 필요
    total_price_stored NUMERIC GENERATED ALWAYS AS (price * (1 + tax_rate)) STORED
);

쓰기 집약적인 테이블에서 자주 계산하는 컬럼을 가상 생성 열로 전환하면 INSERT/UPDATE 성능이 개선된다.


기타 DBA 주요 변경사항

NOT NULL 추가: 전체 테이블 스캔 없음

이전에는 기존 테이블에 NOT NULL 제약을 추가하면 테이블 전체를 스캔해 기존 값을 검증했다. 대형 테이블에서는 수십 분이 걸렸다.

PostgreSQL 18은 이 검증을 지연(deferred) 방식으로 처리한다. 제약 추가는 즉시 완료되고, 기존 데이터 검증은 백그라운드에서 진행된다.

-- 18+: 즉시 완료, 백그라운드 검증
ALTER TABLE large_table ADD CONSTRAINT chk_col_not_null CHECK (col IS NOT NULL) NOT VALID;
-- 이후 검증 완료 선언
ALTER TABLE large_table VALIDATE CONSTRAINT chk_col_not_null;

OAuth 인증

PostgreSQL 18은 OAuth 2.0 인증을 pg_hba.conf에서 설정할 수 있다. 구현은 익스텐션 방식으로 특정 OAuth 제공자(Okta, Azure AD, Google 등)에 맞는 플러그인을 설치한다.

# pg_hba.conf 예시 (OAuth)
hostssl all all 0.0.0.0/0 oauth issuer="https://auth.example.com" scope="postgres"

기업 환경에서 중앙 IdP를 통한 데이터베이스 접근 제어가 가능해진다.

더 빠른 pg_upgrade

PostgreSQL 18은 pg_upgrade --copy-file-range를 도입해 파일 복사 속도를 개선했다. 대형 데이터베이스에서 업그레이드 다운타임이 줄어든다.


18.4 보안 패치 요약

2026년 5월 14일 배포된 18.4에는 11개 CVE가 포함됐다.

CVE심각도내용
CVE-2026-6479Highstartup 패킷 처리 시 무제한 재귀 → 백엔드 크래시
CVE-2026-6473Mediumpg_createsubscriber 구독 이름 SQL 인젝션
CVE-2026-6638Medium논리 복제 오리진 검사에서 SQL 실행 가능

CVE-2026-6479는 미인증 원격 공격자가 악의적인 SSL/GSS 협상 패킷으로 백엔드를 크래시시킬 수 있어 즉시 업그레이드가 권장된다.


PostgreSQL 18 업그레이드 체크리스트

빌드 확인 (io_uring 사용 시)
패키지 관리자로 설치 시: PostgreSQL 18 패키지가 --with-liburing으로 빌드됐는지 확인. 배포판마다 다를 수 있다.
Linux 커널 버전 5.1 이상 확인: uname -r. Amazon Linux 2023, Ubuntu 22.04+, RHEL 9+는 기본 충족.
io_uring 사용 전 worker 모드로 먼저 벤치마킹한 후 io_uring으로 전환해 실제 효과를 측정한다.
I/O 성능 튜닝
effective_io_concurrency를 클라우드 스토리지는 200~256, 로컬 SSD는 1~4로 조정한다. 기본값(1)은 AIO 효과를 충분히 내지 못한다.
pg_aios 뷰로 in-flight I/O 수를 확인한다: SELECT state, count(*) FROM pg_aios GROUP BY state;
maintenance_io_concurrency도 함께 조정해 VACUUM 성능을 높인다. 클라우드: 10~32 권장.
UUID 마이그레이션
신규 테이블은 uuidv7()를 기본값으로 사용한다. 기존 UUIDv4 기본 키 컬럼 마이그레이션은 인덱스 재구축이 필요하므로 영향도를 먼저 평가한다.
UUIDv7 기반 타임스탬프 복원이 필요하다면 uuidv7_to_timestamptz() 함수를 활용한다. created_at 컬럼을 별도 유지할지 UUID에서 추출할지 설계에 반영한다.
보안 패치 적용
18.4 미만이라면 즉시 업그레이드: CVE-2026-6479는 미인증 원격 크래시 취약점이다. 논리 복제를 사용하는 경우 CVE-2026-6638도 해당된다.
17.x 사용 중이라면 17.10도 동시 배포됐으므로 17.10으로 먼저 패치 후 18.4로 메이저 업그레이드를 계획한다.
OAuth 인증 도입 계획이 있다면 pg_hba.conf 변경 전 익스텐션 호환성과 IdP 구성을 테스트 환경에서 먼저 검증한다.
PostgreSQL 18 업그레이드 운영 체크리스트

정리

PostgreSQL 18의 DBA 핵심 판단 기준은 세 가지다.

비동기 I/O: 클라우드 스토리지 환경이라면 io_method = worker(기본값)로 즉시 이득을 볼 수 있다. Linux 5.1+ 환경이고 io_uring 빌드가 되어 있다면 io_uring으로 추가 최적화를 검토한다. effective_io_concurrency를 반드시 조정해야 효과가 나타난다.

uuidv7: 신규 서비스에서 전역 고유 ID가 필요하다면 UUIDv4 대신 uuidv7이 B-트리 인덱스 효율 측면에서 명확히 유리하다. 기존 테이블 마이그레이션은 인덱스 재구축 비용을 감안해 결정한다.

보안 패치: 18.4 미만 버전은 CVE-2026-6479로 인해 미인증 원격 크래시가 가능하다. 바로 패치하는 것이 맞다.

References