PostgreSQLを実務環境で長期間安定運用する上で、避けて通れない最大のイベントがメジャーバージョンアップです。PostgreSQLコミュニティの公式サポート期間はメジャーバージョンリリース後5年間と定められており、サポート終了(EOL: End of Life)を迎えたバージョンはセキュリティ脆弱性や深刻なバグの修正パッチが提供されなくなります。
しかし、メジャーバージョンアップは同一系列内のマイナーアップデート(第7回参照)とは根本的に異なり、ディスク上のデータブロック形式や内部カタログ構造に非互換が生じます。そのため、バイナリを置き換えるだけでは古いデータディレクトリを起動できません。
本記事の技術的到達目標
- なぜ古いデータディレクトリを新バージョンで直接読み込めないのか、物理的な非互換理由を理解する。
- テラバイト級データベースでも数秒で移行を完遂できる
pg_upgrade --link(ハードリンク方式)の内部メカニズムとファイルシステム制約を把握する。 - AlmaLinux標準(AppStream)と公式(PGDG)におけるパッケージ共存性と作業難易度の違いを整理する。
- 実機(AlmaLinux 10 / PostgreSQL 17 → 18)での事前互換性チェック(
--check)、チェックサム不一致の対処(pg_checksums)、本番ハードリンク移行、オプティマイザ統計情報の段階的再収集(vacuumdb --analyze-in-stages)、旧クラスタ削除までの一連の手順を習得する。
本記事では、シングルノード構成における停止時間を最小限に抑え、トラブルなく安全にメジャーバージョンアップを完遂するための実務手順を網羅的に解説します。
目次
1. メジャーバージョンアップの本質と互換性の壁
PostgreSQLのバージョンアップ計画を策定する際、最初に理解すべきはマイナーアップデートとメジャーバージョンアップの構造的な違いです。
1.1 マイナー更新とメジャー更新の決定的な相違
第7回で解説した通り、PostgreSQLのバージョニング規則はバージョン10以降、「メジャーバージョン(17、18など)」と「マイナーバージョン(17.11、18.6など)」の2階層になっています。
- マイナーアップデート(例: 18.4 → 18.6):ディスク上のデータブロックレイアウト、内部データ型OID、システムカタログ定義が100%同一に保たれます。データベースを停止し、実行ファイル(バイナリ)を差し替えて再起動するだけで完了します。
- メジャーバージョンアップ(例: 17 → 18):パフォーマンス向上や新機能追加のため、システムカタログのスキーマ定義、行ヘッダの構造、組み込み関数のOID、WALフォーマット、場合によってはデータ型の内部物理レイアウトが変更されます。
1.2 なぜ古いデータディレクトリを直接読み込めないのか
PostgreSQLのサーバープロセス(postgres)は、起動時にデータディレクトリ内の global/pg_control ファイルを読み込み、クラスタのカタログバージョン番号(Catalog Version Number)を照合します。
例えば、PostgreSQL 17のカタログバージョン番号は 202406281、PostgreSQL 18のカタログバージョン番号は 202506291 です。新バージョンのバイナリで旧バージョンのデータディレクトリを直接読み込もうとした場合、サーバーはカタログバージョンの不一致を検知し、データ破損を防ぐために即座にFATALエラーを出力して停止します。
仮にこのチェックを強制的に回避したとしても、新バイナリが期待するシステムカタログの列定義やテーブルOIDと、ディスク上の実データが一致しないため、あらゆるクエリが実行時クラッシュを引き起こします。そのため、メジャーバージョンを跨ぐ際には何らかのデータ変換・移行プロセスが不可欠となります。
1.3 移行方式の比較:pg_dump(論理) vs pg_upgrade(物理・バイナリ)
メジャーバージョンを移行する手段は、大きく分けて以下の2通りが存在します。
| 比較項目 | 論理ダンプ・リストア(pg_dump / pg_restore) | バイナリ直接変換(pg_upgrade) |
|---|---|---|
| 移行方式 | SQL形式またはカスタム形式で全データを論理抽出し、新クラスタへ再投入 | システムカタログのみを抽出し、テーブル実データファイルを新クラスタへ引き継ぐ |
| 所要時間 | データ容量・インデックス量に比例して増大(数百GBで数時間〜半日) | データ量に依存せず極めて高速(後述の--linkで数秒〜数分) |
| 必要ディスク容量 | ダンプファイル領域 + 新旧両クラスタのデータ領域(実データの約2〜3倍) | コピーモード:2倍 ハードリンクモード( --link):ほぼ0% |
| 副次効果 | テーブルの断片化(Bloat)が完全解消、インデックスが再構築される | 旧環境の断片化状態がそのまま新環境に引き継がれる |
| 適用場面 | 数十GB以下の小規模DB、または大幅なスキーマ改変を伴う移行 | 本番運用環境における標準選択肢(夜間メンテナンス枠に収める必須技術) |
深夜の計画停止枠が数時間以内に制限されるエンタープライズ本番環境において、テラバイト級のデータを pg_dump でダンプ・リストアすることは時間的制約から現実的ではありません。そこで登場するのが pg_upgrade です。
2. pg_upgrade の核心:–link オプションの仕組みと制約
pg_upgrade は、PostgreSQL公式コミュニティが提供する高機能バージョンアップツールです。その最大の特長は、テーブルやインデックスの実データファイルを変換せず、メタデータ(システムカタログ)のみを新クラスタの定義に合わせて論理再構築する点にあります。

