PostgreSQL 17では、フェイルオーバーやメジャーアップグレードが発生しても論理レプリケーションを途切れさせない画期的な機能として、sync_replication_slot パラメータが導入されました。従来のPostgreSQLではフルリシンクが必要でしたが、本機能により論理レプリケーションに依存する下流システムへの影響を最小限に抑えられます。本記事では、Amazon Relational Database Service(RDS)インスタンスを用いた実践的な構成例を通じて、sync_replication_slots の設定方法と動作確認の手順を解説します。
取り上げるシナリオでは、3つのRDS PostgreSQLインスタンスを使用します。
- プライマリ(PRI): ソースデータベース
- リードレプリカ(RR): フェイルオーバー時に昇格するスタンバイレプリカ
- 論理レプリカ(LR): プライマリからの論理レプリケーションを受け取るサブスクライバインスタンス
前提条件
始める前に、以下を準備してください。
- AWS CLI がアクセスキーとシークレットキーで設定済みであること。
- RDSインスタンスへ接続できること。
- 使用するIPからポート
5432への接続を許可するVPCセキュリティグループ(SG)が用意されていること。
全体の流れ
- パラメータグループの作成と設定:必要なパラメータを構成します。
- RDSインスタンスのプロビジョニング:RDS PostgreSQLインスタンスを作成します。
- 論理レプリケーションのセットアップ:スロット、パブリケーション、サブスクリプションを構成します。
- フェイルオーバーのシミュレーションとサブスクリプション更新:リードレプリカを昇格させ、サブスクリプションの接続先を新しいプライマリへ切り替えます。
- レプリケーションフローのテスト:データの整合性を確認します。
- クリーンアップ:リソースを削除します。
ステップ別の手順
1. パラメータグループの設定
- まず、プライマリ、リードレプリカ、論理レプリカ用のカスタムパラメータグループを作成し、以下のパラメータを有効化します。
| Parameter | Value | Description |
|------------------------------|-----------|--------------------------------------------------------------------------------|
| rds.logical_replication | 1 | プライマリインスタンスで論理レプリケーションを有効化します。 |
| hot_standby_feedback | 1 | スタンバイからプライマリへフィードバックを送り、クエリ競合を防ぎます。 |
| rds.logical_slot_sync_dbname | Valid DB | 論理スロット同期に使うデータベースを指定します(デフォルト:`postgres`)。 |
| synchronized_standby_slots | Slot name | 同期を維持するスタンバイの物理レプリケーションスロット名。 |
| sync_replication_slots | 1 | レプリケーションスロットの自動同期を有効化します。 |
パラメータグループを作成します。リードレプリカと論理レプリカについても同様の手順を繰り返してください。
aws rds create-db-parameter-group \
--db-parameter-group-name pg-primary-group \
--db-parameter-group-family postgres17 \
--description "Logical replication setup with sync_replication_slots"
- パラメータを変更します。synchronized_standby_slots はリードレプリカ作成後に設定します。
aws rds modify-db-parameter-group \
--db-parameter-group-name pg-primary-group \
--parameters "ParameterName='rds.logical_replication',ParameterValue=logical,ApplyMethod=pending-reboot" \
"ParameterName='sync_replication_slots',ParameterValue=1,ApplyMethod=pending-reboot"
aws rds modify-db-parameter-group \
--db-parameter-group-name pg-read-replica-group \
--parameters "ParameterName='rds.logical_replication',ParameterValue=1,ApplyMethod=pending-reboot" \
"ParameterName='hot_standby_feedback',ParameterValue='1',ApplyMethod=pending-reboot" \
"ParameterName='rds.logical_slot_sync_dbname',ParameterValue='postgres',ApplyMethod=pending-reboot" \
"ParameterName='sync_replication_slots',ParameterValue=1,ApplyMethod=pending-reboot"
2. RDSインスタンスのプロビジョニング
- AWS CLIでプライマリインスタンス、論理レプリカ、リードレプリカを作成します。テスト用途のため、ここではパブリックアクセスを許可しています。
aws rds create-db-instance \
--db-instance-identifier primary-instance \
--engine postgres \
--engine-version 17.1 \
--allocated-storage 20 \
--master-username postgres \
--master-user-password ChangeM3 \
--db-instance-class db.t3.medium \
--vpc-security-group-ids sg-xxxxxx
論理レプリカも同様に作成します。
- リードレプリカの場合:
aws rds create-db-instance-read-replica \
--db-instance-identifier read-replica \
--source-db-instance-identifier primary-instance
- リードレプリカの作成後、プライマリインスタンスから物理スロット名を取得し、pg-primary-group パラメータグループを更新します。
psql -h $DB_PRI -U postgres -t -c "SELECT slot_name FROM pg_replication_slots where slot_type='physical'"
aws rds modify-db-parameter-group \
--db-parameter-group-name pg-primary-group \
--parameters "ParameterName='synchronized_standby_slots',ParameterValue='rds_us_east_1_db_dn2uyr2436rexq3u7gcdfzw4hy',ApplyMethod=pending-reboot"
- 続いて、各インスタンスに対応するパラメータグループを割り当て、再起動します。
- パラメータが正しく反映されているかを確認します。フェイルオーバー後も論理レプリケーションを継続させるには、これらの設定が不可欠です。
psql -h $DB_PRI -U postgres -c "SELECT name,setting FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication','sync_replication_slots','synchronized_standby_slots')"
:' output
name | setting
----------------------------+---------------------------------------------
rds.logical_replication | on
sync_replication_slots | on
synchronized_standby_slots | rds_us_east_1_db_dn2uyr2436rexq3u7gcdfzw4hy
wal_level | logical
(4 rows)
'
# rds.logical_slot_sync_dbname is not available in pg_settings
# make sure to update it if your database is not "postgres."
psql -h $DB_RR -U postgres -c "SELECT name,setting FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication','sync_replication_slots','hot_standby_feedback','rds.logical_slot_sync_dbname')"
:' output
name | setting
-------------------------+---------
hot_standby_feedback | on
rds.logical_replication | on
sync_replication_slots | on
wal_level | logical
(4 rows)
'
3. 論理レプリケーションのセットアップ
プライマリインスタンスでの作業:
- ソーステーブルを作成し、サンプルデータを投入してパブリケーションを作成します。
CREATE TABLE reptab1 (slno int primary key);
INSERT INTO reptab1 VALUES (generate_series(1,1000));
CREATE PUBLICATION testpub FOR TABLE reptab1;
- 論理レプリカ側に同じテーブルを作成し、failover = true を指定したサブスクリプションを作成します。これによりプライマリインスタンス上に論理レプリケーションスロットが作られます。
CREATE TABLE reptab1 (slno int primary key);
CREATE SUBSCRIPTION testsub CONNECTION 'host=<primary-endpoint> port=5432 dbname=postgres user=postgres password=ChangeM3' PUBLICATION testpub WITH (failover = true);
- サブスクリプションが有効化されており、データがコピーされていることを確認します。
SELECT subname, subenabled FROM pg_subscription;
SELECT count(*) from reptab1;
- リードレプリカインスタンス側にも論理レプリケーションスロットが作成されているはずです。
psql -h $DB_RR -U postgres -c "select slot_name, slot_type, active, failover, synced from pg_replication_slots;"
:'output
slot_name | slot_type | active | failover | synced
-----------+-----------+--------+----------+--------
testsub | logical | f | t | t
(1 row)
'
4. フェイルオーバーのシミュレーションとサブスクリプションの更新
フェイルオーバーをシミュレートする手順:
- リードレプリカを独立したインスタンスへ昇格させます。
aws rds promote-read-replica \
--db-instance-identifier read-replica
- 論理レプリカ側のサブスクリプションを更新し、新しいプライマリへ接続先を切り替えます。
ALTER SUBSCRIPTION testsub CONNECTION 'host=<read-replica-endpoint> port=5432 dbname=postgres user=postgres password=ChangeM3';
5\. 動作確認
sync_replication_slots を有効化しておくと、フェイルオーバー時にも論理レプリケーションスロットが保持されるため、サブスクライバ(論理レプリカ)は再同期なしでシームレスにレプリケーションを継続できます。
- 昇格したリードレプリカに新しい行を追加し、レプリケーションを検証します。
INSERT INTO reptab1 VALUES (generate_series(1001,2000));
- 論理レプリカに更新後の行が反映されていることを確認します。
SELECT COUNT(*) FROM reptab1; -- 新しいデータが反映されているはずです
6\. クリーンアップ
余計なコストを発生させないよう、すべてのRDSインスタンスとパラメータグループを削除します。
aws rds delete-db-instance --db-instance-identifier primary-instance --skip-final-snapshot
aws rds delete-db-instance --db-instance-identifier read-replica --skip-final-snapshot
aws rds delete-db-instance --db-instance-identifier logical-replica --skip-final-snapshot
aws rds delete-db-parameter-group --db-parameter-group-name pg-primary-group
aws rds delete-db-parameter-group --db-parameter-group-name pg-read-replica-group
aws rds delete-db-parameter-group --db-parameter-group-name pg-logical-replica-group
PostgreSQL 17の sync_replication_slots パラメータは、フェイルオーバーをまたいでスロットの同期状態を維持できるため、論理レプリケーションの耐障害性を大幅に高めます。データ整合性とダウンタイム最小化が求められるシーンでは、極めて大きなメリットをもたらす機能です。本記事では、フェイルオーバーをシミュレートしてサブスクリプションを切り替えるだけで、論理レプリケーションがシームレスに継続できることをお見せしました。
本番環境では、暗号化、マルチAZ構成、モニタリングといった観点もあわせて検討し、堅牢な構成に仕上げてください。
動作するサンプルの全体は、こちらのスクリプトでご覧いただけます: https://gist.github.com/aamir814/092ed85bd90e28d79af029e561c1da88
本機能やPostgreSQL全般に関するサポートが必要でしたら、ぜひお問い合わせください。当社のチームはシニアレベルのエンジニアのみで構成されています。DoiT International は、高度なクラウドコンサルティング、アーキテクチャ設計、デバッグサービスを得意としています。分散データベースの導入を検討している段階でも、既存システムの最適化や複雑な問題のトラブルシューティングであっても、お客様のニーズに合わせた専門的なアドバイスをご提供します。
クラウドインフラのポテンシャルを最大限に引き出すために、今すぐお問い合わせください。
参考資料: