目標
このレッスンの後、次のことを行います:
- PostgreSQL メジャー バージョンのアップグレードを計画および実行
- ダウンタイムなしで Patroni をアップグレード
- インプレースで pg_upgrade を使用するアップグレード
- アップグレード用の論理レプリケーションを実装
- 失敗したアップグレードを安全にロールバック
1。アップグレード計画
1.1。アップグレード前チェックリスト
☐ Review PostgreSQL release notes
☐ Check extension compatibility
☐ Test upgrade in staging environment
☐ Backup all data (full + WAL archive)
☐ Document current versions
☐ Schedule maintenance window
☐ Notify stakeholders
☐ Prepare rollback plan
☐ Verify disk space (need 2x current data size)
☐ Check for deprecated features in new version
☐ Update monitoring/alerting
☐ Prepare downtime communication
1.2。バージョン互換性マトリックス
___HTMLTAG_97 ___リスク| From → To | 方法 | ダウンタイム | |
|---|---|---|---|
| 17 → 18 | pg_upgrade | 分___HTMLTAG _108___ | 低 |
| 15 → 18 | pg_upgrade | 分___HTMLTAG_ 118___ | 中 |
| 12 → 18 | 論理的レプリケーション | なし | 中 |
| 9.6 → 18 | ダンプ/復元 | 時間 | 高 |
1.3.現在の状態
# PostgreSQL version psql -c "SELECT version();"Installed extensions
psql -c "\dx"
Database sizes
psql -c "SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database;"
Patroni version
patronictl version
etcd version
etcdctl version
2 を文書化します。 PostgreSQL マイナー バージョン アップグレード
2.1。マイナー アップグレード プロセス (例: 18.0 → 18.1)
# Minor upgrades are easy - just update packagesOn each node (one at a time):
1. Update packages
sudo apt-get update sudo apt-get install --only-upgrade postgresql-18
2. Restart Patroni (will restart PostgreSQL)
sudo systemctl restart patroni
3. Verify new version
psql -c "SELECT version();"
Patroni handles failover automatically during restart
2.2。ローリング マイナー アップグレード_
# Upgrade replicas first for node in node2 node3; do echo "Upgrading $node..." ssh $node "sudo apt-get update && sudo apt-get install -y --only-upgrade postgresql-18" ssh $node "sudo systemctl restart patroni" sleep 30 # Wait for replica to catch up doneSwitchover to upgraded replica
patronictl switchover postgres-cluster --leader node1 --candidate node2
Upgrade old leader (now replica)
ssh node1 "sudo apt-get update && sudo apt-get install -y --only-upgrade postgresql-18" ssh node1 "sudo systemctl restart patroni"
3。 pg_upgrade
3.1 による PostgreSQL メジャー バージョン アップグレード。アーキテクチャ_
Before (PostgreSQL 17): node1 (17, Leader) node2 (17, Replica) node3 (17, Replica)During upgrade: node1 (17, Leader) ← Still serving traffic node2 (18, NEW) ← Upgrading node3 (17, Replica)
After upgrade: node1 (18, Leader) ← Upgraded node2 (18, Replica) node3 (18, Replica)
3.2。新しい PostgreSQL バージョン
# Install PostgreSQL 18 alongside 17 sudo apt-get install -y postgresql-18 postgresql-18-contribBoth versions now installed:
/usr/lib/postgresql/17/
/usr/lib/postgresql/18/
3.3 をインストールします。アップグレードの準備をします (ノード 2 - 最初のレプリカ)
# 1. Stop Patroni on node2 sudo systemctl stop patroni2. Create new data directory for v18
sudo mkdir -p /var/lib/postgresql/18/data sudo chown postgres:postgres /var/lib/postgresql/18/data
3. Initialize new cluster
sudo -u postgres /usr/lib/postgresql/18/bin/initdb
-D /var/lib/postgresql/18/data
--encoding=UTF8
--data-checksums4. Run pg_upgrade
sudo -u postgres /usr/lib/postgresql/18/bin/pg_upgrade
--old-datadir=/var/lib/postgresql/17/data
--new-datadir=/var/lib/postgresql/18/data
--old-bindir=/usr/lib/postgresql/17/bin
--new-bindir=/usr/lib/postgresql/18/bin
--check # Dry run first!If check passes, run actual upgrade:
sudo -u postgres /usr/lib/postgresql/18/bin/pg_upgrade
--old-datadir=/var/lib/postgresql/17/data
--new-datadir=/var/lib/postgresql/18/data
--old-bindir=/usr/lib/postgresql/17/bin
--new-bindir=/usr/lib/postgresql/18/bin
--link # Use hard links (faster)Expected output:
Performing Consistency Checks
-----------------------------
...
Upgrade Complete
----------------
3.4。 v18
# /etc/patroni/patroni.yml postgresql: bin_dir: /usr/lib/postgresql/18/bin # Changed from 17 data_dir: /var/lib/postgresql/18/data # Changed from 17... rest of config
# Start Patroni with new version sudo systemctl start patroniVerify node2 is now running v18
psql -h node2 -U postgres -c "SELECT version();"
3.5 の Patroni 設定を更新します。残りのノード_
# Repeat process for node3 ssh node3 "sudo systemctl stop patroni" ssh node3 "# ... same pg_upgrade steps ..." ssh node3 "sudo systemctl start patroni"Finally, upgrade node1 (current leader)
Switchover to node2 first
patronictl switchover postgres-cluster --leader node1 --candidate node2
Now upgrade node1
ssh node1 "sudo systemctl stop patroni" ssh node1 "# ... same pg_upgrade steps ..." ssh node1 "sudo systemctl start patroni"
All nodes now on v18!
patronictl list
3.6 をアップグレードします。アップグレード後のタスク_
# Run generated optimize scripts sudo -u postgres ./analyze_new_cluster.sh sudo -u postgres ./reindex_hash.sh # If upgrading from < 10Update extensions
psql -c "ALTER EXTENSION pg_stat_statements UPDATE;"
Vacuum analyze all databases
vacuumdb --all --analyze-in-stages
Remove old cluster (after verifying everything works!)
sudo -u postgres ./delete_old_cluster.sh
4。論理レプリケーションによるダウンタイムゼロのアップグレード_
4.1。アーキテクチャ_
Production (v17): node1 (v17, Leader) ← Serving traffic ↓ Logical replication New cluster (v18): node4 (v18, Leader) ← Receiving changes node5 (v18, Replica)
After cutover: Application → node4 (v18) ← New primary
4.2。新しい v18 クラスター_
# Install PostgreSQL 18 on new serversSetup Patroni cluster (node4, node5, node6)
See previous lessons for installation
Verify new cluster
patronictl -c /etc/patroni/patroni-v18.yml list
4.3 をセットアップします。 v17 (ソース)
-- On node1 (v17 leader) CREATE PUBLICATION pg17_to_pg18 FOR ALL TABLES;-- Or specific tables: -- CREATE PUBLICATION pg17_to_pg18 FOR TABLE users, orders, products;
-- Verify SELECT * FROM pg_publication;
4.4 でパブリケーションを作成します。 v18 (ターゲット)
-- On node4 (v18 leader) CREATE SUBSCRIPTION pg18_from_pg17 CONNECTION 'host=node1 port=5432 dbname=myapp user=replicator password=rep_pass' PUBLICATION pg17_to_pg18 WITH (copy_data = true, create_slot = true);-- Monitor initial sync SELECT * FROM pg_stat_subscription;
-- Wait for initial data copy to complete -- subname | pg18_from_pg17 -- received_lsn | 0/3000000 -- ...
4.5 でサブスクリプションを作成します。レプリケーションの遅延_
-- On v17 (source) SELECT slot_name, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots WHERE slot_name LIKE '%pg18%';
-- On v18 (target) SELECT subname, received_lsn, latest_end_lsn, pg_size_pretty(pg_wal_lsn_diff(latest_end_lsn, received_lsn)) AS lag FROM pg_stat_subscription;
4.6を監視します。カットオーバー手順_
# 1. Stop writes to v17 (put app in maintenance mode)Or set database to read-only:
psql -h node1 -U postgres -c "ALTER SYSTEM SET default_transaction_read_only = on;" psql -h node1 -U postgres -c "SELECT pg_reload_conf();"
2. Wait for replication to catch up
psql -h node4 -U postgres -c "SELECT pg_size_pretty(pg_wal_lsn_diff(latest_end_lsn, received_lsn)) FROM pg_stat_subscription;"
Should be 0 bytes
3. Disable subscription on v18
psql -h node4 -U postgres -c "ALTER SUBSCRIPTION pg18_from_pg17 DISABLE;"
4. Drop subscription (optional, after confirming everything works)
psql -h node4 -U postgres -c "DROP SUBSCRIPTION pg18_from_pg17;"
5. Update application connection strings to point to node4
6. Enable writes on v18
psql -h node4 -U postgres -c "ALTER SYSTEM SET default_transaction_read_only = off;" psql -h node4 -U postgres -c "SELECT pg_reload_conf();"
7. Verify application works on v18
8. Keep v17 cluster running for rollback (1-2 weeks)
5。 Patroni バージョン アップグレード
5.1。互換性を確認してください_
# Check current Patroni version patronictl versionCheck PostgreSQL compatibility
Patroni 3.2.0+ supports PostgreSQL 18
See: https://github.com/zalando/patroni/releases
5.2。 Patroni のアップグレード (Python パッケージ)
# On each node:1. Upgrade via pip
sudo pip3 install --upgrade patroni[etcd]
Or specific version:
sudo pip3 install patroni[etcd]==3.2.2
2. Verify new version
patronictl version
3. Restart Patroni service
sudo systemctl restart patroni
No downtime - Patroni handles failover automatically
5.3。ローリング パトローニのアップグレード_
# Upgrade replicas first for node in node2 node3; do echo "Upgrading Patroni on $node..." ssh $node "sudo pip3 install --upgrade patroni[etcd]" ssh $node "sudo systemctl restart patroni" sleep 10 doneSwitchover to upgraded replica
patronictl switchover postgres-cluster --leader node1 --candidate node2
Upgrade old leader
ssh node1 "sudo pip3 install --upgrade patroni[etcd]" ssh node1 "sudo systemctl restart patroni"
6。 etcd のアップグレード_
6.1。 etcd のマイナー アップグレード
# On each etcd node: sudo systemctl stop etcd sudo apt-get update sudo apt-get install --only-upgrade etcd sudo systemctl start etcdVerify cluster health
etcdctl endpoint health
6.2。 etcd メジャー アップグレード (例: 3.4 → 3.5)
# Follow official etcd upgrade guidehttps://etcd.io/docs/latest/upgrades/
Key steps:
1. Backup etcd data
etcdctl snapshot save backup.db
2. Upgrade one member at a time
3. Verify cluster health after each upgrade
4. Update Patroni to use new etcd API version
7。ロールバック戦略
7.1。 pg_upgrade
# Before deleting old cluster, you can rollback1. Stop Patroni
sudo systemctl stop patroni
2. Restore old configuration
/etc/patroni/patroni.yml
postgresql: bin_dir: /usr/lib/postgresql/17/bin # Back to 17 data_dir: /var/lib/postgresql/17/data
3. Start Patroni
sudo systemctl start patroni
Old cluster resumes operation
7.2 をロールバックします。論理レプリケーションをロールバック
# If cutover to v18 fails, rollback to v171. Stop application
2. Set v17 to read-write
psql -h node1 -U postgres -c "ALTER SYSTEM SET default_transaction_read_only = off;" psql -h node1 -U postgres -c "SELECT pg_reload_conf();"
3. Update application connection strings to v17
4. Resume normal operations
Note: Any writes to v18 during cutover will be LOST!
Consider setting up reverse replication v18 → v17 if needed
7.3。 Patroni のアップグレード
# Downgrade Patroni if upgrade causes issues
sudo pip3 install patroni[etcd]==3.1.2 # Previous version sudo systemctl restart patroni
8 をロールバックします。アップグレードのテスト_
8.1。ステージング環境テスト
# 1. Clone production to staging pg_basebackup -h prod-leader -D /var/lib/postgresql/staging -X stream2. Perform upgrade in staging
... follow upgrade procedures ...
3. Run application tests
... smoke tests, integration tests ...
4. Benchmark performance
pgbench -i -s 100 myapp pgbench -c 10 -j 2 -t 1000 myapp
5. Document issues and timings
8.2。アップグレードのリハーサル
# Practice upgrade multiple timesTime each step
Identify bottlenecks
Refine procedures
Example timing log:
Step 1: Stop Patroni - 5 seconds
Step 2: pg_upgrade --check - 30 seconds
Step 3: pg_upgrade - 10 minutes
Step 4: Start Patroni - 15 seconds
Step 5: Replication catchup - 2 minutes
Total: ~13 minutes
9。ベスト プラクティス
✅ DO
- 最初にステージングでテスト - 複数回
- バックアップすべて_ - 完全バックアップ + WAL アーカイブ_
- pg_upgrade --check - 問題を早期に発見
- 文書化手順 -ステップバイステップのランブック_
- メンテナンス期間のスケジュール - オフピーク時間_
- 注意深く監視 - メンテナンス中およびメンテナンス後アップグレード
- 古いバージョンを保持 - 1~2 週間削除しないでください
- 論理レプリケーションを使用 -ゼロダウンタイム
- 拡張機能のアップグレード - PostgreSQL アップグレード後
- 真空分析 - メジャー後アップグレード
❌ 禁止
- バックアップをスキップしない - 重要なセーフティネット
- すべてをアップグレードしないでください一度に - ローリングアップグレード
- 古いクラスターをすぐに削除しないでください - ロールバックのために保持_
- リリースを無視しないでくださいメモ_ - 重大な変更
- テストをスキップしないでください - ステージングは不可欠_
- ピーク時間帯にはアップグレードしないでください - メンテナンスを計画してくださいウィンドウ_
- 拡張機能を忘れないでください_ - 更新が必要な場合があります
10。ラボ演習
ラボ 1: マイナー バージョン アップグレード
タスク:
- 現在の PostgreSQL バージョンを確認する
- パッケージを更新するレプリカ_
- レプリカで Patroni を再起動_
- アップグレードされたレプリカに切り替え_
- 古いリーダーをアップグレード
ラボ 2: pg_upgrade によるメジャー バージョン アップグレード
タスク:
- すべてに PostgreSQL 18 をインストールするノード_
- pg_upgrade を実行 -- レプリカでチェック
- レプリカで pg_upgrade を実行
- Patroni 構成を更新
- ローリングを完了アップグレード
ラボ 3: 論理レプリケーションによるダウンタイムゼロのアップグレード
タスク:
- 新しい v18 をセットアップするクラスター_
- v17 でパブリケーションを作成_
- v18 でサブスクリプションを作成
- レプリケーションラグを監視_
- カットオーバーを実行_
- アプリケーションを確認機能
ラボ 4: ロールバック手順
タスク:
- 失敗したアップグレードのシミュレーション
- 停止すべてのノードで Patroni_
- 古い構成を復元
- 古いクラスターを再起動_
- ロールバックが成功したことを確認_
11。概要____HTMLTAG_364__HTMLTAG_365___アップグレード方法の比較
__ _HTMLTAG_387___分___HTMLTAG_411__ _時間| 方法 | ダウンタイム_ __HTMLTAG_374___ | 複雑さ | リスク | 使用ケース_ |
|---|---|---|---|---|
| pg_upgrade | 低 | 低_ | マイナーバージョンのジャンプ | |
| 論理的レプリケーション | なし | 高 | 中 | ゼロダウンタイム必須 |
| ダンプ/復元 | 低 | 低 | 古代バージョン_ | |
| pg_upgrade --link | 秒 | Medium | Medium | _同じサーバーアップグレード |
一般的なタイムライン___HTMLTAG_436__CODEBLOCK_27___
アップグレード チェックリスト_
Pre-upgrade: ☐ Full backup completed ☐ Staging test successful ☐ Release notes reviewed ☐ Maintenance window scheduled ☐ Rollback plan documented ☐ Stakeholders notifiedDuring upgrade: ☐ Backups verified ☐ pg_upgrade --check passed ☐ Upgrade completed ☐ Replication working ☐ Application connectivity verified
Post-upgrade: ☐ Extensions updated ☐ Vacuum analyze completed ☐ Performance validated ☐ Monitoring updated ☐ Documentation updated
次のステップ_
レッスン 25 では実際のケースについて説明します研究_:
- 運用アーキテクチャの例
- 1000 クエリ/秒以上に拡張
- コストの最適化テクニック
- 失敗から学んだ教訓
- 業界固有の実装