1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PostgreSQL 17から18へのバージョンアップ手順 ─ Amazon Linux 2023標準で試してみた

1
Posted at

1. はじめに

本記事は、PostgreSQL 16から17へのバージョンアップと同じ構成で、PostgreSQL 17から18へのバージョンアップ手順を確認します。

標準リポジトリの制約(データディレクトリ・サービス名の共有)はPostgreSQL17からPostgreSQL18でも変わらないため、今回も dump/restore方式 をメインに進めます。

ただし、PostgreSQL17からPostgreSQL18にはPostgreSQL16からPostgreSQL17にはなかった注意点が2つあります。

  • initdb のデータチェックサムが デフォルトで有効 になった(PostgreSQL17以前は無効がデフォルト)
  • pg_upgradeで プランナ統計情報が引き継がれる ようになった

チェックサムの変更はpg_upgradeを使う場合にハマるポイントです。dump/restore方式でも理解しておく価値があるため、本記事で触れます。

1.1 この記事でできるようになること

  • 標準リポジトリ環境でのPostgreSQL17からPostgreSQL18へのバージョンアップ手順を理解する
  • アップグレード後に必要な作業(ANALYZE・拡張の確認)を理解する
  • チェックサムのデフォルト変更がpg_upgradeに与える影響と対処法を理解する
  • 統計情報の引き継ぎ(PostgreSQL18の新機能)で何が変わるかを理解する

1.2 検証環境

