PostgreSQL 17では、高可用性の設定を強化するフェイルオーバースロットが導入されました。レプリケーションスロットは、レプリケーション中にノード間のデータを信頼性と一貫性を保つことを確実にし、一方、フェイルオーバースロットは、特にフェイルオーバー中およびその後にノード間の一貫性を確保します。
フェイルオーバースロットは、転送先サーバーへのフェイルオーバー後でも、論理レプリケーションが途切れることなく継続できる強力な機能です。フェイルオーバースロットを使用すると、論理レプリケーションスロットをプライマリノードとスタンバイノード間で自動的に同期させることが可能となり、フェイルオーバー時のダウンタイムと手動介入の必要性を大幅に減らすことができます。
このガイドでは、新しいフェイルオーバースロット機能を使用して高可用性のPostgreSQLクラスターを設定する方法を説明します。最終的には、フェイルオーバーをスムーズに処理できる堅牢なレプリケーションセットアップが完成します。
フェイルオーバースロットが歴史的観点から重要である理由
PostgreSQL 15の課題
- プライマリノードに結び付けられたレプリケーションスロット:PostgreSQL 15では、レプリケーションスロットはプライマリサーバーでのみ作成されていました。プライマリサーバーが故障すると、すべての論理レプリケーションスロットが失われ、重大なレプリケーション遅延とデータ損失が発生しました。
- 手動フェイルオーバーの管理:フェイルオーバーシナリオ中、管理者は新しいプライマリサーバーでレプリケーションスロットを手動で再作成する必要があり、これにより複雑さが増し、エラーが導入され、ダウンタイムが延長されました。
- スロット同期なし:スタンバイサーバーはプライマリの論理レプリケーションスロットについて何も知る手段がありませんでした。この同期の欠如により、フェイルオーバーが発生するとレプリケーションストリームが完全にリセットされました。
PostgreSQL 16の改良
最小限の論理デコーディング
PostgreSQL 16では、スタンバイで最小限の論理デコーディングという機能が導入されました。
- スタンバイでの最小デコーディング:これにより、スタンバイサーバーはWALログをデコードして論理レプリケーションの準備を行い、フェイルオーバーが発生した場合に使用するための事前準備スロットを有効にしました。
- 高速フェイルオーバー:スタンバイでWALの変更を事前にデコードすることで、スタンバイをプライマリに昇格させる際のレプリケーション遅延を短縮することが可能でした。ただし、スムーズなフェイルオーバーを確保するためには引き続き一部の手動設定が必要でした。
PostgreSQL 17: ゲームチェンジャー – フェイルオーバースロット
- フェイルオーバースロット:PostgreSQL 17で導入されたフェイルオーバースロットは、プライマリとスタンバイサーバー間の論理レプリケーションスロットを自動的に同期することで、手動介入を不要にしました。
- 自動同期:新しいスロット同期ワーカーにより、フェイルオーバーが有効になっているスロット(failover = true)が常に同期されるようになりました。これは、プライマリノードがアクティブな状態でも常に同期されます。
- シームレスなトランジション: フェイルオーバー時、待機サーバーはレプリケーションスロットを失うことなくプライマリとして引き継ぎ、データの損失をゼロにし、継続的なレプリケーションを確保します。
Feature |
PostgreSQL 15 |
PostgreSQL 16 |
PostgreSQL 17 |
---|---|---|---|
論理レプリケーション |
はい |
はい |
はい |
自動スロット同期 |
いいえ |
スタンバイにおける最小限の論理デコード |
フェイルオーバースロットの完全な引き継ぎ |
フェイルオーバー処理 |
手動介入が必要 |
待機中の事前ウォームアップ済みスロット |
自動フェイルオーバースロット |
スロットのスタンバイへの同期 |
サポートされていません |
最小限で、構成が必要です |
スロット同期ワーカーによる自動 |
論理レプリケーションの高可用性 |
限定された |
最小限のデコードで改善 |
フェイルオーバースロットを使用したシームレス |
フェイルオーバースロットを使用した高可用性クラスタの作成
このセクションでは、フェイルオーバースロットを使用したPostgreSQLの高可用性クラスタの作成方法について説明します。例として、次のノードを使用します:
- NodeA(プライマリサーバー)
- NodeB(物理スタンバイ)
- NodeC(論理サブスクライバー)
前提条件
始める前に、以下を確認してください:
- 3つのノードすべてにPostgreSQL 17がインストールされていること。
- 各ノード間でパスワードなしのSSHアクセスが可能であること。
- PostgreSQL、PostgreSQLレプリケーション、およびPostgreSQL 構成ファイルの基本的な理解があること。
ステップ1: プライマリノード(NodeA)の構成
1.1 NodeAでクラスタを初期化します
主ノードにPostgreSQLをインストールした後、クラスタを初期化します。次のコマンドを使用できます:
mkdir -p /home/pgedge/nodeA
initdb -D /home/pgedge/nodeA --no-locale -E UTF8
pg_ctl -D /home/pgedge/nodeA -l /home/pgedge/logs/nodeA.log start
1.2 postgresql.confファイルでレプリケーションを構成します
クラスタを初期化した後、デフォルトで/home/pgedge/nodeA/postgresql.conf
にあるpostgresql.conf
ファイルを編集します。次のパラメータ値を設定します:
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
synchronous_standby_names = '*'
synchronized_standby_slots = 'sb1_slot'
port = 5432
1.3 pg_hba.confファイルを更新してレプリケーションアクセスを許可します
pg_hba.confファイルはPostgreSQLサーバーのクライアント認証を管理します。 レプリケーションユーザーのアクセスを確保するために、/home/pgedge/nodeA/pg_hba.conf
に次のエントリを追加します:
host replication replicator 127.0.0.1/32 md5
その後、構成を再読み込みします:
pg_ctl -D /home/pgedge/nodeA reload
1.4 レプリケーションユーザーを作成します
次に、PostgreSQLにログインしてレプリケーションユーザーを作成します:
psql -d postgres -p 5432
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replicator_password';
1.5 テーブルを作成し、パブリケーションを設定します
次に、テーブルを作成し、関連付けられたパブリケーションを作成する必要があります:
CREATE TABLE foo (c1 INT PRIMARY KEY);
GRANT SELECT ON foo TO replicator;
CREATE PUBLICATION mypub FOR TABLE foo;
ステップ2:物理スタンバイの構成(NodeB)
2.1 NodeBを初期化します
PostgreSQLをインストールした後、NodeBを初期化します:
mkdir -p /home/pgedge/nodeB
initdb -D /home/pgedge/nodeB --no-locale -E UTF8
pg_ctl -D /home/pgedge/nodeB -l /home/pgedge/logs/nodeB.log start
2.1 ベースバックアップを作成します
次に、クラスタのバックアップを取るためにpg_basebackupを使用します:
mkdir -p /home/pgedge/nodeB
pg_basebackup -D /home/pgedge/nodeB -R -X stream -P -h localhost -p 5432 -U replicator
2.2 Node-Bでpostgresql.confを構成します
postgresql.conf
ファイル(/home/pgedge/nodeB/postgresql.conf
に位置)を変更し、次の設定を行います:
port = 5433
primary_conninfo = 'host=localhost port=5432 user=replicator password=replicator_password dbname=postgres application_name=sb1_slot'
primary_slot_name = 'sb1_slot'
hot_standby_feedback = on
sync_replication_slots = on
2.3 フェイルオーバースロット同期を有効にする
psqlクライアントを使用してNodeBにログインします:
psql -d postgres -p 5433
次に、NodeBのレプリケーションを構成するために次のステートメントを使用します:
ALTER SYSTEM SET sync_replication_slots = on;
ALTER SYSTEM SET hot_standby_feedback = on;
ALTER SYSTEM SET synchronized_standby_slots = 'sb1_slot';
psql
クライアントを終了し、NodeBを再起動します:
pg_ctl -D /home/pgedge/nodeB restart
2.4 スロット同期の確認
その後、psql
を使用してNodeBに再接続し、スロットが同期されていることを確認します:
SELECT slot_name, failover, synced FROM pg_replication_slots;
ステップ3: 論理サブスクライバー(NodeC)の設定
3.1 クラスタを初期化し、NodeCを構成します
PostgreSQLをインストールした後、クラスタを初期化します。次のコマンドを使用できます:
mkdir -p /home/pgedge/nodeC
initdb -D /home/pgedge/nodeC --no-locale -E UTF8
次に、次のパラメータ値を設定して、/home/pgedge/nodeC/postgresql.conf
ファイルを編集します:
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
sync_replication_slots = on
port = 5444
After editing the configuration file, start NodeC:
pg_ctl -D /home/pgedge/nodeC -l /home/pgedge/logs/nodeC.log start
3.2 NodeCにサブスクリプションを作成します
NodeCでサブスクリプションを作成するには、次のコマンドを使用します:
CREATE SUBSCRIPTION foosub CONNECTION 'dbname=postgres host=localhost port=5432 user=replicator password=replicator_password' PUBLICATION mypub WITH (failover = true);
ステップ4: フェイルオーバーのシミュレーションと連続性の確保
次のコマンドを使用して、フェイルオーバーをシミュレートし、レプリケーションが継続され、データの整合性が保持されていることを確認できます。
4.1 フェイルオーバーのシミュレーション
NodeAの障害をシミュレートし、その後NodeBのスタンバイからプライマリへの昇格を行うには、次のコマンドを使用します:
pg_ctl -D /home/pgedge/nodeA stop
pg_ctl -D /home/pgedge/nodeB promote
4.2 NodeCでサブスクリプションを更新します
NodeBを昇格した後、NodeCにログインして、NodeBが現在プライマリノードであることを反映するために接続を更新します。
ALTER SUBSCRIPTION foosub DISABLE;
ALTER SUBSCRIPTION foosub CONNECTION 'dbname=postgres host=localhost port=5433 user=replicator password=replicator_password';
ALTER SUBSCRIPTION foosub ENABLE;
4.3 データの継続性を検証
レプリケーションをテストするには、psql
を使用してNode-B(現在のプライマリ)にログインします:
INSERT INTO foo VALUES (3), (4);
Node-Cでレプリケーションを確認します:
SELECT * FROM foo;
結論
PostgreSQL 17のフェイルオーバースロット機能を使用すると、論理レプリケーション環境でシームレスなフェイルオーバーが可能になります。このガイドで概説されている手順に従うことで、プライマリサーバーの障害が発生してもデータフローが途切れることなく、中断されない高可用性クラスターを作成できます。
構成を最適化し、PostgreSQL 17の新機能を活用することで、ミッションクリティカルなアプリケーション向けに耐障害性の高い効率的なデータベースインフラストラクチャを作成できます。
Source:
https://dzone.com/articles/setting-up-failover-slots-in-postgresql-17