
2026/02/24 0:33
**Show HN:PgDog ― アプリを改変せずにPostgreSQLを拡張する**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
PgDogは、接続プーリング、ロードバランシング、シャーディング、トランザクション・プール、ヘルスチェック、およびフェイルオーバー監視を1つの軽量サービスに統合したRustベースのPostgreSQLプロキシです。
それは2つのTOML構成ファイルを使用します―
pgdog.toml はホストリスト、シャーディングルール(HASH / LIST / RANGE またはスキーマベース)およびプール設定用、users.toml はユーザー名/パスワードのマッピング用です。オプションでコマンドライン上で --config、--users、--database_url を指定して上書きすることもできます。
ルーティングロジック:PgDogはクエリを解析し、書き込みはプライマリノードへ、読み取りはレプリカへ(必要に応じて読み取り専用トランザクションのルーティング付き)とルートします。また、クロスシャード操作を再記述します。サポートされるクエリタイプには SELECT、INSERT、UPDATE/DELETE、DDL、集計関数、部分的な ORDER BY / GROUP BY、複数タプル INSERT、および書き換え規則により自動で更新されるシャードキーが含まれます。
シャーディング機能:
pgdog.unique_id() を使用して BIGINT の主キーを生成します(シーケンスは不要)し、PostgreSQL の2フェーズコミットをサポートしてクロスシャード書き込みの原子性を保証します。再シャーディングワークフローが用意されており、スキーマ同期、データレプリケーション、および原子的な切替シーケンス(MAINTENANCE ON → RELOAD → MAINTENANCE OFF)があります。
モニタリング:PgBouncer スタイルの管理データベースと OpenMetrics エンドポイントを通じてメトリクスを公開します。Datadog ダッシュボードも同梱されています。
展開:Kubernetes(EKS またはセルフホスト)上で Helm チャートを使用して本番環境にデプロイでき、Terraform モジュールで ECS に、Docker Compose でローカルテストに、または単純に
cargo run --release で実行できます。
ライセンス:AGPL v3 の下で配布され、内部利用およびプライベートな変更は許可されていますが、ソフトウェアを公開サービスとして提供する場合はソースコードの開示が必要です。
要約すると、PgDog は最小限のカスタムコードで PostgreSQL ワークロードにスケーラブルなシャーディングを追加できるため、運用複雑性を削減し、スケール時のパフォーマンスを向上させます。
本文
PgDog – PostgreSQL のスケーリングを支えるプロキシ
PgDog は Rust で書かれ、接続プール、クエリのロードバランシング、およびデータベース全体のシャーディング機能を提供します。高速・安全で、商用ハードウェア上でも数千個の接続を管理できます。
ドキュメント
📘 PgDog ドキュメント – ご質問は Discord へどうぞ。
クイックスタート
Kubernetes
helm repo add pgdogdev https://helm.pgdog.dev helm install pgdog pgdogdev/pgdog
AWS
- EKS またはセルフホスト型 Kubernetes クラスター用の Helm チャート
- ECS 上に PgDog をデプロイする Terraform モジュール
Docker で試す
Docker Compose をインストールし、次を実行します。
docker compose up -d
起動後は
psql または任意の PostgreSQL クライアントで接続してください:
PGPASSWORD=postgres psql -h 127.0.0.1 -p 6432 -U postgres
デモデータ(3 シャード、2 シャーディングテーブル):
INSERT INTO users (id, email) VALUES (1, 'admin@acme.com'); INSERT INTO payments (id, user_id, amount) VALUES (1, 1, 100.0); SELECT * FROM users WHERE id = 1; SELECT * FROM payments WHERE user_id = 1;
特徴
設定
PgDog は以下の 2 ファイルを必要とします:
- pgdog.toml – ホスト、シャーディング設定、その他オプション
- users.toml – ユーザー名とパスワード
単一ユーザー・データベース(同一マシン)例:
# pgdog.toml [general] port = 6432 default_pool_size = 10 [[databases]] name = "pgdog" host = "127.0.0.1" # users.toml [[users]] name = "alice" database = "pgdog" password = "hunter2"
pgdog.toml のデータベースに users.toml に対応するユーザーが無い場合、プールは作成されず、接続できません。
ローカルデータベースとユーザーを作成:
CREATE DATABASE pgdog; CREATE USER pgdog PASSWORD 'pgdog' LOGIN;
トランザクション・プーリング
PgDog は PgBouncer と同様にトランザクション(およびセッション)プールをサポートし、
SET 文とスタートアップオプションも解析します。アプリケーションクラッシュ時の自動放棄トランザクション回滚や再同期など、高度な接続復旧機能があります。
ロードバランサ
PostgreSQL 用の OSI Layer 7 ロードバランサです。プロトコルを理解し、複数レプリカ(およびプライマリ)へプロキシし、ラウンドロビン・ランダム・最小アクティブ接続 のいずれかでトランザクションを均等に分配します。
例 – 2 ホスト間のラウンドロビン:
[[databases]] name = "prod" host = "10.0.0.1" role = "primary" [[databases]] name = "prod" host = "10.0.0.2" role = "replica"
ヘルスチェック
PgDog はリアルタイムでヘルシーホストのリストを保持し、失敗したホストは回転から除外され、クエリは再ルーティングされます。
シングルエンドポイント
pg_query を利用して各クエリを解析し、書き込み(INSERT, UPDATE, CREATE TABLE …)はプライマリへ、読み取りはレプリカへ送ります。アプリケーションは一度接続すれば読書の両方に使用できます。
トランザクション
プライマリ/レプリカ構成では、トランザクションは読み取り専用でない限りプライマリへルーティングされます:
BEGIN READ ONLY; SELECT * FROM users LIMIT 1; COMMIT;
フェイルオーバー
PgDog はレプリケーション状態を監視し、レプリカが昇格した場合に書き込みをリダイレクトします。Patroni や AWS RDS などと併用するのに適しています。
例 – 自動フェイルオーバーを有効化:
[general] lsn_check_delay = 0 [[databases]] name = "prod" host = "10.0.0.1" role = "auto" [[databases]] name = "prod" host = "10.0.0.2" role = "auto"
シャーディング
PgDog はシャーディングキーを解析してクエリを正しいシャードへルーティングします。クロスシャードクエリでは、結果をメモリ上で組み立てます。
例 – 同一データベースの 2 シャード:
[[databases]] name = "prod" host = "10.0.0.1" shard = 0 [[databases]] name = "prod" host = "10.0.0.2" shard = 1
少なくとも 1 つのシャーディングテーブルが必要です。
シャーディング関数
- PostgreSQL パーティション関数 – HASH, LIST, RANGE
- スキーマベースのシャーディング – 同一スキーマ内のテーブルは同じシャードへ
例 –
user_id に対するハッシュシャーディング:
[[sharded_tables]] database = "prod" column = "user_id"
リストシャーディング例:
[[sharded_tables]] database = "prod" column = "user_id" [[sharded_mapping]] database = "prod" column = "user_id" values = [1, 2, 3, 4] shard = 0 [[sharded_mapping]] database = "prod" column = "user_id" values = [5, 6, 7, 8] shard = 1
範囲シャーディングは
start/end を使用します。
スキーマベースのシャーディング例
[[sharded_schemas]] database = "prod" name = "customer_a" shard = 0 [[sharded_schemas]] database = "prod" name = "customer_b" shard = 1
customer_a のテーブルはシャード 0へ、customer_b はシャード 1へ送られます。
シャードへの直接クエリ
シャーディングキーを含むクエリは該当シャードにのみルーティングされます。例:
SELECT * FROM users WHERE user_id = $1;
クロスシャードクエリ
シャーディングキーが無い、または複数ある場合は全てのシャードへ送られ、PgDog が結果を統合します。
| Feature | Supported | Notes |
|---|---|---|
| Aggregates | Partial | がサポート |
| ORDER BY | Partial | 列は結果セットに含まれる必要あり |
| GROUP BY | Partial | ORDER BY と同様のルール |
| Multi‑tuple INSERT | ✔ | 1 文あたり 1 行 |
| Sharding key UPDATE | ✔ | 内部で SELECT/INSERT/DELETE を生成 |
| Subqueries | ✘ | 全シャードで実行 |
| CTEs | ✘ | 全シャードで実行 |
COPY
PgDog は
COPY(テキスト、CSV、バイナリ)を解析し、行を自動的にシャードへ分散します。
例:
COPY orders (id, user_id, amount) FROM STDIN CSV HEADER;
2フェーズコミット
PostgreSQL の 2 フェーズトランザクションをサポートし、クロスシャード書き込みの原子性を確保します。有効にすると PgDog が
PREPARE TRANSACTION と COMMIT PREPARED を自動で処理します。
ユニーク ID
PgDog はシーケンスなしでユニーク BIGINT を生成できます:
SELECT pgdog.unique_id();
タイムスタンプベースのアルゴリズムを使用し、秒間数百万件のユニーク番号を発行します。
シャードキー更新
3 つのステートメント(SELECT, INSERT, DELETE)で自動処理されます。単一行更新のみ許可され、多行更新はトランザクションを中断します。
pgdog.toml にて有効化:
[rewrite] enabled = true shard_key = "rewrite" # options: ignore, error
マルチタプル挿入
有効にすると各タプルがシャードへ送られ、ユニーク主キーが付与されます。
[rewrite] enabled = true split_inserts = "rewrite"
リシェーディング
PgDog は論理レプリケーションを使ってダウンタイムなしに既存データベースをリシェーディングできます。手順は次の通りです:
- 新しい空クラスターを作成
でスキーマをコピーschema-sync
でデータ転送(並列)data-sync- 同期後、
で二次インデックスを同期schema-sync --data-sync-complete
,MAINTENANCE ON
,RELOAD
でトラフィックを切り替えMAINTENANCE OFF
モニタリング
PgDog は PgBouncer スタイルの管理データベースと OpenMetrics エンドポイントを公開します。プロダクション監視には OpenMetrics を利用し、Datadog ダッシュボードが付属しています。
ローカルで PgDog を実行
- Rust(
)をインストールrustup - リポジトリをクローンして release モードでビルド:
cargo build --release - シャーディング構成例:
# pgdog.toml [[databases]] name = "pgdog_sharded" host = "127.0.0.1" database_name = "shard_0" shard = 0 [[databases]] name = "pgdog_sharded" host = "127.0.0.1" database_name = "shard_1" shard = 1 [[sharded_tables]] database = "pgdog_sharded" column = "user_id" # users.toml [[users]] database = "pgdog_sharded" name = "pgdog" password = "pgdog"
データベースを作成:
CREATE DATABASE shard_0; CREATE DATABASE shard_1; GRANT ALL ON DATABASE shard_0 TO pgdog; GRANT ALL ON DATABASE shard_1 TO pgdog;
PgDog を起動:
cargo run --release
コマンドラインオプション
| Option | Description |
|---|---|
| 設定ファイルへのパス(デフォルト: ) |
| ユーザーリストファイルへのパス(デフォルト: ) |
| 接続 URL (複数可);設定を上書き |
URL を使用した例:
cargo run --release -d postgres://user:pass@localhost:5432/db1 \ -d postgres://user:pass@localhost:5433/db2
psql で接続:
psql postgres://pgdog:pgdog@127.0.0.1:6432/pgdog
ステータス & パフォーマンス
PgDog は本番稼働に耐え、良好にスケールします。ほとんどの機能は安定していますが、一部は実験的です。新しいシャーディング機能は毎週追加されます。
- Rust, Tokio, bytes クレートで書かれ、割り当てを最小化
- 定期的にプロファイリングしてパフォーマンス回帰を検出
ライセンス
PgDog は AGPL v3 の下でライセンスされています。これにより:
- ソース公開不要で修正済みバイナリを社内利用可能
- プロプライエタリソフトウェアは PgDog をコンポーネントとして使用し、ソースコードの開示なしに配布できます
ただし、パブリックサービスとして PgDog を提供する場合、AGPL は修正点を共有することを要求します。
コントリビューション
PR 提出前に Contribution Guidelines をご確認ください。