Neon の pooler 接続で search_path が空になりハマった話
新規 Neon DB を pooler 経由でつなぐと search_path が空になることがあった。直接接続に寄せた理由。
個人開発の DB を Neon に移したとき、接続文字列を「pooler あり」にしただけでアプリが壊れました。症状はシンプルで、テーブルがあるのに見つからない/スキーマがおかしいように見えることです。
同じ罠を、Contact Hub や Angla Admin、血圧系など複数の DB で踏む(または踏む寸前で避ける)ことになりました。
何が起きたか
Neon にはだいたい次の2系統の接続があります。
- 直接接続(
pooled=false寄り) - pooler 接続(ホスト名に
-poolerが付くタイプ)
新規に作ったデータベースで pooler 経由につなぐと、環境によっては search_path が空になります。Postgres は search_path を見て「どのスキーマをデフォルトで見るか」を決めるので、ここが空だと public のテーブルに素直に届きません。
厄介なのは、ALTER DATABASE ... SET search_path TO public; を pooler 経由で実行しても、期待どおりに効かないケースがあったことです。キャッシュや経路の違いで、直したつもりが直っていない、という状態になります。
どう回避しているか
いまの実務ルールは短くて、次の1行です。
個人向けの低トラフィックな内部ツール/API は、Neon の非 pooler(直接接続)を使う
接続数が爆発するサービスではないので、pooler の恩恵より、search_path の再現性の方が大事でした。
移行時のチェックも簡単にしています。
- アプリのヘルスチェック(DB 読み書き)
- 代表テーブルの件数確認
- 問題なければ古い接続情報はバックアップとして残す(すぐ消さない)
なぜブログに書くか
ドキュメントを読めば分かる話、に見えます。でも実際は、
- 「移行した直後だけおかしい」
- 「pooler の方が正しそう」に見える
- 複数プロジェクトで同じ症状が出る
という組み合わせで、時間が溶けます。自分のメモとしても、横断で残しておく価値がありました。
まとめ
- Neon 新規 DB + pooler で
search_pathが空になることがある - 症状は「テーブルがない」ように見える
- 個人開発の小さいサービスなら、まず直接接続でよい
- 同じ罠をプロジェクト横断で疑う
1台の VPS にサービスを並べる話や、Angla 側の運用は別記事にしています。
Angla を公開するまで / GHA から VPS cron へ