PostgreSQLメジャーバージョンアップグレードの手順
PostgreSQL のメジャーバージョンアップグレードは、性能改善や新機能、サポート期限への対応という意味で避けて通れない運用作業です。一方で、14 → 16 のような更新では内部フォーマットや拡張機能の互換性が変わることがあり、単純なパッケージ更新では済みません。
本記事では、業務システムで PostgreSQL を運用しているチーム向けに、事前確認から方式選定、pg_upgrade を使った基本手順、切り戻し判断までを実務目線で整理します。最優先は「最短で上げること」ではなく、「安全に上げて安全に戻せること」です。
事前に確認すべきこと
最初に確認したいのは、技術的に上げられるかではなく、本番運用として成立するかです。
- 対応OS: 新バージョンの PostgreSQL が現在の OS とパッケージ配布元で正式サポートされているか確認します。あわせて
glibcやロケール、サービス管理方式の差分も見ます。 - 拡張機能互換性:
postgis、pg_stat_statements、pgvectorなどの拡張が新バージョンに対応しているか、同じタイミングで更新可能かを確認します。拡張の非互換が最も詰まりやすいポイントです。 - アプリケーション/ドライバ互換性: ORM、JDBC / pg gem / node-postgres などのドライバが対象バージョンに対応しているかを確認します。接続パラメータや SSL 設定の既定値が変わることもあります。
- ディスク容量:
pg_upgrade --linkを使わない場合は旧新クラスタがしばらく共存するため、データサイズの 2 倍近い空きが必要になるケースがあります。ログや WAL も含めて見積もるべきです。 - 停止許容時間: 数分停止で済むのか、長いメンテナンスが取れるのかで方式は変わります。許容停止時間が短い場合、事前同期や段階切り替えの設計が重要です。
アップグレード方式の選び方
pg_upgrade
同一ホスト、あるいは新旧クラスタを扱える環境で短時間に切り替えたい場合の第一候補です。物理ファイルを活用するため高速で、停止時間を比較的短くできます。
メリット
- ダンプ&リストアより速い
- テーブルサイズが大きくても現実的な停止時間に収まりやすい
- 構成が単純で、検証手順を本番に持ち込みやすい
デメリット
- 拡張機能や周辺モジュールの整合性確認が必要
- OS / パッケージ事情の影響を受けやすい
--link利用時は旧クラスタをそのまま切り戻しに使いにくい
論理レプリケーション / ダンプ&リストア
停止時間を極小化したい、あるいはホスト移行や構成変更を同時に行いたい場合に有力です。データ量が小さいならダンプ&リストアでも十分です。
メリット
- 新環境を別ホストに先行構築しやすい
- 切り替え前に新環境で接続確認しやすい
- 旧環境を比較的そのまま温存できる
デメリット
- 手順が複雑になりやすい
- シーケンス、DDL、双方向更新禁止など設計上の注意が増える
- ダンプ&リストアは大容量DBだと時間が読みにくい
「停止時間を短くしたい」だけで複雑な方式を選ぶと、かえって事故率が上がります。まずは pg_upgrade で要件を満たせるかを検討するのが堅実です。
実施前チェックリスト
アップグレード直前の確認では、次の 3 点を必須項目として固定しておくと事故を減らせます。
- バックアップ取得済みであること
- 物理バックアップまたはスナップショット
- 必要なら
pg_dumpall --globals-onlyでロール・権限定義も退避
- リストア検証済みであること
- 「バックアップがある」だけでは不十分で、復元して起動できることまで確認する
- 監視・接続先・ジョブ停止確認済みであること
- バッチ、ETL、ジョブキュー、BI接続、監視エージェントを洗い出す
- アプリケーションの接続先切り替え手順を明文化する
メンテナンス直前は、書き込み系ジョブを止め、必要に応じてアプリケーションを read-only にして更新差分を最小化します。監視についても、アラート無効化ではなく「何を監視継続するか」を決めておくのが重要です。
pg_upgrade を使った基本手順
1. 新旧バージョンを準備する
新旧の PostgreSQL バイナリが同居できる状態を用意し、新クラスタを初期化します。旧クラスタはアップグレード直前まで通常運用し、新クラスタは空のまま保ちます。
# 旧: PostgreSQL 14, 新: PostgreSQL 16 の例
/usr/lib/postgresql/16/bin/initdb -D /var/lib/postgresql/16/data
# 拡張やロケール、設定差分も先に確認する
/usr/lib/postgresql/14/bin/psql -d postgres -c "SELECT name, default_version, installed_version FROM pg_available_extensions ORDER BY name;"2. 事前チェックを実行する
本番停止前に、検証環境で同等手順を流し、当日は --check で最終確認します。
sudo -u postgres /usr/lib/postgresql/16/bin/pg_upgrade \
--old-bindir=/usr/lib/postgresql/14/bin \
--new-bindir=/usr/lib/postgresql/16/bin \
--old-datadir=/var/lib/postgresql/14/data \
--new-datadir=/var/lib/postgresql/16/data \
--checkpg_upgrade --check で失敗したら、その時点で本番作業は止めます。エラーを解消せずに進めると、停止時間だけが伸びます。
3. 本番メンテナンスでアップグレードを実行する
アプリケーション停止、接続断、旧クラスタ停止後にアップグレードを実行します。
# 旧クラスタ停止後に実行
sudo -u postgres /usr/lib/postgresql/16/bin/pg_upgrade \
--old-bindir=/usr/lib/postgresql/14/bin \
--new-bindir=/usr/lib/postgresql/16/bin \
--old-datadir=/var/lib/postgresql/14/data \
--new-datadir=/var/lib/postgresql/16/data \
--jobs=4
# 統計情報の再収集
sudo -u postgres /usr/lib/postgresql/16/bin/vacuumdb --all --analyze-in-stagesアップグレード直後は統計情報が不足し、実行計画が不安定になりやすいため、vacuumdb --all --analyze-in-stages を早めに実施します。テーブル規模が大きい環境では、切り替え後しばらく性能が揺れる前提で監視します。
アプリケーション切り替え時の注意点
コネクションプール
PgBouncer などのプール層が残った古い接続情報を保持していないか確認します。切り替え時は pool 再起動や DNS キャッシュ考慮が必要です。
migration 順序
アプリケーションの DB migration をアップグレード前後どちらで行うべきかを明確にします。DB バージョン差異に依存する変更は、先にアプリを入れ替えるのか、DB を先行させるのかを検証環境で固定します。
feature flag / read-only 運用
切り替え直前に write を止め、参照のみを許可する運用にすると差分管理がしやすくなります。feature flag で書き込み機能を止められるなら、メンテナンス設計がかなり楽になります。
失敗しやすいポイント
- 拡張機能の更新漏れ
postgresql.conf/pg_hba.confの差分取り込み忘れ- バッチや ETL が裏で再接続して書き込み続ける
- 監視だけ復旧して、アプリ本体の接続確認を後回しにする
- ベンチマークを取らず、切り替え後の性能悪化に気づくのが遅れる
本番では「起動した」だけでは不十分です。最低でも 監視正常化、アプリ接続確認、主要SQLの応答時間比較 まで終えて初回完了とみなすべきです。
ロールバック方針
ロールバックは「何分以内なら戻すか」を事前に決めておきます。たとえば、切り替え後 30 分以内に重大な接続障害や性能劣化が見つかった場合は旧クラスタに戻す、のように判断条件を明文化します。
pg_upgrade --link を使う場合、旧データ領域をそのまま安全な切り戻し先として扱いにくくなるため、ロールバック要件が厳しい環境では慎重に判断します。旧クラスタを一定時間保持し、DNS / 接続先切り戻し手順、監視戻し手順、ジョブ再開順まで含めてリハーサルしておくのが理想です。
まとめ
PostgreSQL のメジャーバージョンアップグレードは、コマンド自体よりも事前準備と切り替え設計が成否を決めます。
- まず互換性、停止許容時間、ディスク容量を確認する
- 要件を満たすなら
pg_upgradeを第一候補にする - バックアップだけでなくリストア検証まで行う
- 切り替え後は監視、接続確認、性能比較まで必ず見る
- ロールバック条件を先に決めてから本番に入る
安全なアップグレードは、慎重さと段取りの勝負です。本番で慌てないためにも、検証環境で同じ手順を繰り返し、実施ログをテンプレート化しておくことをおすすめします。