pg_durable: 마이크로소프트, 데이터베이스 내 내구성 실행을 오픈소스화

발행: (2026년 6월 6일 AM 12:59 GMT+9)
11 분 소요

출처: Hacker News

PostgreSQL에 상태를 보관하고 있는 팀을 위해, 백그라운드 작업을 신뢰할 수 있게 만들기 위해 크론 잡, 워커, 큐, 상태 테이블을 뒤섞어 사용하던 방식을 그만두고 싶다면, 장시간 실행되며 장애에 강한 SQL 함수를 제공합니다. 워크플로를 SQL로 정의하고, pg_durable가 각 단계를 체크포인트하며, 충돌·재시작·실패한 단계 이후에도 실행을 재개합니다.

내구성 있는 실행은 이제 표준 산업 패턴이며, pg_durable는 별도의 서비스 인프라 없이 Postgres 내부에 이를 구현합니다. 데이터에 가까운 컴퓨팅을 제공한다는 우리의 사명 중 하나입니다.

이것이 나에게 맞나요?

대상 독자

  • 데이터를 다루는 백엔드·데이터 엔지니어로, 워크플로가 데이터와 같은 위치에 있기를 원하는 사람
  • 재시작에도 살아남고 SQL로 감사 가능한 런북을 자동화하려는 DBA·SRE
  • 행·문서·배치 단위로 내구성 있는 실행이 필요한 데이터·AI 파이프라인을 구축하는 팀

핵심 아이디어

pg_durable 함수는 PostgreSQL이 실행하면서 체크포인트를 찍는 SQL 단계들의 그래프입니다. 데이터베이스가 충돌하거나 재시작되거나 단계가 실패하면, 마지막 내구성 체크포인트부터 실행을 재개하므로 상태를 직접 복구할 필요가 없습니다.

내구성 함수가 세 개의 병렬 쿼리(사용자 수, 주문 수, 매출 합계)로 팬아웃된 뒤 대시보드 단계와 조인되는 모습

유용한 워크로드

  • 벡터 임베딩 파이프라인: 청크화 → 임베딩 API 호출 → pgvector에 업서트
  • 인제스트 파이프라인: 스테이징 → 중복 제거 → 변환 → 대량 배치 퍼블리시
  • 정기 유지보수: 팽창 탐지 → 알림 → 승인 대기 → 다음 작업 실행
  • 팬아웃 집계: 독립 쿼리를 병렬 실행 후 결과 조인
  • 외부 API 워크플로: 데이터 강화, 분류, 웹훅 스타일 호출 등을 SQL에서 수행

현재 여러분이 하고 있을 가능성이 높은 방식

  • pg_cron + 작업 테이블, 상태 컬럼, 재시도 카운터, 폴링 워커
  • Airflow, Temporal, Step Functions, Argo 등 외부 오케스트레이터가 Postgres를 호출하는 형태
  • 큐 + 워커 + 별도 상태 테이블을 이용해 재시도와 부분 완료를 조정
  • 충돌이나 장시간 트랜잭션이 발생하면 처음부터 다시 시작해야 하는 plpgsql 프로시저

해결하는 고통 포인트

  • 긴 작업 도중 재시작하면 이미 성공한 작업을 다시 실행해야 함
  • 한 행 혹은 한 API 호출 실패가 수동 정리와 불확실한 재실행으로 이어짐
  • 장시간 트랜잭션이 락을 잡고 WAL을 늘려 대규모 배치 작업을 취약하게 함
  • 애플리케이션 계층에서 병렬 작업을 하면 부분 실패 버그와 드리프트가 늘어남
  • 워크플로 로직이 SQL, 워커, 큐, 대시보드, 상태 테이블에 흩어짐

아키텍처에 일어나는 변화

  • 워크플로 정의가 SQL로 이동하고 df.start(...) 로 시작
  • 재시도 상태·진행 추적·체크포인트가 맞춤형 앱 코드가 아니라 Postgres에 저장
  • 일부 애플리케이션 워커, 큐 컨슈머, 스케줄러 연결 코드가 완전히 사라질 수 있음
  • 운영 가시성은 df.instances 같은 Postgres 테이블에서 제공되며, 데이터와 동일한 인증·백업 모델을 사용

사용을 피해야 할 경우

  • 작업이 이미 단일 INSERT … SELECT 혹은 일반 SQL 문 하나로 이루어진 경우
  • 내구성 있는 백그라운드 실행이 아니라 서브밀리초 수준의 동기 요청 처리가 필요한 경우
  • 확장 프로그램을 설치하거나 백그라운드 워커를 실행할 수 없는 환경인 경우
  • 워크플로가 대부분 Postgres 외부에 존재하고 이기종 시스템을 많이 오가는 경우
  • SQL 단계, 분기, 루프, HTTP 호출 등으로 깔끔히 매핑되지 않는 임의의 애플리케이션 로직이 필요한 경우

