Microsoft pg_durable: PostgreSQL를 위한 인-데이터베이스 내구성 있는 실행

Microsoft는 데이터베이스 내에서 직접 내구성 있는 실행을 구현하도록 설계된 PostgreSQL 확장 프로그램인 pg_durable을 오픈 소스로 공개했습니다. 개발자가 SQL을 사용하여 장기 실행되고 결함 허용이 가능한 워크플로를 정의할 수 있게 함으로써, pg_durable은 백그라운드 작업을 관리하기 위한 외부 오케스트레이터, 별도의 큐 시스템 또는 복잡한 상태 추적 테이블의 필요성을 제거합니다.

PostgreSQL 내부의 내구성 있는 실행

pg_durable은 PostgreSQL이 실행하고 체크포인트를 생성하는 SQL 기반 함수 그래프를 생성할 수 있게 합니다. 데이터베이스가 충돌하거나 재시작되거나 특정 단계가 실패하면, 프로세스의 전체 재시작을 요구하는 대신 마지막 내구성 있는 체크포인트에서 실행이 재개됩니다. 이 접근 방식은 재시도 상태, 진행 상황 추적 및 체크포인팅과 같은 오케스트레이션 로직을 애플리케이션 계층에서 데이터베이스 자체로 이동시킵니다.

핵심 기능

  • SQL-Native Definition: 워크플로는 ~>|=>와 같은 조합 가능한 연산자를 사용하여 정의됩니다.
  • Zero Infrastructure: 이 시스템은 PostgreSQL 확장 프로그램으로 실행되므로 Redis, Temporal 또는 Airflow와 같은 외부 서비스가 필요하지 않습니다.
  • Database-Aware Primitives: 이 확장 프로그램은 스케줄링, 조건부 로직 및 병렬 실행에 대한 일급 지원을 제공합니다.
  • Fault Tolerance: 함수 상태는 PostgreSQL에 영구적으로 저장되어 충돌 및 장애 조치(failover) 시에도 생존을 보장합니다.

예시 워크플로

사용자는 개별 단계로 데이터를 처리하는 내구성 있는 함수를 시작할 수 있습니다. 예를 들어, 다음 SQL은 처리되지 않은 문서를 가져와 배치로 업데이트하는 프로세스를 시작합니다:

SELECT df.start(
    'SELECT id FROM documents WHERE processed = false LIMIT 100' |=> 'batch'
    ~> 'UPDATE documents SET processed = true WHERE id = ANY($batch)'
);

대상 워크로드 및 사용 사례

pg_durable은 지연 시간을 줄이고 아키텍처 복잡성을 낮추기 위해 컴퓨팅이 데이터와 가까이 있어야 하는 워크로드에 최적화되어 있습니다.

권장 사용 사례

  • Vector Embedding Pipelines: 데이터를 청킹하고, 임베딩 API를 호출하고, 결과를 pgvector에 업서트(upsert)합니다.
  • Ingest Pipelines: 대량의 데이터를 스테이징, 중복 제거, 변환 및 게시합니다.
  • Scheduled Maintenance: 데이터베이스 비대화(bloat)를 감지하고, 관리자에게 알림을 보내며, 승인 후 정리 작업을 실행합니다.
  • Fan-out Aggregation: 독립적인 쿼리를 병렬로 실행하고 결과를 결합합니다.
  • External API Workflows: SQL에서 직접 데이터 보강(enrichment), 분류 및 웹훅 스타일의 호출을 처리합니다.

pg_durable 사용을 피해야 할 때

  • Simple Queries: 작업이 단일 INSERT ... SELECT 또는 표준 SQL 문인 경우 pg_durable은 불필요합니다.

  • Low Latency: 밀리초 미만 단위의 동기식 요청 처리를 목적으로 하지 않습니다.

  • External-Heavy Workflows: 워크플로가 많은 이기종 시스템에 걸쳐 있고 주로 PostgreSQL 외부에서 실행된다면 범용 오케스트레이터가 더 적합합니다.

  • Complex Application Logic: SQL 단계, 분기, 루프 또는 HTTP 호출로 매핑되지 않는 로직은 애플리케이션 계층에 유지되어야 합니다.

기술 아키텍처

pgrx로 구축된 pg_durable은 서버 내에서 완전히 작동하는 PostgreSQL 확장 프로그램입니다. 함수 그래프를 구축하기 위한 SQL DSL과 실행을 관리하는 백그라운드 워커로 구성됩니다.

기반 프레임워크

  • duroxide: 결정론적 재생(deterministic replay), 체크포인트, 타이머를 포함한 오케스트레이션 런타임을 제공하는 내구성 있는 작업 프레임워크입니다.
  • duroxide-pg: duroxide를 위한 PostgreSQL 기반 상태 제공자로, 런타임 상태(인스턴스, 히스토리 및 작업 큐)를 전용 duroxide.* 스키마에 영구적으로 저장합니다.

데이터 조직

  • df.* Schema: DSL 그래프, 노드, 인스턴스 및 변수를 저장합니다.
  • duroxide.* Schema: duroxide-pg 제공자가 소유한 내부 런타임 상태를 저장합니다.

설치 및 배포

pg_durable는 현재 Preview 상태입니다. 태그된 릴리스는 amd64용 PostgreSQL 17 및 18에 대한 Debian 패키지를 제공합니다.

설정 프로세스

  1. PostgreSQL 설치 디렉토리에 패키지를 설치합니다.
  2. shared_preload_librariespg_durable을 추가합니다.
  3. PostgreSQL을 재시작합니다.
  4. 확장 프로그램을 생성합니다: CREATE EXTENSION pg_durable;

보안 및 멀티 테넌시

액세스 권한은 명시적인 권한 부여를 통해 관리됩니다. 관리자는 애플리케이션 역할을 위해 SELECT df.grant_usage('app_role');를 사용하여 액세스 권한을 부여해야 합니다. 행 수준 보안(RLS)을 통해 사용자는 자신의 내구성 있는 함수 인스턴스 및 노드만 관리할 수 있습니다. 백그라운드 워커 역할(기본값: azuresu)은 RLS를 우회하고 모든 사용자 인스턴스를 관리하기 위해 슈퍼유저여야 합니다.

커뮤니티 관점 및 트레이드오프

엔지니어들 사이의 논의는 "데이터베이스-as-오케스트레이터" 접근 방식을 선호하는 사람들과 전통적인 외부 DAG 스케줄러를 선호하는 사람들 사이의 의견 차이를 보여줍니다.

주요 반대 의견

  • Control Flow Location: 일부 개발자들은 제어 흐름과 큐 로직이 데이터베이스 내부가 아닌 버전 관리된 코드(Git)에 있어야 한다고 주장합니다.
  • Resource Contention: 데이터베이스—인프라에서 가장 확장하기 어려운 부분인 경우가 많음—에 추가적인 장기 실행 백그라운드 작업을 로드하는 것에 대한 우려가 있습니다.
  • Comparison to Temporal: 일부 사용자는 pg_durable는 의도적으로 SQL 형태를 갖추고 있어 범위가 더 제한적이라는 점을 언급하며, pg_durable가 Temporal과 같은 도구와 어떻게 비교되는지 질문했습니다.
  • Inner-Platform Effect: 한 비평가는 이것이 프로그래밍 언어의 기능(상태 중단 및 재개)을 데이터베이스 환경 내에서 재현하는 도구의 사례인 "inner-platform effect"의 사례일 수 있다고 제안했습니다.

Sources