pglogical を使用してインスタンス間でデータを同期する
現在利用可能なすべての Aurora PostgreSQL バージョンは、pglogical
拡張機能をサポートしています。pglogical 拡張は、バージョン 10 で PostgreSQL により導入された機能的に類似した論理レプリケーション機能よりも前のものです。詳細については、「Aurora での PostgreSQL 論理レプリケーションの概要」を参照してください。
pglogical
拡張が、2 つ以上の Aurora PostgreSQL DB クラスター間の論理レプリケーションをサポートします。また、異なる PostgreSQL バージョン間のレプリケーション、および RDS for PostgreSQL DB と Aurora PostgreSQL DB クラスターで実行されているデータベース間のレプリケーションもサポートしています。pglogical
拡張は、公開/サブスクライブモデルを使用して、テーブルやその他のオブジェクト (シーケンスなど) への変更をパブリッシャーからサブスクライバーに複製します。パブリッシャーノードからサブスクライバーノードに変更が確実に同期されるようにするには、レプリケーションスロットを使用し、次のように定義されます。
パブリッシャーノードは、他のノードにレプリケートされるデータのソースである Aurora PostgreSQL DB クラスターです。パブリッシャーノードは、パブリケーションセットでレプリケートするテーブルを定義します。
サブスクライバーノードは、公開者から WAL の更新を受け取る Aurora PostgreSQL DB クラスターです。サブスクライバーは、パブリッシャーに接続してデコードされた WAL データを取得するためのサブスクリプションを作成します。サブスクライバーがサブスクリプションを作成すると、パブリッシャーノードに複製スロットが作成されます。
pglogical
拡張の設定についての情報は、以下を参照してください。
トピック
pglogical 拡張の要件と制限
Aurora PostgreSQL の現在利用可能なすべてのリリースが pglogical
拡張機能をサポートしています。
パブリッシャーノードとサブスクライバーノードの両方を論理レプリケーション用に設定する必要があります。
サブスクライバーからパブリッシャーにレプリケートするテーブルは、同じ名前と同じスキーマである必要があります。これらのテーブルにも同じ列が含まれている必要があり、列は同じデータ型を使用する必要があります。パブリッシャーテーブルとサブスクライバーテーブルの両方に同じプライマリキーが必要です。一意の制約事項としては PRIMARY KEY のみを使用することをお勧めします。
サブスクライバーノードのテーブルには、CHECK 制約と NOT NULL 制約について、パブリッシャーノードのテーブルよりも許可度が高い制約を設定できます。
pglogical
拡張は、PostgreSQL (バージョン 10 以降) に組み込まれている論理レプリケーション機能ではサポートされていない双方向レプリケーションなどの機能を提供します。詳細については、「PostgreSQL bi-directional replication using pglogical
pglogical 拡張のセットアップ
Aurora PostgreSQL DB クラスターに pglogical
拡張機能を設定するには、Aurora PostgreSQL DB クラスター用のカスタム DB クラスターのパラメータグループの共有ライブラリに pglogical
を追加します。また、論理デコードをオンにするには、rds.logical_replication
パラメータの値を 1
に設定する必要があります。最後に、データベースに拡張を作成します。これらのタスクには、AWS Management Console または AWS CLI を使用できます。
これらのタスクを実行するには、rds_superuser
ロールとしてアクセス許可が必要です。
以下の手順では、Aurora PostgreSQL DB クラスター がカスタム DB クラスター パラメータグループに関連付けられていることを前提としています。カスタム DB クラスターパラメータグループの詳細については、「Amazon Aurora のパラメータグループ」を参照してください。
pglogical 拡張をセットアップするには
AWS Management Console にサインインし、Amazon RDS コンソール (https://console.aws.amazon.com/rds/
) を開きます。 -
ナビゲーションペインで、Aurora PostgreSQL DB クラスターのライターインスタンス を選択します。
-
Aurora PostgreSQL DB クラスターライターインスタンスの [Configuration] (設定) タブを開きます。インスタンスの詳細の中から、パラメータグループのリンクを見つけてください。
-
リンクを選択して、Aurora PostgreSQL DB クラスターに関連するカスタムパラメータを開きます。
-
パラメータ検索フィールドに、
shared_pre
を入力してshared_preload_libraries
パラメータを検索します。 -
プロパティ値にアクセスするには、[Edit parameters] (パラメータの編集) を選択します。
-
[Values] (値) フィールドのリストに
pglogical
を追加します。値のリスト内の項目を区切るにはカンマを使用します。 rds.logical_replication
パラメータを見つけて1
に設定し、論理レプリケーションをオンにします。Aurora PostgreSQL DB クラスターのライターインスタンス を再起動して、変更を有効にします。
インスタンスが使用可能になったら、
psql
(または pgAdmin) を使用して Aurora PostgreSQL DB クラスターのライターインスタンスに接続します。psql --host=
111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=postgres
--password --dbname=labdb
pglogical が初期化されていることを確認するには、次のコマンドを実行します。
SHOW shared_preload_libraries;
shared_preload_libraries -------------------------- rdsutils,pglogical (1 row)
次のように、論理デコードを有効にする設定を確認します。
SHOW wal_level;
wal_level ----------- logical (1 row)
次のように拡張を作成します。
CREATE EXTENSION pglogical;
EXTENSION CREATED
[変更を保存] をクリックします。
Amazon RDS コンソール (https://console.aws.amazon.com/rds/
) を開きます。 データベースリストから Aurora PostgreSQL DB クラスターのライターインスタンス を選択して選択し、アクションメニューから [Reboot] (再起動) を選択します。
pglogical 拡張のセットアップするには
AWS CLI を使用して pglogical を設定するには、次の手順に示すように、modify-db-parameter-group オペレーションを呼び出してカスタムパラメータグループの特定のパラメータを変更します。
次の AWS CLI コマンドを使用して
shared_preload_libraries
パラメータにpglogical
を追加します。aws rds modify-db-parameter-group \ --db-parameter-group-name
custom-param-group-name
\ --parameters "ParameterName=shared_preload_libraries,ParameterValue=pglogical,ApplyMethod=pending-reboot" \ --regionaws-region
次の AWS CLI コマンドを使用して
rds.logical_replication
を1
に設定し、Aurora PostgreSQL DB クラスターのライターインスタンスの論理デコード機能をオンにします。aws rds modify-db-parameter-group \ --db-parameter-group-name
custom-param-group-name
\ --parameters "ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot" \ --regionaws-region
-
次の AWS CLI コマンドを使用して Aurora PostgreSQL DB クラスターのライターインスタンスを再起動し、pglogical ライブラリを初期化します。
aws rds reboot-db-instance \ --db-instance-identifier
writer-instance
\ --regionaws-region
インスタンスが使用可能になったら、
psql
を使用して Aurora PostgreSQL DB クラスターのライターインスタンスに接続します。psql --host=
111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=postgres
--password --dbname=labdb
次のように拡張を作成します。
CREATE EXTENSION pglogical;
EXTENSION CREATED
次の AWS CLI コマンドを使用して、Aurora PostgreSQL DB クラスターのライターインスタンス を再起動します。
aws rds reboot-db-instance \ --db-instance-identifier
writer-instance
\ --regionaws-region
Aurora PostgreSQL DB クラスターに論理レプリケーションを設定する
以下の手順では、2 つの Aurora PostgreSQL DB クラスター間で論理レプリケーションを開始する方法を示しています。これらのステップでは、ソース (パブリッシャー) とターゲット (サブスクライバー) の両方に、pglogical 拡張のセットアップ で説明されているように pglogical
拡張が設定されていることを前提としています。
パブリッシャーノードを作成し、複製するテーブルを定義するには
これらのステップは、別のノードに複製する 1 つ以上のテーブルがあるデータベースを含むライターインスタンスが Aurora PostgreSQL DB クラスターにあることを前提としています。サブスクライバー上のパブリッシャーからテーブル構造を再作成する必要があるため、まず必要に応じてテーブル構造を取得します。そのためには、psq1
メタコマンド \d
を使用してサブスクライバーインスタンスに同じテーブルを作成します。次の手順では、デモンストレーションを目的として、パブリッシャー (ソース) でサンプルテーブルを作成します。tablename
psql
を使用して、サブスクライバーのソースとして使用したいテーブルがあるインスタンスに接続します。psql --host=
source-instance
.aws-region
.rds.amazonaws.com --port=5432 --username=postgres
--password --dbname=labdb
複製する既存のテーブルがない場合は、次のようにサンプルテーブルを作成できます。
次の SQL ステートメントを使用してサンプルテーブルを作成します。
CREATE TABLE docs_lab_table (a int PRIMARY KEY);
次の SQL ステートメントを使用して、生成されたデータをテーブルに入力します。
INSERT INTO docs_lab_table VALUES (generate_series(1,5000));
INSERT 0 5000
次の SQL ステートメントを使用して、テーブルにデータが存在することを確認します。
SELECT count(*) FROM docs_lab_table;
次のように、この Aurora PostgreSQL DB クラスターをパブリッシャーノードとして指定します。
SELECT pglogical.create_node( node_name := '
docs_lab_provider
', dsn := 'host=source-instance
.aws-region
.rds.amazonaws.com port=5432 dbname=labdb
');create_node ------------- 3410995529 (1 row)
複製するテーブルをデフォルトのレプリケーションセットに追加します。レプリケーションセットの詳細については、pglogical ドキュメントの「Replication sets
」(レプリケーションセット) を参照してください。 SELECT pglogical.replication_set_add_table('default', '
docs_lab_table
', 'true', NULL, NULL);replication_set_add_table --------------------------- t (1 row)
パブリッシャーノードの設定が完了しました。これで、パブリッシャーから更新を受け取るようにサブスクライバーノードを設定できます。
サブスクライバーノードを設定し、更新を受信するサブスクリプションを作成するには
これらのステップは、Aurora PostgreSQL DB クラスターが pglogical
拡張機能を使用してセットアップされていることを前提としています。詳細については、「pglogical 拡張のセットアップ」を参照してください。
psql
を使用して、パブリッシャーから更新を受け取るインスタンスに接続します。psql --host=
target-instance
.aws-region
.rds.amazonaws.com --port=5432 --username=postgres
--password --dbname=labdb
-
サブスクライバーの Aurora PostgreSQL DB クラスターで、パブリッシャーに存在するのと同じテーブルを作成します。この例では、テーブルは
docs_lab_table
です。次に示すようにテーブルを作成できます。CREATE TABLE docs_lab_table (a int PRIMARY KEY);
このテーブルが空であることを確認します。
SELECT count(*) FROM docs_lab_table;
count ------- 0 (1 row)
次のように、この Aurora PostgreSQL DB クラスターをサブスクライバーノードとして指定します。
SELECT pglogical.create_node( node_name := '
docs_lab_target
', dsn := 'host=target-instance
.aws-region
.rds.amazonaws.com port=5432 sslmode=require dbname=labdb
user=postgres
password=********
');create_node ------------- 2182738256 (1 row)
サブスクリプションを作成します。
SELECT pglogical.create_subscription( subscription_name := 'docs_lab_subscription', provider_dsn := 'host=
source-instance
.aws-region
.rds.amazonaws.com port=5432 sslmode=require dbname=labdb
user=postgres
password=*******
', replication_sets := ARRAY['default'], synchronize_data := true, forward_origins := '{}' );create_subscription --------------------- 1038357190 (1 row)
このステップを完了すると、パブリッシャーのテーブルのデータが、サブスクライバーのテーブルに作成されます。このことを確認するには、次の SQL クエリを使用します。
SELECT count(*) FROM docs_lab_table;
count ------- 5000 (1 row)
これ以降、パブリッシャーのテーブルに加えられた変更は、サブスクライバーのテーブルにレプリケートされます。
メジャーアップグレード後の論理レプリケーションの再確立
論理レプリケーションのパブリッシャーノードとして設定されている Aurora PostgreSQL DB クラスターのメジャーバージョンアップグレードを実行する前に、アクティブではないものを含め、すべてのレプリケーションスロットを削除する必要があります。パブリッシャーノードからデータベーストランザクションを一時的に迂回させ、レプリケーションスロットを削除し、Aurora PostgreSQL DB クラスターをアップグレードしてから、レプリケーションを再確立して再開することをお勧めします。
レプリケーションスロットはパブリッシャーノードでのみホストされます。論理レプリケーションシナリオの Aurora PostgreSQL サブスクライバーノードには、削除するスロットがありません。Aurora PostgreSQL のメジャーバージョンアップグレードプロセスでは、パブリッシャーノードとは関係なく、サブスクライバーを新しいメジャーバージョンの PostgreSQL にアップグレードできます。ただし、アップグレードプロセスによってレプリケーションプロセスが中断され、パブリッシャーノードとサブスクライバーノード間の WAL データの同期が妨げられます。パブリッシャーまたはサブスクライバー、あるいはその両方をアップグレードした後に、パブリッシャーとサブスクライバー間の論理レプリケーションを再確立する必要があります。以下の手順は、レプリケーションが中断されたことを確認する方法と問題を解決する方法を示しています。
論理レプリケーションが中断されたことの確認
次のように、パブリッシャーノードまたはサブスクライバーノードのいずれかにクエリを実行することで、レプリケーションプロセスが中断されたことを確認できます。
パブリッシャーノードを確認するには
psql
を使用してパブリッシャーノードに接続して、pg_replication_slots
関数をクエリします。active 列の値に注目します。通常はt
(true) が返されます。これは、レプリケーションがアクティブであることを示します。クエリがf
(false) を返す場合は、サブスクライバーへのレプリケーションが停止したことを示します。SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots;
slot_name | plugin | slot_type | active -------------------------------------------+------------------+-----------+-------- pgl_labdb_docs_labcb4fa94_docs_lab3de412c | pglogical_output | logical | f (1 row)
サブスクライバーノードを確認するには
サブスクライバーノードでは、3 つの異なる方法でレプリケーションのステータスを確認できます。
サブスクライバーノードの PostgreSQL ログを調べて、失敗のメッセージを見つけます。ログでは、次に示すように、終了コード 1 を含むメッセージで失敗が識別されます。
2022-07-06 16:17:03 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 14610) exited with exit code 1 2022-07-06 16:19:44 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 21783) exited with exit code 1
pg_replication_origin
関数をクエリします。次のように、psql
を使用してサブスクライバーノード上のデータベースに接続し、pg_replication_origin
関数をクエリします。SELECT * FROM pg_replication_origin;
roident | roname ---------+-------- (0 rows)
結果セットが空の場合は、レプリケーションが中断されたことを意味します。通常、次のような出力が表示されます。
roident | roname ---------+---------------------------------------------------- 1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c (1 row)
次の例に示すように、
pglogical.show_subscription_status
関数をクエリします。SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status();
subscription_name | status | slot_name ---====----------------+--------+------------------------------------- docs_lab_subscription | down | pgl_labdb_docs_labcb4fa94_docs_lab3de412c (1 row)
この出力は、レプリケーションが中断されたことを示しています。そのステータスは
down
です。通常、出力にはステータスがreplicating
として表示されます。
論理レプリケーションプロセスが中断された場合は、次のステップに従ってレプリケーションを再確立できます。
パブリッシャーノードとサブスクライバーノード間の論理レプリケーションを再確立するには
レプリケーションを再確立するには、以下のステップで説明するように、まずサブスクライバーをパブリッシャーノードから切断し、次にサブスクリプションを再確立します。
次のように
psql
を使用してサブスクライバーノードに接続します。psql --host=
222222222222
.aws-region
.rds.amazonaws.com --port=5432 --username=postgres
--password --dbname=labdb
pglogical.alter_subscription_disable
関数を使用してサブスクリプションを非アクティブ化します。SELECT pglogical.alter_subscription_disable('docs_lab_subscription',true);
alter_subscription_disable ---------------------------- t (1 row)
以下のように、
pg_replication_origin
をクエリして、パブリッシャーノードの識別子を取得します。SELECT * FROM pg_replication_origin;
roident | roname ---------+------------------------------------- 1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c (1 row)
前のステップからの応答を
pg_replication_origin_create
コマンドに使用して、サブスクリプションが再確立されたときに使用できる識別子を割り当てます。SELECT pg_replication_origin_create('pgl_labdb_docs_labcb4fa94_docs_lab3de412c');
pg_replication_origin_create ------------------------------ 1 (1 row)
次の例のように、ステータスを
true
にして名前を渡し、サブスクリプションを有効にします。SELECT pglogical.alter_subscription_enable('docs_lab_subscription',true);
alter_subscription_enable --------------------------- t (1 row)
ノードのステータスを確認します。ステータスはこの例のように replicating
として表示されているはずです。
SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status();
subscription_name | status | slot_name -------------------------------+-------------+------------------------------------- docs_lab_subscription | replicating | pgl_labdb_docs_lab98f517b_docs_lab3de412c (1 row)
パブリッシャーノード上のサブスクライバーのレプリケーションスロットのステータスを確認します。スロットの active
列は t
(true) を返し、レプリケーションが再確立されたことを示します。
SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots;
slot_name | plugin | slot_type | active -------------------------------------------+------------------+-----------+-------- pgl_labdb_docs_lab98f517b_docs_lab3de412c | pglogical_output | logical | t (1 row)
Aurora PostgreSQL 用ロジカルレプリケーションスロットの管理
論理レプリケーションシナリオでパブリッシャーノードとして機能している Aurora PostgreSQL DB クラスターのライターインスタンスでメジャーバージョンアップグレードを実行する前に、インスタンスのレプリケーションスロットを削除する必要があります。メジャーバージョンアップグレードの事前確認プロセスにより、スロットが削除されるまでアップグレードを続行できないことが通知されます。
pglogical
拡張を使用して作成されたレプリケーションスロットを特定するには、各データベースにログインしてノードの名前を取得します。サブスクライバーノードにクエリを実行すると、次の例に示すように、パブリッシャーノードとサブスクライバーノードの両方が出力されます。
SELECT * FROM pglogical.node;
node_id | node_name ------------+------------------- 2182738256 | docs_lab_target 3410995529 | docs_lab_provider (2 rows)
次のクエリで、サブスクリプションの詳細を取得できます。
SELECT sub_name,sub_slot_name,sub_target FROM pglogical.subscription;
sub_name | sub_slot_name | sub_target ----------+--------------------------------+------------ docs_lab_subscription | pgl_labdb_docs_labcb4fa94_docs_lab3de412c | 2182738256 (1 row)
これで、次のようにサブスクリプションを削除できます。
SELECT pglogical.drop_subscription(subscription_name := 'docs_lab_subscription');
drop_subscription ------------------- 1 (1 row)
サブスクリプションを削除すると、ノードを削除できます。
SELECT pglogical.drop_node(node_name := 'docs-lab-subscriber');
drop_node ----------- t (1 row)
次のように、ノードが存在しないことを確認できます。
SELECT * FROM pglogical.node;
node_id | node_name ---------+----------- (0 rows)
pglogical 拡張のパラメータリファレンス
表には、pglogical
拡張に関連するパラメータがあります。pglogical.conflict_log_level
や pglogical.conflict_resolution
などのパラメータは、更新の競合を処理するために使用されます。パブリッシャーから変更をサブスクライブしているテーブルにローカルで変更を加えると、競合が発生する可能性があります。これ以外にも、競合は、双方向のレプリケーションや、複数のサブスクライバーが同じパブリッシャーからレプリケートする場合など、さまざまなシナリオで発生する可能性があります。詳細については、「PostgreSQL bi-directional replication using pglogical
パラメータ | 説明 |
---|---|
pglogical.batch_inserts | 可能であれば、バッチ挿入。デフォルトでは設定されていません。オンにする場合は「1」に、オフにする場合は「0」に変更します。 |
pglogical.conflict_log_level | 解決された競合のログ記録に使用するログレベルを設定します。サポートされている文字列値は、debug5、debug4、debug3、debug2、debug1、info、notice、warning、error、log、fatal、panic です。 |
pglogical.conflict_resolution | 競合が解決可能な場合に競合を解決するために使用するメソッドを設定します。サポートされている文字列値は、error、apply_remote、keep_local、last_update_wins、first_update_wins です。 |
pglogical.extra_connection_options | すべてのピアノード接続に追加する接続オプション。 |
pglogical.synchronous_commit | pglogical 固有の同期コミット値 |
pglogical.use_spi | 低レベル API の代わりに SPI (サーバープログラミングインターフェイス) を使用して変更を適用します。オンにする場合は「1」に、オフにする場合は「0」に設定します。SPI の詳細については、PostgreSQL ドキュメントの「サーバープログラミングインターフェイス |