概要
pgrust は Rust で書き直された PostgreSQL データベースシステムで、Postgres 18.3 と互換性があり、4.6万件以上のリグレッションクエリに合格し、ディスクフォーマットもネイティブの Postgres と互換性があります。プロジェクトの目標は、Rust と AI 支援開発によって Postgres の改修のハードルを下げることです。
README プレビュー
pgrust\n\n\n A Postgres rewrite in Rust.\n\n\n\n \n \n \n \n \n\n\n\n Browser demo\n | \n Discord\n | \n Get pgrust updates\n | \n Issues\n\n\n\n\npgrust targets compatibility with Postgres 18.3 and matches Postgres's\nexpected output across more than 46,000 regression queries.\n\npgrust is disk compatible with Postgres and can boot from an existing Postgres\n18.3 data directory.\n\nThe goal is to make Postgres easier to change from the inside: keep the behavior\nPostgres-shaped, keep the real Postgres tests as the oracle, and use Rust plus\nAI-assisted programming to explore deeper server changes.\n\nUpdate: We're working on a new not yet published version of pgrust that currently passes 100% of Postgres regression suite, has a thread per connection model instead of process per connection, is 50% faster than Postgres on transaction workloads, and is ~300x faster than Postgres on analytical workloads (2x slower than Clickhouse on clickbench and we think it can get faster than Clickhouse). Follow pgrust or join our Discord for updates!\n\n## Follow pgrust\n\n[Get project updates by email](https://pgrust.com/#updates), including new\nreleases, compatibility milestones, and architecture experiments.\n\n## Status\n\npgrust is not production-ready yet. It is not performance optimized yet.\n\nExisting Postgres extensions and procedural language extensions such as\nPL/Python, PL/Perl, and PL/Tcl are not generally compatible yet. Some bundled\ncontrib modules are already ported, and more compatibility may be possible over\ntime.\n\n## Roadmap\n\n- multithreaded Postgres internals\n- built-in connection pooling\n- better JSON-heavy workload support\n- fast forking and branching workflows\n- storage experiments, including no-vacuum designs\n- runtime guardrails for bad queries and AI-generated SQL\n- fewer sudden bad plan switches\n\n## Try It\n\nTry the WebAssembly demo at https://pgrust.com.
FAQ (5)
トラブル対応pgrustでクラッシュリカバリ後にDROP TABLEがCPU 100%でハングする場合の修正方法
これは WAL redo に起因するバッファピンのリークが原因です。recovery prefetcher の io_uring レーンが、最後にプリフェッチしたページを startup スレッドのリングスロット内にピン留めしたまま残してしまいます。InvalidateBuffer はその foreign pin 上でスピンし続け、キャンセルできなくなります。
修正: PR #2062、コミット 4f84297963e(xlogrecovery: drain prefetch pins after the redo loop)を含むビルドへ pgrust をアップグレードしてください。このパッチは、redo ループの直後、かつリカバリ終了時チェックポイントの前にプリフェッチリングをドレインし、foreign pin の待機をキャンセル可能にします。以下でビルドして再起動します。
git fetch origin
git checkout 4f84297963e # or any later commit containing the fix
cargo build --release --locked --bin postgres
その後、サーバーを再起動して DROP TABLE を再試行してください。リカバリ後、pg_buffercache で pinning_backends = 0 となっていることを確認し、そのリレーションにリークしたピンが残っていないことを検証してください。
脆弱なビルドでの一時的な緩和策: 計画的な停止の前に、大量の挿入の後で CHECKPOINT を実行してください。これにより、リカバリ中にそれらのページが WAL のみからリプレイされることを防ぎます。これは予期しないクラッシュからは保護しません。バックエンドがすでにスピンしている場合、pg_cancel_backend では停止できません。パッチ適用済みのビルドで再起動してください。
トラブル対応pgrust で PostgreSQL の IDENTITY カラムを含むテーブルへの INSERT に対して EXPLAIN VERBOSE を実行したときに発生する「T_NextValueExpr deparse arm unported」エラーを修正するにはどうすればよいですか?
これは、EXPLAIN VERBOSE が GENERATED ALWAYS AS IDENTITY 列のプランをデパースする際に、pgrust 0.2 に影響します。即時の回避策: VERBOSE を付けずに EXPLAIN を実行してください。例:
EXPLAIN INSERT INTO t (v) VALUES (1);
他のオプションを使用する場合も VERBOSE を省略できます:
EXPLAIN (ANALYZE, BUFFERS) INSERT INTO t (v) VALUES (1);
プランは出力されますが、identity シーケンスの nextval(...) 式を含む verbose の Output: 行は省略されます。
恒久対策: PR #472 を含むビルドへ pgrust をアップグレードしてください(main で修正済み、2026-08-08)。この修正により NextValueExpr は nextval('seq') としてデパースされ、PostgreSQL 18.6 と一致します。serial 列は通常の DEFAULT nextval(...) パスを使用するため、影響を受けません。
トラブル対応pgrustでformat()にNULLIF、GREATEST、IS NULL、またはANDを渡した際に発生する「funcapi exprType: node family T_NullIfExpr not ported」エラーはどうすれば修正できますか?
pgrust を、コミット 77ab13c454b を含む現在の main ビルドにアップグレードしてください。この修正により、funcapi は引数の型解決を nodes_core::node_funcs::expr_type に委譲するようになり、T_NullIfExpr、T_MinMaxExpr、T_NullTest、T_BoolExpr、T_DistinctExpr、T_BooleanTest、T_ScalarArrayOpExpr、T_SubPlan、および関連する式ファミリーがカバーされます。これは、PostgreSQL 18.3 互換コードを用いた pgrust 0.2 と、実行時に解決される "any" または VARIADIC "any" 引数を使用する関数(format()、concat()、concat_ws()、json_build_object() など)に影響します。すぐにアップグレードできない場合は、問題のある式をマテリアライズド CTE またはサブクエリ内で評価し、生の式ではなく、得られた列/Var を関数に渡してください。
トラブル対応SERIALIZABLE トランザクションを開始する際に発生する "SERIALIZABLEXACT slots exhausted and the pg_serial summarization path is not ported" パニックの修正方法
このパニックは、サイズが (MaxBackends + max_prepared_xacts) * 10 である固定 SERIALIZABLEXACT プールが満杯になったときに発生します。影響を受ける pgrust ビルドでは、pg_serial SLRU の要約処理が実装されていなかったため、GetSerializableTransactionSnapshot はコミット済みの最も古いシリアライザブルトランザクションを再利用する代わりにパニックしていました。
修正方法は、PR #168 を含む現在の main ビルドにアップグレードすることです。これにより、実際の pg_serial SLRU が移植され、GetSerializableTransactionSnapshotInt が SummarizeOldestCommittedSxact と CreatePredXact を組み合わせてループするようになり、PostgreSQL の動作と一致します。SerialAdd、SerialSetActiveSerXmin、CheckPointPredicate も実装されています。
手順:
1. PR #168 を含む main のコミットを取得してビルドします。
2. データベースを再デプロイして再起動します。
3. 必要に応じて scripts/ssi-sxact-exhaustion-e2e.sh で検証します。このリグレッションテストはスロットプールを使い切り、CHECKPOINT を実行し、パニックが発生せずサーバーが正常な状態を維持していることを確認します。
古いビルドでの一時的な緩和策:
- SERIALIZABLE トランザクションの同時実行数またはコミットレートを下げます。
- SxactGlobalXmin をピン留めする長時間実行の SERIALIZABLE セッションを避けます。
- 安全であれば、max_prepared_transactions または MaxBackends を増やしてプールのしきい値を引き上げ、その後再起動します。
- 正確性の要件が許す場合に限り、更新頻度の高いトランザクションを READ COMMITTED に移行します。これによりシリアライザブルの保証は弱まります。
トラブル対応coverage-guard のトリップ後に pgrust の parallel/morsel VACUUM で発生する dead_items_info.num_items の二重カウントまたはデバッグアサーションの失敗を修正する方法
このバグは、PGRUST_RUNTIME_VACUUM=1 で有効化される実験的な parallel/morsel VACUUM パスに影響します。カバレッジガードが resume_g を巻き戻した際に、シリアルアームがそれらのページを再スキャンする前に、リーダーが再開ポイントより上方の遅延クリーンアップページを処理する可能性がありました。dead_items_add() はブロックの TID を置き換えていましたが、それでも dead_items_info.num_items を再度インクリメントしていたため、二重カウントが発生し、デバッグビルドで debug_assert_eq!(tids.len() as i64, vacrel.dead_items_info.num_items) が発動していました。
修正: PR #469/現在の main を含む pgrust ビルドに更新してください。この修正により、round_drain_plan がリーダー遅延のクリーンアップページを巻き戻された再開ブロックより下にクランプし、各ページが1つのアームによってのみドレインされることが保証されます。リグレッションテストには morsel_coverage_trip_counts_each_dead_item_once と morsel_verified_round_drains_all_runs_and_deferred が含まれます。
一時的な回避策: 実験的なパラレル vacuum パスを無効にします:
unset PGRUST_RUNTIME_VACUUM
# または
PGRUST_RUNTIME_VACUUM=0
本番環境では、PGRUST_RUNTIME_VACUUM_FAULT=lose-local などのテスト用フォールトインジェクションを有効にしないでください。