Chuyển đến nội dung chính

PostgreSQL 17.6 から 18.1 (実稼働標準) へのアップグレード手順

Duy Tran15分
PostgreSQL 17.6 から 18.1 (実稼働標準) へのアップグレード手順

PostgreSQL 18 は 2025 年 9 月 25 日に正式にリリースされ、PostgreSQL の歴史の中で最も重要なリリースの 1 つとなりました。紹介付き 非同期 I/O サブシステム、ストレージからの読み取りパフォーマンスが向上しました。 3回などの多くの新機能とともに、 UUIDv7、 仮想生成列、そして OAuth 2.0認証。

この記事では、運用標準に従って PostgreSQL 17.6 から 18.1 にアップグレードする方法について詳しく説明します。 最小限のダウンタイム そして 安全なロールバック。


1. PostgreSQL 18 にアップグレードする必要があるのはなぜですか?

1.1.優れた機能

特長 説明 利点
非同期I/O 新しい非同期 I/O システム シーケンシャルスキャン、ビットマップヒープスキャンを最大 3 倍高速化
統計の保存 アップグレード時にプランナーの統計を保持する アップグレード後に ANALYZE を実行する必要はありません
スキップスキャン 複数列 B ツリー インデックスのルックアップ 条件を省略するとクエリが高速化されます = プレフィックス列について
UUIDv7 ネイティブ uuidv7() 機能 UUID にはタイムスタンプがあり、インデックス作成に適しています
仮想生成列 クエリ時の計算列 スキーマ設計の柔軟性の向上
OAuth 2.0 ID プロバイダーによる認証 簡単な SSO 統合
pg_upgrade --swap 新しいスワップモード アップグレードが速くなり、ファイルをコピーする必要がなくなります

1.2.注意すべき重大な変更点

⚠️ QUAN TRỌNG - Các thay đổi không tương thích ngược:
  1. Data Checksums mặc định BẬT (initdb)

    • Cần matching checksum settings khi pg_upgrade
  2. MD5 authentication DEPRECATED

    • Nên migrate sang SCRAM-SHA-256
  3. Time zone abbreviation handling thay đổi

    • Session timezone được ưu tiên trước timezone_abbreviations

2. アップグレード前の準備

2.1.アップグレード前のチェックリスト

#!/bin/bash



pre-upgrade-checklist.sh

echo "=== PostgreSQL Upgrade Checklist ==="

1. Kiểm tra version hiện tại

echo "1. Current PostgreSQL Version:" psql -c "SELECT version();"

2. Kiểm tra disk space

echo "2. Disk Space (cần ít nhất 2x data directory size):" df -h /var/lib/postgresql

3. Kiểm tra data directory size

echo "3. Data Directory Size:" du -sh /var/lib/postgresql/17/main

4. Kiểm tra checksum status

echo "4. Data Checksum Status:" pg_controldata /var/lib/postgresql/17/main | grep "Data page checksum"

5. Kiểm tra extensions

echo "5. Installed Extensions:" psql -c "SELECT extname, extversion FROM pg_extension ORDER BY extname;"

6. Kiểm tra replication slots

echo "6. Replication Slots:" psql -c "SELECT slot_name, slot_type, active FROM pg_replication_slots;"

7. Kiểm tra prepared transactions

echo "7. Prepared Transactions (should be empty):" psql -c "SELECT * FROM pg_prepared_xacts;"

2.2.バックアップ戦略

重要: アップグレードする前に必ずバックアップを行ってください。

# 1. Full backup với pg_dumpall (logical backup)
pg_dumpall -U postgres -h localhost -f /backup/full_backup_$(date +%Y%m%d).sql

2. Base backup (physical backup) - khuyến nghị

pg_basebackup -D /backup/basebackup_$(date +%Y%m%d)
-Ft -z -P
-U replication
-h localhost

3. Backup configuration files

cp /etc/postgresql/17/main/postgresql.conf /backup/ cp /etc/postgresql/17/main/pg_hba.conf /backup/ cp /etc/postgresql/17/main/pg_ident.conf /backup/

2.3. PostgreSQL 18.1 をインストールする

# Ubuntu/Debian
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get install postgresql-18

RHEL/Rocky Linux

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo dnf -qy module disable postgresql sudo dnf install -y postgresql18-server postgresql18-contrib


3. アップグレード方法

3.1.手法の比較

