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:
Data Checksums mặc định BẬT (initdb)
- Cần matching checksum settings khi pg_upgrade
MD5 authentication DEPRECATED
- Nên migrate sang SCRAM-SHA-256
Time zone abbreviation handling thay đổi
Session timezone được ưu tiên trước timezone_abbreviations
2. アップグレード前の準備
2.1.アップグレード前のチェックリスト
#!/bin/bashpre-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).sql2. Base backup (physical backup) - khuyến nghị
pg_basebackup -D /backup/basebackup_$(date +%Y%m%d)
-Ft -z -P
-U replication
-h localhost3. 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-18RHEL/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. pg_upgrade によるアップグレード (推奨)
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/mainChuyể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-8Nế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/mainChạy check mode TRƯỚC
/usr/lib/postgresql/18/bin/pg_upgrade
--old-datadir=$PGDATAOLD
--new-datadir=$PGDATANEW
--old-bindir=$PGBINOLD
--new-bindir=$PGBINNEW
--checkExpected 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-mainVerify 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-onlyHoặ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.sql2. 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/bashcutover.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 done3. 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. ロールバック計画
7.1. pg_upgrade --link からのロールバック
# 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ênChỉ 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/bashmonitor-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 そして 統計の保存 これまで以上にスムーズなアップグレードを支援します。慎重に計画し、適切なプロセスに従うことで、運用データベースをアップグレードできます。 最小限のダウンタイム そして リスクが低い。
参考文献:
記事が役に立った場合は、以下に共有してコメントを残してください。 👇