項目 内容
OS Amazon Linux 2023
移行元 PostgreSQL17(標準リポジトリ postgresql17-server
移行先 PostgreSQL18(標準リポジトリ postgresql18-server
インスタンスタイプ t3.micro(2 vCPU、1GiB メモリ)EBS 30GB
データディレクトリ /var/lib/pgsql/data
サービス名 postgresql

2. PostgreSQL17からPostgreSQL18で新たに注意すること

2.1 チェックサムのデフォルトが変わった

PostgreSQL18から、initdb 実行時にデータチェックサムが デフォルトで有効 になりました。

pg_upgradeで移行する際は新旧クラスタのチェックサム設定を一致させる必要があります。PostgreSQL17環境はチェックサムが無効(旧デフォルト)のため、そのままpg_upgradeを実行するとエラーになります。下記例では、PostgreSQL17とPostgreSQL18のそれぞれの環境で、データベースクラスタをtmpフォルダ配下にデフォルトで作成して、pg_upgradeのcheckを実行しています。

# PostgreSQL17のデータベースクラスタ 初期化
$sudo -u postgres /usr/pgsql-17/bin/initdb -D /tmp/pg17_dummy
PostgreSQL17 initdbの結果
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "C.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /tmp/pg17_dummy ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /usr/pgsql-17/bin/pg_ctl -D /tmp/pg17_dummy -l logfile start
# PostgreSQL18のデータベースクラスタ 初期化
$sudo -u postgres /usr/pgsql-18/bin/initdb -D /tmp/pg18_dummy
PostgreSQL18 initdbの結果
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "C.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are enabled.

creating directory /tmp/pg18_dummy ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /usr/pgsql-18/bin/pg_ctl -D /tmp/pg18_dummy -l logfile start

pg_upgradeで移行可能かをチェックする(--check オプション)。
下記は、NGの結果です。(not use data checksums )

$sudo -u postgres /usr/pgsql-18/bin/pg_upgrade \
  -b /usr/pgsql-17/bin \
  -B /usr/pgsql-18/bin \
  -d /tmp/pg17_dummy \
  -D /tmp/pg18_dummy \
  --check
Performing Consistency Checks
-----------------------------
Checking cluster versions                                     ok

old cluster does not use data checksums but the new one does
Failure, exiting

対処法は2つです。

対処法 コマンド 備考
A. 新クラスタのチェックサムを無効にする initdb --no-data-checksums PostgreSQL17と同じ設定に揃える
B. 旧クラスタにチェックサムを有効化する pg_checksums --enable PostgreSQLを停止した状態で実行。大規模DBは時間がかかる

警告
本記事のdump/restore方式はこの問題を回避できます。pg_upgradeを使う場合の補足は末尾に記載します。

2.2 統計情報が引き継がれるようになった

PostgreSQL17以前のpg_upgradeはアップグレード後にプランナ統計情報が失われ、ANALYZE が完了するまでクエリ性能が不安定になる場合がありました。

PostgreSQL18からはpg_upgradeで統計情報が引き継がれます。 アップグレード直後から安定した実行計画が期待できます。

dump/restore方式ではデータを再投入するため、ANALYZEは引き続き必要です。統計情報の引き継ぎはpg_upgrade方式でとくに恩恵が大きい改善です。

3. 事前準備(両方式 共通)

3.1 現状の確認

# PostgreSQL17が動いていることを確認
$sudo systemctl status postgresql

# バージョン確認
$sudo -u postgres psql -c "SELECT version();"

導入済み拡張の棚卸し(重要)

$sudo -u postgres psql -d pgbench_test -Atc  "SELECT extname, extversion FROM pg_extension ORDER BY extname;"

contribパッケージに含まれない拡張(pg_repack 等)は、PostgreSQL18向けの版を別途用意しておかないとリストア時に失敗します。注意点

3.2 バックアップ(必須)

# ルート上にバックアップ用ディレクトリを用意
$sudo mkdir -p /var/backups/pg
$sudo chown postgres:postgres /var/backups/pg

# 圧縮しながらダンプ
$sudo -u postgres bash -c "pg_dumpall | gzip > /var/backups/pg/dump_all_$(date +%Y%m%d).sql.gz"

# 取得できたか確認
$ls -lh /var/backups/pg/

3.3 設定ファイルの退避

$sudo cp /var/lib/pgsql/data/postgresql.conf /var/backups/pg/postgresql.conf.17.bak
$sudo cp /var/lib/pgsql/data/pg_hba.conf     /var/backups/pg/pg_hba.conf.17.bak

4. dump / restore 方式でのバージョンアップ

4.1 PostgreSQL 17の停止

$sudo systemctl stop postgresql
$sudo systemctl status postgresql   # stopped を確認

4.2 旧データの退避(保険)

$sudo tar czf /var/backups/pg/pgsql_data_17_backup.tar.gz -C /var/lib/pgsql data
$ls -lh /var/backups/pg/pgsql_data_17_backup.tar.gz

4.3 17の削除と18の導入

PostgreSQL17系のパッケージを削除します。postgresql17-private-libspostgresql17-private-devel が残っているとPostgreSQL18のインストール時に競合エラーになるため、まとめて削除します。

# 17系パッケージをすべて削除(データディレクトリは残る)
$sudo dnf remove -y postgresql17-server postgresql17-contrib postgresql17 postgresql17-private-libs postgresql17-private-devel

# 削除されたか確認(何も出なければOK)
$rpm -qa | grep postgresql17

postgresql17-private-libs が残ったままだと、次のインストール時に conflicts with postgresql-private-libs-any というエラーで失敗します。rpm -qa | grep postgresql17 で17系が残っていないことを必ず確認してください。

# 旧データディレクトリを退避してクリア
$sudo mv /var/lib/pgsql/data /var/lib/pgsql/data_17_old

# PostgreSQL18をインストール
$sudo dnf install -y postgresql18-server postgresql18-contrib

4.4 PostgreSQL18のデータベースクラスタを初期化

$sudo postgresql-setup --initdb

$sudo systemctl start postgresql
$sudo systemctl enable postgresql

# 18として上がっているか確認
$sudo -u postgres psql -c "SELECT version();"

4.5 リストア

$sudo -u postgres bash -c "gunzip -c /var/backups/pg/dump_all_*.sql.gz | psql"
# データベース一覧で pgbench_test があるか確認
$sudo -u postgres psql -c "\l"

# pgbench_test のテーブルが戻っているか確認
$sudo -u postgres psql -d pgbench_test -c "\dt"

4.6 設定の移し替え

3.3で控えた17の設定値を見ながら、18の postgresql.conf に手で移します。ファイルを丸ごと上書きしないこと(バージョン間でパラメータの意味が変わっている場合があるため)。

# 17と18の設定差分を確認
$sudo diff /var/backups/pg/postgresql.conf.17.bak /var/lib/pgsql/data/postgresql.conf | less

$sudo vi /var/lib/pgsql/data/postgresql.conf

$sudo systemctl restart postgresql
$sudo systemctl status postgresql
パラメータ デフォルト値 記事で使用した値 カテゴリ 出典記事
shared_buffers 128MB 512MB / 8MB メモリ #3 postgresql.conf / #4 チェックポインタ
work_mem 4MB 64MB / 128MB メモリ #3 postgresql.conf
max_connections 100 400 接続 #3 postgresql.conf
checkpoint_timeout 5min 30s(劣化用)/ 15min(改善用) チェックポイント #4 チェックポインタ
checkpoint_completion_target 0.9 0.001(劣化用)/ 0.9(改善用) チェックポイント #4 チェックポインタ
max_wal_size 1GB 126MB(劣化用)/ 4GB(改善用) WAL #4 チェックポインタ
bgwriter_delay 200ms 10s(劣化用)/ 100ms(改善用) bgwriter #4 チェックポインタ
bgwriter_lru_maxpages 100 0(劣化用)/ 300(改善用) bgwriter #4 チェックポインタ
bgwriter_lru_multiplier 2.0 2(参考掲載) bgwriter #4 チェックポインタ
log_checkpoints off on ログ #4 チェックポインタ
shared_preload_libraries (空) 'pg_stat_statements' 拡張機能 #6 pg_stat_statements

5. アップグレード後の作業

5.1 ANALYZEを実行する

sudo -u postgres psql -c "ANALYZE VERBOSE;"

pg_upgrade方式では統計情報が引き継がれるため(PostgreSQL18の新機能)、この手順を省略できるケースがあります。dump/restore方式では引き続き実行してください。

5.2 拡張機能の確認

$sudo -u postgres psql -d pgbench_test -c "SELECT * FROM pg_extension;"

# pg_stat_statementsを使っていた場合
$sudo -u postgres psql -d pgbench_test -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"

5.3 pgbenchで動作確認

sudo -u postgres pgbench -c 2 -T 10 pgbench_test
pgbench_testの結果
pgbench (18.3)
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 50
query mode: simple
number of clients: 2
number of threads: 1
maximum number of tries: 1
duration: 10 s
number of transactions actually processed: 6987
number of failed transactions: 0 (0.000%)
latency average = 2.861 ms
initial connection time = 6.664 ms
tps = 699.027285 (without initial connection time)

アップグレード後も正常にpgbenchが動作していることを確認できました。性能面の比較に関しては、別記事で記載予定です。

6. (補足)PGDG(PostgreSQL Global Development Group)リポジトリで実施する場合

標準リポジトリはバージョン分離構成が作れないためpg_upgradeは難しいですが、PGDGリポジトリを最初から使っていればバイナリ・データ・サービスがバージョンごとに分離され、pg_upgradeを素直に使えます。ここではPGDGリポジトリでのPostgreSQL17インストールから18へのバージョンアップまでの一連の流れを示します。

Amazon Linuxには /etc/redhat-release というファイルが存在しない(または記述が異なる)ため、PGDGのRed Hat向けリポジトリパッケージ(pgdg-redhat-repo)が依存関係エラー(Failed dependencies)でインストールできませんでした。そのため、Red Hat Enterprise Linux環境を新しく作成して、試しています。

6.1 PostgreSQL 17のインストール(初期構築)

# ACLを管理する acl パッケージをインストール
$sudo dnf install -y acl

# 作業用のpg_shared ディレクトリを作成
$mkdir /home/ec2-user/pg_shared

# ec2-user ディレクトリの「通過権限(x)」を postgres に付与
$sudo setfacl -m u:postgres:x /home/ec2-user

# 作成したフォルダの「読み書き実行権限(rwx)」を postgres に付与
$sudo setfacl -m u:postgres:rwx /home/ec2-user/pg_shared

# 今後このフォルダ内に作られるファイルにも、自動で postgres の権限が引き継がれるようにする(デフォルト設定)
$sudo setfacl -d -m u:postgres:rwx /home/ec2-user/pg_shared

# 移動
$cd pg_shared
# PGDGリポジトリを追加
$ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm
Updating Subscription Management repositories.
Unable to read consumer identity
(省略)
Installed:
  pgdg-redhat-repo-42.0-64.rhel10PGDG.noarch

Complete!

# 標準リポジトリのPostgreSQLモジュールを無効化(競合防止)
$sudo dnf module disable -y postgresql
Updating Subscription Management repositories.
Unable to read consumer identity

 (省略)
PostgreSQL common RPMs for RHEL / Rocky Linux / AlmaLinux 10 - x86_64                    17 kB/s | 659  B     00:00
PostgreSQL common RPMs for RHEL / Rocky Linux / AlmaLinux 10 - x86_64                   2.4 MB/s | 2.4 kB     00:00
Importing GPG key 0xAAAAAAAA:
 Userid     : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
 Fingerprint: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX 
 From       : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
 (省略)
 Updating Subscription Management repositories.
Unable to read consumer identity

# PostgreSQL 17をインストール
$sudo dnf install -y postgresql17-server postgresql17-contrib
Updating Subscription Management repositories.
Unable to read consumer identity
 (省略)
Installed:
  libicu-74.2-5.el10_0.x86_64                               libxslt-1.1.39-8.el10_0.x86_64
  postgresql17-17.10-2PGDG.rhel10.2.x86_64                  postgresql17-contrib-17.10-2PGDG.rhel10.2.x86_64
  postgresql17-libs-17.10-2PGDG.rhel10.2.x86_64             postgresql17-server-17.10-2PGDG.rhel10.2.x86_64

Complete!

# 初期化・起動
$sudo /usr/pgsql-17/bin/postgresql-17-setup initdb
Initializing database ... OK

$sudo systemctl enable --now postgresql-17
Created symlink '/etc/systemd/system/multi-user.target.wants/postgresql-17.service''/usr/lib/systemd/system/postgresql-17.service'.

# バージョン確認
$sudo -u postgres psql -c "SELECT version();"
                                                  version
-----------------------------------------------------------------------------------------------------------
 PostgreSQL 17.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.3.1 20251022 (Red Hat 14.3.1-4), 64-bit
(1 row)

# PostgreSQLサービスを起動する
$sudo systemctl restart postgresql-17

# 無事に起動しているかステータスを確認する
$sudo systemctl status postgresql-17

# 試しにpgbench_testを実行しておく
$sudo -u postgres /usr/pgsql-17/bin/createdb pgbench_test
$sudo -u postgres /usr/pgsql-17/bin/pgbench -i -s 1 pgbench_test
dropping old tables...
NOTICE:  table "pgbench_accounts" does not exist, skipping
NOTICE:  table "pgbench_branches" does not exist, skipping
NOTICE:  table "pgbench_history" does not exist, skipping
NOTICE:  table "pgbench_tellers" does not exist, skipping
creating tables...
generating data (client-side)...
vacuuming...
creating primary keys...
done in 0.20 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 0.11 s, vacuum 0.04 s, primary keys 0.04 s).

PGDGリポジトリでは以下のようにバージョンごとに分離されます。

バイナリ:  /usr/pgsql-17/bin/
データ:    /var/lib/pgsql/17/data/
サービス:  postgresql-17.service

6.2 バックアップ(必須)

標準リポジトリ版と同様に、アップグレード前に必ずバックアップを取得します。

$sudo mkdir -p /var/backups/pg
$sudo chown postgres:postgres /var/backups/pg

$sudo -u postgres bash -c "pg_dumpall | gzip > /var/backups/pg/dump_all_$(date +%Y%m%d).sql.gz"
$ls -lh /var/backups/pg/

6.3 PostgreSQL18のインストール

PostgreSQL17を動かしたまま、PostgreSQL18を追加インストールします。

$sudo dnf install -y postgresql18-server postgresql18-contrib
Updating Subscription Management repositories.
Unable to read consumer identity
(省略)
Installed:
  liburing-2.12-1.el10.x86_64                                  postgresql18-18.4-2PGDG.rhel10.2.x86_64
  postgresql18-contrib-18.4-2PGDG.rhel10.2.x86_64              postgresql18-libs-18.4-2PGDG.rhel10.2.x86_64
  postgresql18-server-18.4-2PGDG.rhel10.2.x86_64

Complete!

バイナリが分離されるため、17は停止せずに18を導入できます。

バイナリ:  /usr/pgsql-17/bin/  ← そのまま残る
           /usr/pgsql-18/bin/  ← 追加される

6.4 新クラスタの初期化

チェックサムの設定を旧クラスタ(PostgreSQL17)に揃えます。PostgreSQL17はデフォルトでチェックサムが無効のため、--no-data-checksums を指定します。こちらは、PostgreSQL18のpg_upgrade時の一時的な対応です。あとから、チェックサムを有効化します(有効化には長時間かかる可能性がある)。

$sudo -u postgres /usr/pgsql-18/bin/initdb --no-data-checksums -D /var/lib/pgsql/18/data
# データベース初期化時にエラーが出た
$ sudo -u postgres /usr/pgsql-18/bin/initdb --no-data-checksums -D /var/lib/pgsql/18/data
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "C.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

initdb: error: directory "/var/lib/pgsql/18/data" exists but is not empty
initdb: hint: If you want to create a new database system, either remove or empty the directory "/var/lib/pgsql/18/data" or run initdb with an argument other than "/var/lib/pgsql/18/data".

# 既存のディレクトリを削除 & 作成 & 確認
# 【重要】退避が必要な場合には、必ず退避してから削除を実施してください。
# sudo -u postgres rm -rf /var/lib/pgsql/18/data
# sudo -u postgres mkdir /var/lib/pgsql/18/data
# sudo chmod 700 /var/lib/pgsql/18/data

6.5 PostgreSQL 17の停止

$sudo systemctl stop postgresql-17
$sudo systemctl status postgresql-17   # inactive (dead) を確認

6.6 pg_upgradeの事前チェック

--check オプションを使うと、実際のデータ移行をせずに「この構成でpg_upgradeが通るか」を事前検証できます。本番前に必ず通しておきます。

$sudo -u postgres /usr/pgsql-18/bin/pg_upgrade \
  -b /usr/pgsql-17/bin \
  -B /usr/pgsql-18/bin \
  -d /var/lib/pgsql/17/data \
  -D /var/lib/pgsql/18/data \
  --check

Performing Consistency Checks
-----------------------------
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*

Clusters are compatible と表示されれば本番実行に進めます。

6.7 pg_upgradeの実行

$sudo -u postgres /usr/pgsql-18/bin/pg_upgrade \
  -b /usr/pgsql-17/bin \
  -B /usr/pgsql-18/bin \
  -d /var/lib/pgsql/17/data \
  -D /var/lib/pgsql/18/data \
  --jobs 2 \
  --swap
PostgreSQL18 pg_upgradeの結果
-----------------------------
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
Creating dump of global objects                               ok
Creating dump of database schemas
                                                              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

If pg_upgrade fails after this point, you must re-initdb the
new cluster before continuing.

Performing Upgrade
------------------
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

Because "swap" mode was used, the old cluster can no longer be
safely started.
Swapping data directories
                                                              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

Upgrade Complete
----------------
Some statistics are not transferred by pg_upgrade.
Once you start the new server, consider running these two commands:
    /usr/pgsql-18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
    /usr/pgsql-18/bin/vacuumdb --all --analyze-only
Running this script will delete the old cluster's data files:
    ./delete_old_cluster.sh
オプション 内容
--jobs 2 チェック処理を並列実行(18の新機能)
--swap ディレクトリ入れ替え方式で移行を高速化(18の新機能)

6.8 PostgreSQL18の起動と確認

$sudo systemctl enable --now postgresql-18
Created symlink '/etc/systemd/system/multi-user.target.wants/postgresql-18.service''/usr/lib/systemd/system/postgresql-18.service'.

# バージョン確認
$ sudo -u postgres psql -p 5432 -c "SELECT version();"

                                                 version
----------------------------------------------------------------------------------------------------------
 PostgreSQL 18.4 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.3.1 20251022 (Red Hat 14.3.1-4), 64-bit
(1 row)

# データベース一覧
sudo -u postgres psql -c "\l"
                                                   List of databases
     Name     |  Owner   | Encoding | Locale Provider | Collate |  Ctype  | Locale | ICU Rules |   Access privileges
---------------------------------------------------------------------------------------------------------------
 pgbench_test | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |        |           |
 postgres     | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |        |           |
 template0    | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |        |           | =c/postgres          +
              |          |          |                 |         |         |        |           | postgres=CTc/postgres
 template1    | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |        |           | postgres=CTc/postgres+
              |          |          |                 |         |         |        |           | =c/postgres
(4 rows)

pg_upgrade方式では統計情報が引き継がれるため(18の新機能)、ANALYZEを急いで実施する必要はありません。アップグレード直後から安定した実行計画で動作します。

6.9 チェックサムを有効化

PostgreSQL18のデータベースクラスタのチェックサムを無効化した状態で作成したため、チェックサムを後から有効化します。

処理時間: すべてのデータブロックにチェックサムの計算値を書き込むため、データ量(テーブルサイズやインデックスサイズ)に比例して時間がかかります。実行中は進行状況(パーセンテージ)が表示されます。

# サービスを停止
$sudo systemctl stop postgresql-18

# チェックサムを有効化
$sudo -u postgres /usr/pgsql-18/bin/pg_checksums \
  -D /var/lib/pgsql/18/data \
  --enable
Checksum operation completed
Files scanned:   1261
Blocks scanned:  99566
Files written:  1039
Blocks written: 99546
pg_checksums: syncing data directory
pg_checksums: updating control file
Checksums enabled in cluster

# サービスを再度起動
$sudo systemctl start postgresql-18
$sudo -u postgres psql -p 5432 -c "SHOW data_checksums;"
 data_checksums
----------------
 on
(1 row)

6.10 旧クラスタの削除(任意)

動作確認が取れたら旧クラスタを削除します。

# pg_upgradeが生成するスクリプトで旧クラスタを削除
./delete_old_cluster.sh

7. PostgreSQL17から18へのバージョンアップまとめ

変更点 内容 対応
チェックサムのデフォルト変更 initdbがデフォルトで有効に pg_upgrade時は --no-data-checksums を指定するか旧側を有効化
統計情報の引き継ぎ pg_upgradeで統計情報が保持される pg_upgrade方式ではANALYZE不要に
--jobs オプション チェック処理を並列実行 大規模DB・オブジェクト数が多い環境に有効
--swap オプション ディレクトリ入れ替えで高速化 大規模DBのダウンタイム短縮に有効

dump/restore方式は変わらず確実な手段です。一方で、PostgreSQL18からpg_upgradeが「アップグレード直後から性能が安定する」方式になったことで、本番でpg_upgradeを選ぶ理由がひとつ増えました

8. もっと深く学びたい方へ

ページ URL
pg_upgrade https://www.postgresql.jp/docs/18/pgupgrade.html
pg_checksums https://www.postgresql.jp/docs/18/app-pgchecksums.html
initdb https://www.postgresql.jp/docs/18/app-initdb.html
PostgreSQL 18 リリースノート https://www.postgresql.jp/document/18/html/release-18.html
書籍名称 内容
[改訂3版]内部構造から学ぶPostgreSQL―設計・運用計画の鉄則 使った事がある人向けの設計・運用の鉄則。大変お世話になりました。
PostgreSQL実践入門 ─⁠─アーキテクチャ、運用監視、性能改善 こちらも基本からチューニングまで幅広い内容。特に監視面のところが充実してそう。

9. おわりに

PostgreSQL17からPostgreSQL18へのバージョンアップで一番ハマりやすいのは、チェックサムのデフォルト変更です。pg_upgradeを使う場合は事前に確認しておくと安心です。

一方で、統計情報の引き継ぎによりアップグレード後の性能面のリスクが軽減されました。「アップグレード直後はクエリが遅い」という経験をされた方には、pg_upgrade方式を選択しやすくなりました。

これらの情報を活かして、実環境へ適用する前に検証環境で確認しておきましょう。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?