方法 ダウンタイム ユースケース 複雑さ
pg_upgrade 分 同じホスト、短い一時停止 低い
pg_upgrade --link 秒~分 同じファイルシステム、最速 低い
pg_upgrade --swap (新PG18) 秒~分 ディレクトリを交換する 低い
論理レプリケーション 秒 24 時間年中無休のアプリ、ダウンタイムなし 高
pg_dump/restore 時間 - 日付 小規模 DB、クロスプラットフォーム 低い

3.2.生産に関する推奨事項

┌─────────────────────────────────────────────────────────────┐
│                    DECISION FLOWCHART                        │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Database size < 100GB?                                      │
│     YES → pg_upgrade --link hoặc --swap                     │
│     NO  ↓                                                   │
│                                                              │
│  Zero-downtime required?                                     │
│     YES → Logical Replication                                │
│     NO  → pg_upgrade --link với maintenance window           │
│                                                              │
│  Cross-platform migration?                                   │
│     YES → pg_dump/restore                                    │
│                                                              │
└─────────────────────────────────────────────────────────────┘

4.1.新しいクラスターの初期化

# Tạo data directory cho PostgreSQL 18
sudo mkdir -p /var/lib/postgresql/18/main
sudo chown postgres:postgres /var/lib/postgresql/18/main

Chuyển sang user postgres

sudo -i -u postgres

Kiểm tra checksum của cluster cũ

pg_controldata /var/lib/postgresql/17/main | grep "Data page checksum"

Output: Data page checksum version: 0 (disabled) hoặc 1 (enabled)

Init cluster mới với MATCHING checksum setting

Nếu cluster cũ KHÔNG có checksum:

/usr/lib/postgresql/18/bin/initdb
-D /var/lib/postgresql/18/main
--no-data-checksums
--encoding=UTF8
--locale=en_US.UTF-8

Nếu cluster cũ CÓ checksum (hoặc muốn enable):

/usr/lib/postgresql/18/bin/initdb
-D /var/lib/postgresql/18/main
--data-checksums
--encoding=UTF8
--locale=en_US.UTF-8

4.2.アップグレード前チェック

# Set environment variables
export PGBINOLD=/usr/lib/postgresql/17/bin
export PGBINNEW=/usr/lib/postgresql/18/bin
export PGDATAOLD=/var/lib/postgresql/17/main
export PGDATANEW=/var/lib/postgresql/18/main

Chạy check mode TRƯỚC

/usr/lib/postgresql/18/bin/pg_upgrade
--old-datadir=$PGDATAOLD
--new-datadir=$PGDATANEW
--old-bindir=$PGBINOLD
--new-bindir=$PGBINNEW
--check

Expected output:

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

...

Clusters are compatible

4.3.サービスとアップグレードの停止

# 1. Stop ứng dụng kết nối đến database

(tùy thuộc vào setup của bạn)

2. Stop PostgreSQL 17

sudo systemctl stop postgresql@17-main

3. Verify PostgreSQL 17 đã stop

pg_isready -p 5432

Output: no response

4. Thực hiện upgrade với --link mode (nhanh nhất)

cd /var/lib/postgresql /usr/lib/postgresql/18/bin/pg_upgrade
--old-datadir=$PGDATAOLD
--new-datadir=$PGDATANEW
--old-bindir=$PGBINOLD
--new-bindir=$PGBINNEW
--link
--jobs=$(nproc)

Hoặc với --swap mode (PostgreSQL 18 mới)

/usr/lib/postgresql/18/bin/pg_upgrade
--old-datadir=$PGDATAOLD
--new-datadir=$PGDATANEW
--old-bindir=$PGBINOLD
--new-bindir=$PGBINNEW
--swap
--jobs=$(nproc)

4.4.設定ファイルのコピー

# Copy các config files từ cluster cũ
cp /etc/postgresql/17/main/postgresql.conf /etc/postgresql/18/main/
cp /etc/postgresql/17/main/pg_hba.conf /etc/postgresql/18/main/
cp /etc/postgresql/17/main/pg_ident.conf /etc/postgresql/18/main/

Hoặc nếu dùng data directory cho config

cp $PGDATAOLD/postgresql.conf $PGDATANEW/ cp $PGDATAOLD/pg_hba.conf $PGDATANEW/

Cập nhật port trong postgresql.conf nếu cần

(nếu muốn chạy song song cả 2 version)

sed -i 's/port = 5432/port = 5433/' /etc/postgresql/18/main/postgresql.conf

4.5. PostgreSQL 18 を開始して確認する

# Start PostgreSQL 18
sudo systemctl start postgresql@18-main

Verify connection

psql -p 5432 -c "SELECT version();"

Output: PostgreSQL 18.1 on x86_64-pc-linux-gnu...

Verify databases

psql -c "\l"

Verify table counts (sample)

psql -d your_database -c "SELECT schemaname, COUNT(*) FROM pg_tables GROUP BY schemaname;"


5. アップグレード後のタスク

5.1.統計処理 (PostgreSQL 18 は自動的に保存)

# PostgreSQL 18 tự động preserve statistics!

Chỉ cần chạy cho extended statistics nếu có:

/usr/lib/postgresql/18/bin/vacuumdb
--all
--analyze-in-stages
--missing-stats-only

Hoặc chạy đầy đủ nếu muốn

vacuumdb --all --analyze

5.2.拡張機能のアップデート

# Kiểm tra extensions cần update
psql -c "SELECT * FROM pg_extension WHERE extversion != (SELECT default_version FROM pg_available_extensions WHERE name = extname);"

Update tất cả extensions

psql -c "SELECT format('ALTER EXTENSION %I UPDATE;', extname) FROM pg_extension;" | psql

Hoặc update từng extension

psql -c "ALTER EXTENSION pg_stat_statements UPDATE;" psql -c "ALTER EXTENSION postgis UPDATE;"

5.3.クリーンアップ

# Xóa cluster cũ (CHỈ SAU KHI VERIFY HOÀN TẤT!)

pg_upgrade tạo script delete_old_cluster.sh

./delete_old_cluster.sh

Hoặc thủ công

rm -rf /var/lib/postgresql/17/main

Disable PostgreSQL 17 service

sudo systemctl disable postgresql@17-main

5.4.パフォーマンスの検証

-- Kiểm tra query plan của các query quan trọng
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT * FROM your_critical_table WHERE your_condition;

-- So sánh với baseline trước upgrade -- Lưu ý: PostgreSQL 18 EXPLAIN ANALYZE tự động include BUFFERS

-- Kiểm tra AIO settings (PostgreSQL 18) SHOW io_method; -- Output: io_uring (Linux) hoặc worker

-- Monitor với pg_stat_io (mới trong PG16, cải thiện PG18) SELECT * FROM pg_stat_io WHERE reads > 0;


6. 論理レプリケーションを使用したアップグレード (ゼロダウンタイム)

6.1.アーキテクチャの概要

┌──────────────────────┐         ┌──────────────────────┐
│   PostgreSQL 17.6    │         │   PostgreSQL 18.1    │
│     (Publisher)      │  ─────► │    (Subscriber)      │
│   Primary/Source     │   WAL   │   Target/Replica     │
│     Port: 5432       │         │     Port: 5433       │
└──────────────────────┘         └──────────────────────┘
│
▼
Cutover (DNS/HAProxy)

6.2.パブリッシャーのセットアップ (PostgreSQL 17)

-- 1. Enable logical replication trong postgresql.conf
-- wal_level = logical
-- max_replication_slots = 10
-- max_wal_senders = 10

-- 2. Tạo publication CREATE PUBLICATION pg18_migration FOR ALL TABLES;

-- 3. Tạo replication user CREATE USER repl_user WITH REPLICATION PASSWORD 'secure_password'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO repl_user;

-- 4. Cập nhật pg_hba.conf -- host all repl_user subscriber_ip/32 scram-sha-256 -- host replication repl_user subscriber_ip/32 scram-sha-256

6.3.サブスクライバーのセットアップ (PostgreSQL 18)

# 1. Dump schema only (không data)
pg_dump -h old_server -U postgres -s -d your_db > schema.sql

2. Restore schema vào PostgreSQL 18

psql -d your_db -f schema.sql

-- 3. Tạo subscription
CREATE SUBSCRIPTION pg18_sub
CONNECTION 'host=old_server port=5432 dbname=your_db user=repl_user password=secure_password'
PUBLICATION pg18_migration;

-- 4. Monitor sync progress SELECT * FROM pg_stat_subscription; SELECT * FROM pg_subscription_rel;

-- 5. Kiểm tra lag SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) as lag FROM pg_replication_slots;

6.4.カットオーバープロセス

#!/bin/bash

cutover.sh - Zero-downtime cutover script

echo "=== Starting Cutover Process ==="

1. Stop writes to old server (application level)

echo "1. Stopping application writes..."

kubectl scale deployment/app --replicas=0

hoặc update HAProxy/PgBouncer

2. Wait for replication to catch up

