
2026/06/06 0:59
pg_durable:Microsoft がオープンソース化したインデータベース耐障害処理機能
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
pg_durable は、Airflow や cron ジョブなどの外部オーケストレータを必要とせず、直接データベース内で長時間実行可能で障害耐性を備えた SQL ワークフローを可能にする新しい PostgreSQL 拡張機能(バージョン 17/18)です。Microsoft によって設計され、Azure HorizonDB で利用可能な本ツールは、Rust をバックエンドとするランタイム「duroxide」を活用し、SQL だけで定義された複雑なステップグラフ(df.* スキーマ経由)を実行します。標準テーブル(df.instances、df.nodes)において自動的にチェックポイントと状態復元を処理するため、AI エンベッディングやバッチインゲシュンのようなデータパイプラインがクラッシュ後に手動介入なしに再開できます。従来の方法とは異なり、不安定な長時間実行トランザクションを、PostgreSQL の既存のセキュリティモデル、行レベル制限、バックアップ手順とシームレスに統合される自己修復論理で置き換えます。グローバル状態を管理するにはスーパーユーザー背景ワーカーロールが必要ですが、この拡張機能は PostgreSQL ライセンスの下でオープンソースであり、外部テリメトリの使用を明示的に回避しています。監査可能なランブックスの自動化を目指すバックエンドエンジニアや DBA にとって理想的ですが、サブミリ秒同期リクエストやデータベースクラスター外の異種システムを跨ぐワークフローには適していません。本文
pg_durable:耐障害性を備えた SQL ナティブなワークフロー実行エンジン
PostgreSQL に組み込まれ、長年継続運用に耐える高い信頼性を誇る SQL 関数 です。バックグラウンドタスクの信頼性を高めるために設計されており、独自のクロノジョブ、ワーカー、キュー、およびステートステーブルを組み合わせています。
ワークフローを SQL で定義し、各ステップにおいて
pg_durable がチェックポイントを確認することで、クラッシュや再起動からの復旧を実現します。「耐障害性のある実行(Durable Execution)」は業界標準ですが、pg_durable は追加のサービスインフラストラクチャなしで PostgreSQL 内にこの機能を統合します。これは「計算処理をデータに近づける」我々のミッションの一環です。
Azure HorizonDB での利用
Microsoft の新設された PostgreSQL クラウドサービス Azure HorizonDB では、パフォーマンスを重視して設計され、pg_durable が内部に組み込まれています。今すぐ試用可能です。
対象となるユーザー
pg_durable は以下の役割やチーム向けです。
- バックエンドエンジニアおよびデータエンジニア: データに触れたままワークフローを実現する際に向いています。
- DBA と SRE: 再起動にも耐え、SQL 上で監査可能な実行書式(runbooks)の自動化を追求する場合に最適です。
- データパイプライン構築チーム: 行、ドキュメント、またはバッチごとの耐障害性のある実行が必要な場合や、AI パイプラインの構築に必要な場合に適しています。
核心的な考え方
pg_durable 関数は、PostgreSQL が実行・チェックポイントを確認しながら進めていく SQL ステップのグラフ です。
- データベースがクラッシュしたり再起動したりした場合でも、手作業で状態を再構築する必要はありません。
- 最後の耐障害性のあるチェックポイントから実行を即座に再開できます。
この仕組みが役立つワークロード
pg_durable は多様な業務ユースケースに対応可能です。
- ベクトル埋め込みパイプライン: チャンク化、埋め込み API の呼び出し、
へのアップsert(結合挿入)。pgvector - 取り込みパイプライン: ステージング、重複排除、変換、および大量バッチの公開。
- スケジュールされたメンテナンス: バLOAT(肥大化)の検出・通知、承認を待った次のアクションの実行。
- ファノアウト集約: 独立したクエリの並列実行と結果の結合。
- 外部 API ワークフロー: 富化、分類、および SQL からの Webhook 風呼び出し。
代替手段とその課題
現在、以下の方法が使用されていますが、それぞれ課題を抱えています。
- pg_cron の利用: ジョブテーブル、ステータスカラム、再試行カウンター、ポーリングワーカーを使用する場合。
- 外部オーケストレーターの活用: Airflow、Temporal、Step Functions、Argo などが PostgreSQL へ呼び出しを返している場合。
- 複雑なキュー処理: キューや別のステートステーブルで調整を行っている場合。
- 脆弱な plpgsql スプロシージャ: クラッシュや長トランザクションにより再実行せざるを得ない場合。
解消する課題(ポイント)
- リプレイ問題: 中途半端に再起動すると、成功した作業を再び実行してしまいます。
- 手動 Cleanup の負担: 1 つの失敗が不確実な再実行(リプレイ)や、手動でのクリーンアップにつながります。
- ロックと WAL の増大: 長トランザクションはロックを保ち続け、WAL を増大させ、大規模バッチジョブを脆弱にします。
- 分散ロジックの弊害: ワークフローロジックが SQL、ワーカー、キューなどに分散し、部分的な障害によるバグやズレ(ドリフト)が発生しやすいです。
アーキテクチャにおける変化点
pg_durable を導入すると、以下の構造変化があります。
- ワークフロー定義の SQL 化:
で開始し、定義を SQL に移します。df.start(...) - 状態管理の内蔵化: 再試行ステートやチェックポイントングは PostgreSQL 内へ移行され、専用アプリコードが不要になります。
- グルー(コネクター)の消失: ワーカー、キュー消費者などのアプリケーション階層内のコネクティングティスクが完全になくなります。
- 運用可視性の向上: ステータスは PostgreSQL テーブル(例:
)から管理でき、同じ認証・バックアップモデルを使います。df.instances
使用すべきでない場合
pg_durable は以下のユースケースには適していません。
- ジオブ自体が単一の
や通常の SQL ステートメントである場合。INSERT ... SELECT - サブミリ秒単位での同期リクエスト処理が必要な場合。
- PostgreSQL エンバウンド環境でエクステンションのインストールやバックグラウンドワーカーの実行ができない場合。
- ワークフローの大部分が外部の heterogeneous システムにあり、PostgreSQL を横断する場合。
- SQL ステップ、分岐、ループに明確にマッピングできない複雑なアプリケーションロジックが必要である場合。
動作原理と制限事項
- 動作原理:
および~>
の組み合わせ可能なオペレーターを使用して SQL でワークフローを定義します。|=>
で開始し、インスタンス ID を取得します。Runtime は各ステップ間をチェックポイントを確認しながら耐障害性を持って実行します。df.start() - 制限事項: 「SQL 形状」に意図的に設計されています。任意のコードが必要や、豊富なインメモリ制御フローが必要な場合は、ロジックを SQL 関数内か
の HTTP エンドポイントでラップするか、汎用オーケストレーターを使用する必要があります。df.http()
主要な機能
- 耐障害性 (Durable): ステートは PostgreSQL に永続化され、クラッシュ・フェイルオーバーに耐えます。
- SQL ネイティブ: 組み合わせ可能なオペレーターで SQL で関数を定義します。
- データベース意識の高い (Database-aware): スケジュールリング、条件、並列実行のためのファーストクラスなプリミティブを提供します。
- ゼロインフラストラクチャ: PostgreSQL エクステンションとして動作し、Redis や外部サービスは不要です。
簡易例
以下のように SQL で耐障害性のある関数を定義・開始します。
-- ステップごとにデータを処理する耐障害性のある関数 SELECT df.start( 'SELECT id FROM documents WHERE processed = false LIMIT 100' |=> 'batch' ~> 'UPDATE documents SET processed = true WHERE id = ANY($batch)' );
インストールとパッケージ
パッケージ(リリースアセット)
GitHub のリリースアセットから、以下の形式の Debian パッケージを入手できます。
- 形式:
pg-durable-postgresql-<PG major>_<pg_durable version>-1_<arch>.deb - 対象: PostgreSQL 17 および 18、amd64 アーキテクチャ
- 構成: 拡張機能ライブラリ、コントロールファイル、SQL アップグレードファイルをインストール。
インストール後の必須手順:
# shared_preload_libraries に pg_durable を追加し、PostgreSQL を再起動 # 設定されたデータベース内で拡張機能を作成 CREATE EXTENSION pg_durable;
デフォルトのデータベースは
postgres です。詳細なバックグラウンドワーカー構成については「ユーザーガイド」をご覧ください。
開発環境でのインストール(ソースからビルド)
前提条件: PostgreSQL 17/18、Rust (nightly)、cargo-pgrx 0.16.1、GitHub Codespace。
-
プリビルド: GitHub のメインブランチでは、
下にローカルクラスターが準備されます(PostgreSQL 実行済みではないため手動起動が必要です)。~/.pgrx# PostgreSQL を起動 ./scripts/pg-start.sh # コネクション建立 ~/.pgrx/17.*/pgrx-install/bin/psql -h localhost -p 28817 -d postgres -
ソースからビルド: プリビルドのないブランチや、
の再実行。pg-start.sh./scripts/pg-start.sh # ローカル pgrx PostgreSQL インスタンスに接続 ~/.pgrx/17.*/pgrx-install/bin/psql -h localhost -p 28817 -d postgres
は新しいローカルデータディレクトリをブートストラップし、OS ユーザー向けのスーパユーザーロールを作成します。pg-start.sh -
Dev Container: VS Code Dev Container には Rust、PostgreSQL 17 などが事前インストールされています。
# ビルドとテスト ./scripts/test-e2e-docker.sh --rebuild # ACR へのデプロイ(オプション) ./scripts/deploy-acr.sh
マルチユーザー構成と権限付与
CREATE EXTENSION pg_durable は PUBLIC に権限を付与しません。インストール後は、管理者がアプリケーションロールに明示的にアクセス権限を与える必要があります。
権限付与方法
-
直接付与:
-- CREATE EXTENSION 後、特定のロールに付与 SELECT df.grant_usage('app_role'); -
仲介ロール(Indirection Role)を使用:
-- pg_durable アクセス用の共有ロールを作成 CREATE ROLE pg_durable_user NOLOGIN; SELECT df.grant_usage('pg_durable_user'); -- アプリケーションロールにメンバーシップを付与 GRANT pg_durable_user TO app_backend, etl_service;
重要事項(セキュリティとベストプラクティス)
-
アップグレード時の権限:
でアップグレードした際、新しい関数へのアクセス権がない場合があります。ALTER EXTENSION pg_durable UPDATE
を再実行するか手動で権限を付与する必要があります。df.grant_usage('role')注意:
は既存の関数のみ対象となります。GRANT EXECUTE ON ALL FUNCTIONS -
バックグラウンドワーカーロール: GUC
(デフォルトpg_durable.worker_role
)はスーパユーザーである必要があります。RLS をバイパスしてすべてのユーザーのインスタンスを管理するためです。postgres -
可視性制御: ユーザーには
に対しdf.instances / df.nodes
権限を与え、SELECT + INSERT
はUPDATE
用途に限定します。df.cancel() -
アイデンティティ保護: アイデンティティカラム(例:
)はユーザーによって変更できません。submitted_by -
変数空間:
はパーユーザのスコーピングを使用します。各ユーザーは独自の命名空間を持ち、スーパユーザーであっても DSL 関数は呼び出しユーザーにスコープされます。機密情報を平文で保存することを避けてください。df.vars
CI/CD とテスト
すべてのプルリクエストがマージされる前に以下のチェックが通過する必要があります。
- フォーマットチェック:
cargo fmt --check - 品質と検証:
、単体テスト (cargo clippy
)、pg_regress テスト、E2E テスト。cargo pgrx test pg17 - ワークフロー定義:
(pgrx を使用)。.github/workflows/ci.yml
テストスイート
-
pg_regress テスト(標準 PostgreSQL レグレッション):
- コア DSL 機能のための高速で決定論的なテストを提供。
-
make test-regress # フルリセット後実行 make installcheck # 実行のみ(PostgreSQL が既に稼働している必要あり)
-
E2E テスト(包括シナリオ):
- pgrx PostgreSQL を使用した複雑なローカル統合テスト。
-
./scripts/test-e2e-local.sh # ローカル SQL 全 E2E テスト ./scripts/test-e2e-local.sh 04_parallel # 特定のテスト(並列) ./scripts/test-e2e-local.sh --default-build-phases # デフォルトビルドフェーズグループのみ
ドキュメント
- ユーザーガイド: 例付きの完全な使用法ガイド。
- MVP ガイド: 実装詳細と内部構造に関する情報。
- Examples: サンプル規約およびスモークチェックガイダンス。
アーキテクチャ概要
pg_durable は PostgreSQL エクステンション(pgrx でビルド)です。すべてが PostgreSQL サーバー内で行われ、外部サービスは不要です。
- 機能公開: SQL DSL を使用して関数グラフを構築。
- 実行エンジン: Rust ライブラリ上で耐障害性を持って実行するバックグラウンドワーカーを登録。
- duroxide: 決定論的な再再生、チェックポイント、サブオーケストレーション、タイマーを含むオーケストレーション runtime。
- duroxide-pg: PostgreSQL 支援状態プロバイダー。Runtime ステートを拡張が所有する専用
スキーマに永続化します。duroxide.*
Rust/Python/Node で耐障害性を確保しつつステートを PostgreSQL に管理したい場合は、ホスト言語から直接
duroxide を使用可能ですが、pg_durable は SQL での定義を好む ユースケース向けです。
スキーマ構成
: DSL グラフ(ノード、インスタンス、変数)df.*
: runtime ステート(duroxide-pg が所有)duroxide.*
サポート情報とライセンス
- ステータス: プレビュー段階です。
- サポート: バグ報告や機能要望は GitHub Issues へ。(セキュリティ脆弱性は「SECURITY.md」の指示に従ってください。)
- 行動規範: 「Microsoft Open Source Code of Conduct」を採用しています。質問・懸念は
へ。opencode@microsoft.com - 商標: Microsoft のロゴまたはブランドの使用はガイドラインに従う必要があります。
- ライセンス: PostgreSQL ライセンス