2.1 コピー方式(デフォルト)とハードリンク方式(–link)の比較
pg_upgrade の実行モードには、大きく分けて「通常コピー方式」と「ハードリンク方式(--link)」の2種類が存在します。
- 通常コピー方式(オプション無指定):旧クラスタのデータディレクトリから新クラスタのデータディレクトリへ、テーブル実データファイルを物理的に1ファイルずつコピーします。移行中も旧クラスタのデータはそのまま残るため安全性は高いですが、データ容量と同等の空きディスク容量が必要となり、大量のディスクI/Oが発生するため時間がかかります。
- ハードリンク方式(
--link指定):ファイルを物理コピーする代わりに、Linuxファイルシステムのハードリンク(Hard Link)を作成します。新旧データディレクトリの双方が、同一のディスクi-node(実データブロック)を指し示す状態を作ります。
2.2 なぜ –link はテラバイト級データでも数秒で移行できるのか
ハードリンク方式の最大の強みは、実データの読み書き(ディスクI/O)が一切発生しない点です。Linuxファイルシステムにおいて、ハードリンクの作成とは「ディレクトリエントリ(ファイル名とi-node番号の対応表)を新設し、該当i-nodeのリンクカウント(参照数)をインクリメントする」だけの処理です。
データサイズが10GBであろうと10TBであろうと、ファイル数が同等であれば処理時間はほとんど変わりません。新旧クラスタのシステムカタログ作成・検証処理を含めても、わずか数秒から数十秒でバージョンアップが完了します。
2.3 –link 採用時の必須制約と注意点
高速な移行処理を実現する --link ですが、採用にあたっては以下の2つの重要な制約と運用リスクを熟知しておく必要があります。
ハードリンク方式採用時の2大制約
- 同一ファイルシステム(同一マウントポイント)の必須:
ハードリンクはUNIXファイルシステムの構造上、同一パーティション(同一ファイルシステム)内でしか作成できません。旧データディレクトリ(例:/var/lib/pgsql/17/data)と新データディレクトリ(例:/var/lib/pgsql/18/data)が異なるディスクや別マウントポイントに分かれている場合、pg_upgrade --linkはエラーとなって失敗します。 - 不可逆性(新クラスタ起動後は旧クラスタへの即時切り戻し不可):
ハードリンクによって同一の実データブロックを共有しているため、新クラスタを一度起動して書き込み処理が行われると、旧クラスタの実データブロックも変更されてしまいます。そのため、新クラスタ起動後に問題が発生した場合、「旧クラスタを再起動して切り戻す」という初歩的なフォールバックは通用しません。万一に備えた事前スナップショットまたは事前完全論理バックアップが必須の命綱となります。
3. パッケージリポジトリ別のメジャー更新難易度:AppStream vs PGDG
第2回で解説したリポジトリ選定は、メジャーバージョンアップの実務難易度を決定づける極めて重大な分岐点となります。
3.1 AppStream版の構造的制約
AlmaLinuxやRHELのOS標準リポジトリ(AppStream)では、PostgreSQLパッケージが postgresql-server という単一の名称で管理されています。メジャーバージョンの切り替えは DNF モジュールストリーム(例: dnf module enable postgresql:16)によって行われます。
この仕組みの致命的な欠点は、単一のOS上に異なるメジャーバージョンのRPMパッケージを同時にインストールできない点です。新旧バージョンのバイナリが共存できないため、AppStream版では pg_upgrade の実行が極めて困難であり、事実上「事前ダンプ → 旧版アンインストール → 新版インストール → リストア」という長時間停止のダンプリストア移行を強いられることになります。
3.2 PGDG版の運用設計上の利点
PostgreSQL公式コミュニティが提供するPGDGリポジトリでは、メジャーバージョンごとにパッケージ名と配置パスが完全に分離されています。
- PostgreSQL 17: バイナリ
/usr/pgsql-17/bin/、データ/var/lib/pgsql/17/data/ - PostgreSQL 18: バイナリ
/usr/pgsql-18/bin/、データ/var/lib/pgsql/18/data/
このように新旧の実行バイナリとライブラリが完全に共存できるため、旧クラスタ(17)を停止した直後に新クラスタ(18)を同一サーバー上に導入し、両方のバイナリパスを指定してシームレスに pg_upgrade --link を実行できます。エンタープライズ環境でPGDGリポジトリが選定される最大の理由の一つが、このメジャー更新の容易性にあります。
4. 実務標準:pg_upgrade 7ステップ完全作業フロー
シングル構成において、事故や想定外の長期ダウンタイムを完全に防ぐための標準作業パイプラインを定義します。