echo "2. Waiting for replication lag to be 0..." while true; do LAG=$(psql -h new_server -p 5433 -t -c
"SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn) FROM pg_replication_slots WHERE slot_name='pg18_sub'") if [ "$LAG" -eq 0 ]; then break fi sleep 1 done

3. Disable subscription

echo "3. Disabling subscription..." psql -h new_server -p 5433 -c "ALTER SUBSCRIPTION pg18_sub DISABLE;" psql -h new_server -p 5433 -c "DROP SUBSCRIPTION pg18_sub;"

4. Reset sequences (quan trọng!)

echo "4. Resetting sequences..." psql -h new_server -p 5433 -c "SELECT setval(c.oid, s.last_value) FROM pg_class c JOIN pg_sequences s ON c.relname = s.sequencename WHERE s.last_value IS NOT NULL;"

5. Switch traffic to new server

echo "5. Switching traffic..."

Update DNS, HAProxy, PgBouncer, etc.

echo "=== Cutover Complete ==="


7. ロールバック計画

# QUAN TRỌNG: Với --link mode, bạn KHÔNG THỂ rollback sau khi start cluster mới!

Do đó, LUÔN test kỹ trước khi start

Nếu chưa start PostgreSQL 18:

Chỉ cần start lại PostgreSQL 17

sudo systemctl start postgresql@17-main

7.2. pg_upgrade --copy からのロールバック

# Nếu dùng --copy mode, cluster cũ vẫn còn nguyên

Chỉ cần switch về cluster cũ

sudo systemctl stop postgresql@18-main sudo systemctl start postgresql@17-main

7.3.論理レプリケーションからのロールバック

-- Trên subscriber (PostgreSQL 18)
ALTER SUBSCRIPTION pg18_sub DISABLE;
DROP SUBSCRIPTION pg18_sub;

-- Switch traffic về PostgreSQL 17 -- Update DNS/HAProxy/PgBouncer


8. 監視とトラブルシューティング

8.1.監視スクリプト

#!/bin/bash

monitor-upgrade.sh

echo "=== PostgreSQL 18 Health Check ==="

1. Version

psql -c "SELECT version();"

2. Uptime

psql -c "SELECT pg_postmaster_start_time(), now() - pg_postmaster_start_time() as uptime;"

3. Active connections

psql -c "SELECT count(*) as active_connections FROM pg_stat_activity WHERE state = 'active';"

4. Database sizes

psql -c "SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database ORDER BY pg_database_size(datname) DESC;"

5. Long running queries

psql -c "SELECT pid, now() - pg_stat_activity.query_start AS duration, query FROM pg_stat_activity WHERE state = 'active' AND now() - pg_stat_activity.query_start > interval '5 minutes';"

6. Replication status (if applicable)

psql -c "SELECT * FROM pg_stat_replication;"

7. I/O statistics (PostgreSQL 18)

psql -c "SELECT backend_type, reads, writes, extends FROM pg_stat_io WHERE reads > 0 OR writes > 0;"

9. ベストプラクティスのまとめ

9.1.アップグレード前

  • [ ] よく読んでください リリースノート PostgreSQL 18
  • [ ] ステージング/開発環境でのテストアップグレード
  • [ ] フルバックアップ (論理 + 物理)
  • [ ] ドキュメントのロールバック計画
  • [ ] メンテナンス期間について関係者に通知します
  • [ ] すべての拡張子の互換性を確認する

9.2.アップグレード中

  • [ ] 使用する pg_upgrade --check 実際のアップグレードの前に
  • [ ] アップグレード中にディスク容量を監視する
  • [ ] 端末セッションを維持します 画面 または tmux
  • [ ] トラブルシューティングのためにすべての出力をログに記録します

9.3.アップグレード後

  • [ ] データの整合性を検証する
  • [ ] 重要なクエリをテストし、ベースラインと比較します
  • [ ] 拡張機能の更新
  • [ ] パフォーマンスを 24 ~ 48 時間監視します
  • [ ] 検証の完了後に古いクラスターをクリーンアップする
  • [ ] ドキュメントとランブックを更新する

10. 結論

PostgreSQL 18 は、特に多くの貴重な改善をもたらしました。 非同期I/O そして 統計の保存 これまで以上にスムーズなアップグレードを支援します。慎重に計画し、適切なプロセスに従うことで、運用データベースをアップグレードできます。 最小限のダウンタイム そして リスクが低い。

参考文献:


記事が役に立った場合は、以下に共有してコメントを残してください。 👇