작동 방식

  • ~>·|=> 같은 조합 가능한 연산자를 사용해 SQL로 워크플로 정의
  • df.start() 로 시작하고 인스턴스 ID를 반환
  • 런타임이 각 단계를 내구성 있게 실행하고 단계 사이에 체크포인트를 기록
  • 워크플로 실행 중이든 완료 후든 PostgreSQL에서 상태와 결과를 조회

제한 사항

모델은 의도적으로 SQL 형태에 맞춰져 있습니다. 단계가 임의의 코드, 비‑HTTP SDK, 복잡한 메모리 제어 흐름을 필요로 하면 해당 로직을 SQL 함수로 감싸거나 df.http() 용 HTTP 엔드포인트 뒤에 두거나, 그 부분만 별도 범용 오케스트레이터를 사용해야 할 수 있습니다.

기능

  • 내구성 — 함수 상태가 PostgreSQL에 영구 저장됩니다. 충돌·재시작·페일오버를 견딥니다.
  • SQL‑네이티브 — 조합 가능한 연산자를 사용해 SQL로 함수를 정의합니다.
  • 데이터베이스 인식 — 스케줄링·조건·병렬 실행을 위한 일급 프리미티브 제공
  • 인프라 제로 — PostgreSQL 확장으로 동작합니다. Redis·Temporal·외부 서비스가 필요 없습니다.

간단 예시

'batch'
    ~> 'UPDATE documents SET processed = true WHERE id = ANY($batch)'
);">-- 단계별로 데이터를 처리하는 내구성 함수
SELECT df.start(
    'SELECT id FROM documents WHERE processed = false LIMIT 100' |=> 'batch'
    ~> 'UPDATE documents SET processed = true WHERE id = ANY($batch)'
);

패키지

태그된 릴리스는 GitHub 릴리스 자산에서 amd64용 PostgreSQL 17·18 Debian 패키지를 제공합니다. 패키지 이름은 pg-durable-postgresql-_-1_.deb이며, 확장 라이브러리·컨트롤 파일·SQL 업그레이드 파일을 해당 PostgreSQL 설치 디렉터리에 넣습니다.

패키지를 설치한 뒤 shared_preload_librariespg_durable를 추가하고 PostgreSQL을 재시작한 뒤, 설정된 pg_durable 데이터베이스에서 확장을 생성합니다.

CREATE EXTENSION pg_durable;

기본 pg_durable 데이터베이스는 postgres이며, 백그라운드 워커 설정·권한 구성은 User Guide를 참고하세요.

릴리스 자산에는 소스 아카이브도 포함되어 있어 직접 빌드할 수 있습니다.

개발 설치

전제 조건

  • PostgreSQL 17 또는 18
  • Rust (nightly)
  • cargo-pgrx 0.16.1

GitHub Codespace

메인 브랜치는 PostgreSQL 17을 미리 설치하고 pg_durable를 빌드한 뒤 ~/.pgrx 아래 로컬 클러스터를 준비합니다. PostgreSQL은 실행 중이지 않으니 작업을 시작할 때 직접 시작하세요.

# PostgreSQL 시작
./scripts/pg-start.sh

# 연결
~/.pgrx/17.*/pgrx-install/bin/psql -h localhost -p 28817 -d postgres

프리빌드가 없는 브랜치를 사용할 경우 pg-start.sh 를 실행하면 최초 실행 시 확장을 빌드·설치합니다(몇 분 소요).

./scripts/pg-start.sh

기타 환경

로컬 및 Dev Container

VS Code Dev Container(.devcontainer/)는 Rust, cargo-pgrx, PostgreSQL 17이 미리 설치된 환경을 제공합니다. 일반 로컬 머신에서는 .devcontainer/onCreateCommand.sh 를 따라 툴체인을 먼저 설치하세요.

# 빌드, PostgreSQL 초기화, 확장 설치
# 시간이 좀 걸리니 다른 작업을 해두세요
./scripts/pg-start.sh

# 로컬 pgrx PostgreSQL 인스턴스에 연결
~/.pgrx/17.*/pgrx-install/bin/psql -h localhost -p 28817 -d postgres

pg-start.shpostgres 슈퍼유저와 현재 OS 사용자를 위한 동일 이름 슈퍼유저 역할을 가진 새로운 로컬 데이터 디렉터리를 부트스트랩합니다. 기본 psql 사용이 그대로 동작합니다. 명시적으로 postgres 역할을 쓰려면 -U postgres 옵션을 추가하세요.

Docker

# 빌드 및 테스트
./scripts/test-e2e-docker.sh --rebuild

# 선택 사항: 커스텀 PG17 이미지에 pg_durable를 포함해 ACR에 배
0 조회
Back to Blog

관련 글

더 보기 »

OpenAI, SEC에 S‑1 초안 제출

We recently submitted a confidential S-1. We expect it to leak so we’re just announcing it. We have not decided on timing yet; it may be a while because there a...