pg_upgrade 7ステップ作業手順
- 互換性事前調査:公式リリースノートを精読し、廃止・削除された組み込み関数、パラメータ名変更、拡張機能(extension)の対応状況を確認します。
- 事前完全バックアップ:グローバルロール情報(
pg_dumpall -g)および全DB論理ダンプ(pg_dump -Fc)を採取し、可能であればVM/ストレージスナップショットを取得します。 - メンテナンス停止と新バイナリ導入:アプリケーション接続を遮断し、旧サービス(
postgresql-17)を停止します。新バージョンのPGDGパッケージ(postgresql18-server)をインストールします。 - 新クラスタの初期化:新バージョンの
initdbを実行します。ロケール、エンコーディング、およびデータチェックサム設定を旧クラスタと完全に一致させます。 - 事前適合性診断(–check):
pg_upgrade --checkを実行し、カタログ互換性、OID整合性、共有ライブラリ存在をドライラン検証します。 - 高速本番移行(–link):
pg_upgrade --linkを実行し、数秒でハードリンク移行を完了させます。 - 新クラスタ起動とオプティマイザ統計再収集:新サービス(
postgresql-18)を起動し、必須運用であるvacuumdb --all --analyze-in-stagesを実行してクエリ実行計画を安定化させます。
5. 【実機検証】AlmaLinux 10での PostgreSQL 17 → 18 バージョンアップ実践
検証環境(alma-db01)を用いて、実際にPostgreSQL 17.11から最新のPostgreSQL 18.6へのメジャーバージョンアップを実機実演します。特に事前チェックで直面した実務トラブルとその解決手順を記録します。
5.1 旧環境(PostgreSQL 17)の初期状態
データベース production_db に口座テーブル accounts と注文テーブル orders を作成し、外部キー制約とインデックスを設定した上でデータを投入しておきます。
$ sudo -u postgres /usr/pgsql-17/bin/psql -c "SELECT version();"
version
-----------------------------------------------------------------------------------------------------------
PostgreSQL 17.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.3.1 20251022 (Red Hat 14.3.1-4), 64-bit
(1 行)
$ sudo -u postgres /usr/pgsql-17/bin/psql -d production_db -c "SELECT * FROM public.accounts;"
account_id | username | email | balance | created_at
------------+-------------+--------------------+-----------+-----------------------------
1 | tokyo_user | user@example.tokyo | 150000.00 | 2026-09-09 21:04:51.7611+09
2 | infra_admin | admin@example.jp | 320000.50 | 2026-09-09 21:04:51.7611+09
3 | developer01 | dev01@example.com | 45000.00 | 2026-09-09 21:04:51.7611+09
(3 行)
5.2 事前バックアップと新バージョンパッケージ導入
作業前の安全措置として論理バックアップを採取し、ファイルシステム構成を確認します。
# 1. 論理バックアップの採取
$ sudo -u postgres /usr/pgsql-17/bin/pg_dumpall -g -f /var/lib/pgsql/globals_pre_upgrade.sql
$ sudo -u postgres /usr/pgsql-17/bin/pg_dump -Fc -v -d production_db -f /var/lib/pgsql/production_db_pre_upgrade.dump
# 2. ファイルシステムの同一性確認(同一マウントポイントであることを確認)
$ df -h /var/lib/pgsql
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/mapper/almalinux-root 64G 3.0G 61G 5% /
# 3. 旧バージョンサービスの停止
$ sudo systemctl stop postgresql-17
# 4. 新バージョンパッケージの導入とクラスタ初期化
$ sudo dnf -y install postgresql18-server postgresql18
$ sudo /usr/pgsql-18/bin/postgresql-18-setup initdb
5.3 事前チェック(–check)とチェックサム不一致の検知・解決
pg_upgrade の最大の利点は、データに変更を加えないドライランモード(--check)が用意されている点です。実際に実行してみます。
$ sudo -u postgres bash -c "cd /var/lib/pgsql && /usr/pgsql-18/bin/pg_upgrade \
--old-datadir=/var/lib/pgsql/17/data \
--new-datadir=/var/lib/pgsql/18/data \
--old-bindir=/usr/pgsql-17/bin \
--new-bindir=/usr/pgsql-18/bin \
--check"
実行した結果、以下のエラーが出力されて停止しました。
整合性チェックを実行しています。
-----------------------------
Checking cluster versions ok
旧クラスタではデータチェックサムを使用していませんが、新クラスタでは使用しています
失敗しました、終了しています
実機トラブル解説:データチェックサムのデフォルト差異
PostgreSQL 18ではデータ破損を自動検出するデータチェックサム(--data-checksums)がデフォルトで有効化されています。一方、PostgreSQL 17以前で構築した環境ではチェックサムが無効になっているケースが多く見られます。
pg_upgrade は新旧クラスタ間でチェックサム設定が一致していない場合、整合性維持のためにアップグレードを拒否します。
解決策:旧クラスタ(17)のチェックサムをオフラインツール pg_checksums を使って有効化します(PostgreSQL 12以降で利用可能)。
旧クラスタに対して pg_checksums を実行し、チェックサムを有効化します。
$ sudo -u postgres /usr/pgsql-17/bin/pg_checksums -e -D /var/lib/pgsql/17/data
チェックサム操作が完了しました
スキャンしたファイル数: 1256
スキャンしたブロック数: 3764
クラスタのチェックサムが有効化されました
チェックサムを有効化した上で、再度 pg_upgrade --check を実行します。
$ sudo -u postgres bash -c "cd /var/lib/pgsql && /usr/pgsql-18/bin/pg_upgrade \
--old-datadir=/var/lib/pgsql/17/data \
--new-datadir=/var/lib/pgsql/18/data \
--old-bindir=/usr/pgsql-17/bin \
--new-bindir=/usr/pgsql-18/bin \
--check"
整合性チェックを実行しています。
-----------------------------
Checking cluster versions ok
Checking database connection settings ok
Checking database user is the install user ok
Checking for prepared transactions ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for valid logical replication slots ok
Checking for subscription state ok
Checking data type usage ok
Checking for objects affected by Unicode update ok
Checking for not-null constraint inconsistencies ok
Checking for presence of required libraries ok
Checking database user is the install user ok
Checking for prepared transactions ok
Checking for new cluster tablespace directories ok
* クラスタは互換性があります *
すべての検証項目がパスし、* クラスタは互換性があります *(* Clusters are compatible *)が出力されました。
5.4 本番ハードリンク移行(–link)の実行
事前チェックに合格したため、--link オプションを指定して本番移行を実行します。所要時間を計測するため time コマンドを併用します。
$ sudo -u postgres bash -c "cd /var/lib/pgsql && time /usr/pgsql-18/bin/pg_upgrade \
--old-datadir=/var/lib/pgsql/17/data \
--new-datadir=/var/lib/pgsql/18/data \
--old-bindir=/usr/pgsql-17/bin \
--new-bindir=/usr/pgsql-18/bin \
--link"
実行ログ(実測結果):
アップグレードを実行しています。
------------------
Setting locale and encoding for new cluster ok
Analyzing all rows in the new cluster ok
Freezing all rows in the new cluster ok
Deleting files from new pg_xact ok
Copying old pg_xact to new server ok
Setting oldest XID for new cluster ok
Setting next transaction ID and epoch for new cluster ok
Deleting files from new pg_multixact/offsets ok
Copying old pg_multixact/offsets to new server ok
Deleting files from new pg_multixact/members ok
Copying old pg_multixact/members to new server ok
Setting next multixact ID and offset for new cluster ok
Resetting WAL archives ok
Setting frozenxid and minmxid counters in new cluster ok
Restoring global objects in the new cluster ok
Restoring database schemas in the new cluster ok
Adding ".old" suffix to old "global/pg_control" ok
旧クラスタを起動する場合、"/var/lib/pgsql/17/data/global/pg_control.old"から
".old"拡張子を削除する必要があります。「リンク」モードが使われて
いるため、一度新クラスタを起動してしまうと旧クラスタは安全に起動
することができなくなります。
Linking user relation files ok
Setting next OID for new cluster ok
Sync data directory to disk ok
Creating script to delete old cluster ok
Checking for extension updates ok
アップグレードが完了しました
----------------
統計情報の一部は pg_upgrade では転送されません。
新しいサーバーを起動した後、次の2つのコマンドの実行を検討してください。
/usr/pgsql-18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
/usr/pgsql-18/bin/vacuumdb --all --analyze-only
このスクリプトを実行すると、旧クラスタのデータファイルが削除されます:
./delete_old_cluster.sh
real 0m2.322s
user 0m0.083s
sys 0m0.221s
実測所要時間はわずか2.322秒でした。数GBから数百GBのデータが存在する場合でも、ハードリンク作成処理は数秒から数十秒で完了します。
5.5 新バージョンサービスの起動とデータ完全性の照合
旧サービス(postgresql-17)を自動起動から解除し、新サービス(postgresql-18)を有効化して起動します。
# 1. サービスの切り替え
$ sudo systemctl disable postgresql-17
$ sudo systemctl enable --now postgresql-18
# 2. バージョン照合
$ sudo -u postgres /usr/pgsql-18/bin/psql -c "SELECT version();"
version
----------------------------------------------------------------------------------------------------------
PostgreSQL 18.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.3.1 20251022 (Red Hat 14.3.1-4), 64-bit
(1 行)
# 3. 既存データの健全性確認
$ sudo -u postgres /usr/pgsql-18/bin/psql -d production_db -c "SELECT * FROM public.accounts;"
account_id | username | email | balance | created_at
------------+-------------+--------------------+-----------+-----------------------------
1 | tokyo_user | user@example.tokyo | 150000.00 | 2026-09-09 21:04:51.7611+09
2 | infra_admin | admin@example.jp | 320000.50 | 2026-09-09 21:04:51.7611+09
3 | developer01 | dev01@example.com | 45000.00 | 2026-09-09 21:04:51.7611+09
(3 行)
5.6 統計情報の段階的再収集と旧クラスタ削除
pg_upgrade 完了直後は、オプティマイザの統計情報が存在しないため、直ちに統計情報を再収集します。データベース全体の統計を一度に収集しようとすると膨大なI/OとCPUを消費し、アプリケーション再開後のクエリ遅延を招く恐れがあります。そのため、PostgreSQL 18では --analyze-in-stages オプションによる3段階の段階的収集が強く推奨されます。
vacuumdb –analyze-in-stages の3段階動作メカニズム
- ステージ1(迅速収集):サンプリング率を極小に抑え、クエリオプティマイザが最悪の実行計画(全表Seq Scanの誤選択など)を回避するために最低限必要な大まかな統計を数秒で即座に生成します。
- ステージ2(標準収集):業務アプリケーションの標準的なクエリ処理に耐えうる実用的な統計精度までサンプリング母数を拡大して更新します。
- ステージ3(高精度収集):デフォルトの
default_statistics_targetに基づく完全な統計情報をバックグラウンドで時間をかけて精緻に収集します。
# 統計情報の段階的生成(最小限サンプリング → 複数サンプリング → 完全生成)
$ sudo -u postgres /usr/pgsql-18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
$ sudo -u postgres /usr/pgsql-18/bin/vacuumdb --all --analyze-only
新環境の安定稼働を確認した後、自動生成された削除スクリプトを実行して旧データディレクトリを整理します。
# 削除スクリプトの内容確認
$ cat /var/lib/pgsql/delete_old_cluster.sh
#!/bin/sh
rm -rf '/var/lib/pgsql/17/data'
# 旧クラスタ領域の削除実行
$ sudo -u postgres bash /var/lib/pgsql/delete_old_cluster.sh
旧データディレクトリを削除しても、ハードリンクによってi-node参照が新クラスタに保持されているため、新環境のデータは一切影響を受けません。
6. 実務チートシート:pg_upgrade 失敗時のトラブルシューティングと回避策
実務の本番移行で遭遇しやすい典型的なエラー原因と回避策をチートシート形式で整理します。
pg_upgrade 典型エラーと対処マトリクス
- エラー①:データチェックサム設定の不一致
現象:旧クラスタではデータチェックサムを使用していませんが、新クラスタでは使用しています
対処法:移行前に旧クラスタを停止し、pg_checksums -e -D <旧データパス>でチェックサムを有効化してから再実行します。 - エラー②:ロケール・エンコーディング・LC_COLLATEの不一致
現象:encodings or collations do not match
対処法:新クラスタ初期化(initdb)時に、旧クラスタのpg_controldataで確認したロケール設定(例:C.UTF-8やja_JP.UTF-8)を明示指定して再初期化します。 - エラー③:拡張モジュール(共有ライブラリ)の未導入
現象:could not load library "...": file not found(例: PostGIS, pgaudit, pg_trgm等)
対処法:旧バージョンで利用していた拡張モジュールの新メジャーバージョン用RPMパッケージ(例:postgresql18-contrib等)を事前にすべてインストールしておきます。 - エラー④:未コミットのプリペアドトランザクションの存在
現象:prepared transactions found in cluster
対処法:旧クラスタを一度起動し、SELECT gid FROM pg_prepared_xacts;で残存トランザクションを確認してROLLBACK PREPAREDまたはCOMMIT PREPAREDで解消します。 - エラー⑤:スキーマやシステムカタログの不整合(pg_upgrade_internal.log)
現象:check failed in check_for_data_types_usageなど、特定のテーブル型やビュー定義で検査が停止
対処法:実行カレントディレクトリに出力されるpg_upgrade_internal.logおよびpg_upgrade_dump_*.logを確認し、問題となっている型(例:複合型内の非互換関数等)を旧クラスタ側で事前に再定義または退避します。
7. 理解度確認演習問題(全3問・解答解説付き)
本記事で解説したメジャーバージョンアップの設計と運用知識を定着させるための確認問題です。
【問1】pg_upgrade の –link オプションに関する記述として、最も適切なものを1つ選択してください。
- 旧クラスタと新クラスタが異なるストレージボリューム(別マウントポイント)にあっても高速移行できる。
- ハードリンクによって実データブロックを共有するため、新クラスタ起動後も旧クラスタを再起動すれば即座に切り戻せる。
- Linuxファイルシステムのハードリンクを利用するため、テラバイト級の大規模データベースでも数秒から数十秒で移行が完了する。
- 移行完了直後に delete_old_cluster.sh を実行すると、新クラスタの実データブロックも一緒に削除されてしまう。
正解と解説を表示
正解:C
解説:ハードリンク方式(--link)は実データの読み書きを行わずディレクトリエントリのみを作成するため、データ量に依存せず極めて高速に処理が完了します(Cが正解)。ハードリンクは同一ファイルシステム内でしか機能しないためAは誤りです。新クラスタ起動後は実データブロックが新エンジンによって更新されるため旧クラスタの単純再起動はできず、Bは誤りです。旧ディレクトリを削除してもリンクカウントが減少するだけで実データブロックは保護されるためDも誤りです。
【問2】pg_upgrade 完了後、新クラスタを起動した直後に最優先で実行すべき運用タスクはどれですか。
- 旧クラスタデータディレクトリの即時削除(rm -rf)
- 全テーブルに対する VACUUM FULL の一括実行
- オプティマイザ統計情報の段階的再収集(vacuumdb –analyze-in-stages)
- pg_checksums による新クラスタチェックサムの無効化
正解と解説を表示
正解:C
解説:pg_upgrade ではシステムカタログのオプティマイザ統計情報は引き継がれません。統計情報が空の状態で業務クエリが流入すると、全表スキャンが多発して深刻な性能遅延を引き起こします。そのため、サービス再開直後に vacuumdb --analyze-in-stages を実行して統計情報を段階的かつ迅速に再生成することが必須です(Cが正解)。
【問3】AlmaLinux標準(AppStream)と比較した際の、PGDG(公式コミュニティ)リポジトリのメジャーバージョンアップにおける利点として正しいものはどれですか。
- 新旧メジャーバージョンのRPMパッケージが異なるディレクトリに共存できるため、同一サーバー上でシームレスに pg_upgrade を実行できる。
- OSの dnf update を一括実行した際に、メジャーバージョンも自動的に最新へ更新される。
- データチェックサムの設定が不一致であっても、自動的に互換性を調整して変換してくれる。
- 論理レプリケーションの機能が標準で無効化されているため、セキュリティが高い。
正解と解説を表示
正解:A
解説:PGDGリポジトリでは /usr/pgsql-17/ や /usr/pgsql-18/ のようにメジャーバージョンごとに配置パスが完全に分離されており、複数バージョンを同一OS上に共存インストールできます。これにより pg_upgrade の新旧バイナリ指定を確実に行えます(Aが正解)。AppStream版では単一のパッケージ名であるため共存ができません。
8. まとめと次回予告
- 非互換の壁:メジャーバージョンアップではカタログ構造や行ヘッダ形式が刷新されるため、古いデータディレクトリを新エンジンで直接起動することはできない。
- –link の処理特性と制約:ハードリンク方式を採用することで、データ量に関わらず移行時間を数秒に短縮できる。ただし「同一ファイルシステムの必須」と「新環境起動後の不可逆性」を理解し、事前バックアップの取得が不可欠。
- 実務ワークフロー:「事前調査 → 事前完全バックアップ → 新版共存インストール →
--check事前診断 →--link本番移行 →vacuumdb --analyze-in-stages統計再収集」の7ステップを順守する。 - リポジトリ選定の重要性:新旧バイナリが完全共存できるPGDGリポジトリの採用が、安全かつ迅速なバージョンアップの前提条件となる。
次回は第9回「【物理レプリケーション実践】ストリーミングレプリケーション構築と遅延監視」を解説します。本シリーズの最終回として、プライマリとスタンバイの2ノード間におけるWAL転送の仕組み、物理レプリケーションスロットの運用、pg_basebackup -Rによるスタンバイ初期化、および遅延監視手法を実機環境で整理します。
PostgreSQL 18 構築・運用ガイド
- 前の記事: 第7回「【無停止への第一歩】PostgreSQLのマイナーバージョンアップ実務:バイナリ更新と安全な切り戻し」
- 現在の記事: 第8回「【ダウンタイム極小化】PostgreSQLのメジャーバージョンアップ手順:pg_upgrade実務攻略」
- 次の記事: 第9回「【物理レプリケーション実践】ストリーミングレプリケーション構築と遅延監視」
- シリーズ企画・目次: シリーズ総合ロードマップとカリキュラム一覧
Kindle書籍版(第9章)のご案内:論理レプリケーションによるニアゼロダウンタイム移行
本ブログ記事で紹介した手法は「数分から十数分の計画停止枠(ダウンタイム)」を許容できるシングル構成を前提としています。しかし、24時間365日の連続稼働が求められる大規模ミッションクリティカル環境では、数分の停止すら許されないケースが少なくありません。商業出版予定のKindle書籍版『現場で困らない PostgreSQL 本番運用大全 —— 4ノード実機で作る高可用性・チューニング・障害復旧』第9章では、ブログ版の内容をさらに発展させ、以下のエンタープライズ実践アーキテクチャを完全収録しています。
- 論理レプリケーション(Logical Replication)を活用した無停止メジャーバージョン移行:旧バージョン(17)と新バージョン(18)の間でテーブル単位のデータ変更をリアルタイム同期させ、アプリの接続先を切り替える「最小停止(秒単位)マイグレーション」。
- シーケンス同期とDDL変更の取り扱い:論理レプリケーションで自動同期されない
SEQUENCE値を安全に引き継ぐ実務スクリプトと検証手順。 - リバースレプリケーションによる確実な切り戻し設計:新環境への切り替え後に致命的な不具合が発生した場合、新環境で発生した差分データを失うことなく旧環境へ即時フェイルバックする高度な冗長化手法。
