「あっちのサーバーのデータ、こっちから見れたら楽なのにな」を叶える:postgres_fdwの実践入門
「本番環境のログサーバーにあるデータと、分析用DBのデータをJOINしたい…」
「マイクロサービス化してDBが分かれたけど、クロス集計が面倒すぎる…」
エンジニアなら一度は頭を抱えたことがあるはずです。データを物理的に転送したり、アプリケーション側で無理やりマージしたり……。そんな非効率なやり方、今日で卒業しましょう。
PostgreSQLには`postgres_fdw`という、まさに「魔法」のような標準拡張機能があります。今回は、現場で役立つこいつの基本と、ちょっとしたコツを解説します。
—
postgres_fdw とは何か?
一言で言えば、「別のPostgreSQLサーバーのテーブルを、まるで自分のローカルDBにあるかのように扱える」仕組みです。
仕組みとしては、SQLを投げると、それをFDW(Foreign Data Wrapper)が解釈して、接続先のサーバーに「おーい、このSQL実行して結果をこっちに送ってくれ」と翻訳してくれます。開発者は、リモートにデータがあることをほとんど意識せずにSQLを書けるわけです。
実際に設定してみよう
理屈よりコードですよね。流れは大きく分けて4ステップです。
1. 拡張機能の有効化
まずは、ローカルのDBで拡張を読み込みます。
CREATE EXTENSION postgres_fdw;
2. 外部サーバーの定義
「どこのサーバーに繋ぐか」を教えます。
CREATE SERVER remote_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host ‘192.168.1.10’, dbname ‘analytics_db’, port ‘5432’);
3. ユーザーマッピング
「どのユーザー権限でアクセスするか」を定義します。本番環境でこれをやるときは、リモート側に専用の読み取り専用ユーザーを作っておくのがセオリーですよ。
CREATE USER MAPPING FOR current_user
SERVER remote_server
OPTIONS (user ‘fdw_user’, password ‘secure_password’);
4. 外部テーブルの定義
最後に、リモートのテーブル構造をローカル側に「写し鏡」として作ります。
IMPORT FOREIGN SCHEMA public
LIMIT TO (users)
FROM SERVER remote_server
INTO public;
これだけで、`SELECT FROM users;` と叩けば、リモートのデータが手元に降ってきます。感動的でしょ?
—
実務で「ハマる前」に知っておいてほしいこと
ここからが先輩の経験則です。`postgres_fdw`は便利ですが、使い方を間違えるとシステム全体を巻き込む「爆弾」にもなり得ます。
1. 「全部持ってきてからフィルタ」は厳禁
`SELECT FROM remote_table WHERE id = 100;` と書けば、PostgreSQLは賢いのでちゃんとリモート側に `WHERE` 句をプッシュダウン(転送)してくれます。
しかし、複雑な関数をWHERE句に入れたり、集計関数を絡めたりすると、「リモートの全データをローカルに転送してからローカルでフィルタリング」という悲劇が起こります。ネットワーク帯域が死にます。`EXPLAIN` を叩いて、リモート側に条件が渡っているか確認する癖をつけましょう。
2. 通信断は「障害」になる
`postgres_fdw` を使ったクエリを実行中にリモート側のネットワークが瞬断すると、そのままクエリがタイムアウトして失敗します。トランザクションを張っている場合、ローカル側の処理も道連れになる可能性があることは忘れないでください。
3. 統計情報の更新を忘れずに
リモートのテーブルには、ローカルの `ANALYZE` が効きません。リモートのデータが激しく更新される場合、ローカルのオプティマイザが古い統計情報を元に「全件スキャン」という間違ったプランを立てることがあります。定期的にリモート側で `ANALYZE` をかけるか、外部テーブルに対して手動で統計情報を更新するメンテナンスが必要です。
—
まとめ:いつ使うべきか?
`postgres_fdw` は強力ですが、「何でもかんでもこれに頼る」のはお勧めしません。頻繁にJOINが発生するなら、素直にデータベースを統合するか、ETLツールでデータを同期すべきです。
逆に、「たまに参照するマスタデータ」「分散したログのスポット的な突き合わせ」には最強のツールになります。
「とりあえず手元で見たい」というニーズを、安全かつスマートに解決できるのが `postgres_fdw`。ぜひ、テスト環境で遊んでみてください。ネットワーク越しにクエリが通ったときの快感は、エンジニア冥利に尽きますよ!
それでは、また次回の記事で。ハッピーなDBライフを!
コメント