はじめに
前回の記事(【IBM Cloud】Database for PostgreSQL のバージョンアップ方法について)で少し紹介した「ダウンタイム最小限でバージョンアップする方法」についてまとめています。
バージョンアップ方法について
以前の記事で紹介した通り IBM Cloud Doc には2つの方法が説明されています。
- 読み取り専用レプリカをプロモートしてアップグレード
- バックアップを新規デプロイメントにリストアしてアップグレード
ただし、これらの方法ではデータの損失を防ぐためには一時的に書き込みを停止する必要があります。
そこで、以下の記事で紹介されている PostgreSQL の論理レプリケーションを使った方法が登場します。
https://www.ibm.com/products/tutorials/upgrading-ibm-cloud-databases-for-postgresql-with-minimal-downtime
この方法にすることで、アップグレード中も書き込みを継続でき、アプリケーションの切り替え時のみ瞬間的な停止で済みます。
手順
1. 元のインスタンスの準備
-
wal2jsonを使って論理レプリケーションを有効化
wal2json の構成ドキュメントの説明に従いステップ2まで行い、論理レプリケーションを有効にします。 -
replユーザーに対象テーブルのSELECT権限を付与GRANT SELECT ON ALL TABLES IN SCHEMA {schema} TO repl;紹介している記事にはテーブルへの権限付与のみ行っていますが、スキーマへの権限付与も必要な場合があります。
GRANT USAGE ON SCHEMA {schema} TO repl; -
インスタンスの接続先情報を取得
コンソールの Overview タブの Endpoint > PostgreSQL からインスタンスのホスト名とポートを取得します。
2. 新しいインスタンスの作成
- 新しい PostgreSQL バージョンのインスタンスを作成
-
pg_dump --schema-onlyなどを使って DDL を移行
3. レプリケーション設定
-
元のインスタンスで
CREATE PUBLICATIONを実行CREATE PUBLICATION {schema}_migration FOR TABLE {table}, {table}, {...}; -
新しいインスタンスで
create_subscriptionを実行SELECT create_subscription('{schema}_subscription', '{hostname}', '{port}', '{password}', 'repl', 'ibmclouddb', '{schema}_migration');
4. レプリケーションの確認
以下のクエリを元のインスタンスで実行し、レプリケーションの進捗を確認
SELECT slot_name, confirmed_flush_lsn, pg_current_wal_lsn(), (pg_current_wal_lsn() - confirmed_flush_lsn) AS lsn_distance FROM pg_replication_slots;
lsn_distance がゼロになれば、同期完了です。
5. アプリケーションの切り替え
- アプリケーションの接続先を新しいインスタンスに変更
- 作成したサブスクリプションを削除
SELECT delete_subscription('{schema}_subscription', 'ibmclouddb'); - 動作確認後、元のインスタンスを削除
注意点と制限事項
- DDL やスキーマ変更はレプリケートされないため、手動で移行が必要
- シーケンスやラージオブジェクトは非対応
- IBM Cloud のメンテナンスでレプリケーションが中断する可能性あり
未解決事項
- サイズの大きいテーブルのタイムアウト
タイムアウト時間が 43200000ms(12h) に設定されているため、テーブルサイズによってはタイムアウトして同期が完了しない状況になります。
おそらく、PostgreSQL の設定のstatement_timeoutと思われますが、現時点で変更する方法が不明のため、不要なデータを削除してサイズを減らすことで対応しています。 - レプリケーション切断によるやり直し
注意点と制限事項にあるとおり、メンテナンスによりレプリケーションが切断する可能性があります。
切断すると同期されなくなるため、一度サブスクリプションを削除し再度一から同期し直す必要があります。
なお、切断された状態でdelete_subscriptionを実行すると、サブスクリプションが正しく削除されないため、先に次の2つを実行してください。SELECT disable_subscription('{schema}_subscription','ibmclouddb'); SELECT subscription_slot_none('{schema}_subscription','ibmclouddb');
まとめ
PostgreSQL の論理レプリケーションを活用することで、IBM Cloud Database for PostgreSQL のメジャーバージョンアップを ほぼ無停止で実現 できます。
特に、ミッションクリティカルなアプリケーションを運用している場合には非常に有効な手法です。
以上、Database for PostgreSQL のダウンタイム最小限でバージョンアップ方法についてでした。
運用時の参考になれば幸いです。