Replication Sets

レプリケーションセットは、 BDRノードがサブスクライブできるテーブルのグループです。レプリケーションセットを使用すると、各ノードが他のノードの正確なコピーである通常の対称マルチマスターよりも複雑なレプリケーショントポロジを作成できます。

すべてのBDRグループは、グループ自分自身と同じ名前のレプリケーションセットを自動的に作成します。このレプリケーションセットはデフォルトのレプリケーションセットであり、すべてのユーザテーブルとDDLレプリケーションに使用され、すべてのノードがサブスクライブされます。つまり、デフォルトでは、すべてのユーザテーブルがすべてのノード間でレプリケートされます。

レプリケーションセットの使用

追加のレプリケーションセットは、create_replication_set()を使用して作成できます。挿入、更新、削除、または切り捨てアクションを含めるかどうかを指定します。既存のテーブルをセットに自動的に追加するオプションがあり、2番目のオプションは作成時にテーブルを自動的に追加するかどうかを定義します

レプリケーションセットに追加または削除するテーブルを手動で定義することもできます。

レプリケーションセットに含まれるテーブルは、ノードがクラスターに参加した後も保持されます。

ノードが参加しても、レプリケーションセットからテーブルを削除できますが、新しいテーブルの追加は再同期オペレーションで行う必要があります。

デフォルトでは、新しく定義されたレプリケーションセットは、 DDLまたはBDRadministrationファンクション呼び出しを複製しません。 replication_set_add_ddl_filterを使用して、複製するコマンドを定義します。

BDRは、すべてのノードでレプリケーションセット定義を作成します。その後、各ノードを定義して、alter_node_replication_setsを使用して各レプリケーションセットをパブリッシュおよび/またはサブスクライブします。

これらの定義を後で変更したり、replicationsetを削除したりするFunctionsがあります。

!!! Note * 選択レプリケーションにデフォルトのレプリケーションセットを使用しないでください。デフォルトのDDLレプリケーションおよび管理ファンクション呼び出しにも使用されるため、クラスター内のBDRノードのデフォルトレプリケーションセットを削除または変更しないでください。

パーティションテーブルの動作

BDRはテーブルパーティションを透過的にサポートします。つまり、パーティションテーブルをレプリケーションセットに追加でき、パーティションに関係する変更がダウンストリームにレプリケートされます。

!!! Note * パーティションテーブルを通じてパーティションがレプリケートされる場合、パーティションで直接実行されるステートメントは、親テーブルで実行されたときにレプリケートされます。例外は、影響を受けるテーブルまたはパーティションのリストを常に複製するTRUNCATEコマンドです。

レプリケーションセットに個々のパーティションを追加することができます。その場合、通常のテーブルのように(ダウンストリームのパーティションと同じ名前のテーブルに)複製されます。パーティショニングロジックを実行する必要がないため、プロバイダとサブスクライバの両方でパーティショニング定義が同じ場合、これにはパフォーマンス上の利点があります。

!!! Note * ルートパーティションテーブルがレプリケーションセットのパートである場合、個々のパーティションのメンバーシップは無視され、そのルートテーブルのメンバーシップのみがアカウントされます。

外部キーの動作

外部キー制約により、参照元テーブルの行が被参照テーブルの行と一致することが保証されます。したがって、参照テーブルがレプリケーションセットのメンバである場合、被参照テーブルも同じレプリケーションセットのメンバである必要があります。

現在のバージョンのBDRは、この条件を自動的に確認または強制しません。したがって、テーブルをレプリケーションセットに追加するときに、外部キーを介して被参照されるすべてのテーブルも追加されるmakeを確認するのは、データベース管理者の責任です。

次のクエリーを使用して、この要件を満たさないすべての外部キーとレプリケーションセットをリストできます。つまり、参照テーブルはレプリケーションセットのメンバですが、参照テーブルはそうではありません。

SELECT t1.relname,
   *      t1.nspname,
   *      fk.conname,
   *      t1.set_name
   * FROM bdr.tables AS t1
   * JOIN pg_catalog.pg_constraint AS fk
   *   ON fk.conrelid = t1.relid
   *  AND fk.contype = 'f'
 WHERE NOT EXISTS (
   * SELECT *
   *   FROM bdr.tables AS t2
   *  WHERE t2.relid = fk.confrelid
   *    AND t2.set_name = t1.set_name
);

このクエリーの出力は次のようになります。

 relname | nspname |  conname  | set_name
---------+---------+-----------+----------
 t2      | public  | t2_x_fkey | s2
(1 row)

つまり、テーブルt2はレプリケーションセットs2のメンバですが、外部キーt2_x_fkeyによって被参照されるテーブルはそうではありません。

!!! Note * TRUNCATE CASCADEコマンドは、コマンドを複製する前にレプリケーションセットのメンバーシップをアカウントします。

TRUNCATE table1 CASCADE;

これは、レプリケーションセットのみの一部であるすべてのテーブルでカスケードなしのTRUNCATEになります。

TRUNCATE table1, referencing_table1, referencing_table2 ...

レプリケーションセットの管理

レプリケーションセットの管理。

bdr.alter_node_replication_setsを例外て、次の関数はDDLと見なされるため、 DDLレプリケーションとグローバルロックが現在アクティブになっている場合は適用されます。 [DDL Replication]を参照してください。

bdr.create_replication_set

このファンクションは、レプリケーションセットを作成します。

このコマンドの複製は、 DDLフィルタリング設定をDDLレプリケーション構成の影響を受けます。

あらすじ

bdr.create_replication_set(set_name name,
   *                          replicate_insert boolean DEFAULT true,
   *                          replicate_update boolean DEFAULT true,
   *                          replicate_delete boolean DEFAULT true,
   *                          replicate_truncate boolean DEFAULT true,
   *                          autoadd_tables boolean DEFAULT false,
   *                          autoadd_existing boolean DEFAULT true)

パラメーター

  • set_name-新しいレプリケーションセットの名前。 BDR全体で一意である必要があります グループ

  • replicate_insert-このテーブルに挿入するかどうかを示します レプリケーションセットを複製する必要があります

  • replicate_update-これのテーブルの更新かどうかを示します レプリケーションセットを複製する必要があります

  • replicate_delete-この中のテーブルから削除するかどうかを示します レプリケーションセットを複製する必要があります

  • replicate_truncate-この中のテーブルの切り捨てかどうかを示します レプリケーションセットを複製する必要があります

  • autoadd_tables-新しく作成された(将来の)テーブルを作成するかどうかを示します このレプリケーションセットに追加されました

  • autoadd_existing-すべての既存のユーザテーブルを このレプリケーションセットに追加されました。これは、autoadd_tablesが trueに設定

注

デフォルトでは、新しいレプリケーションセットはDDLまたはBDR管理関数呼び出しを複製しません。レプリケーションセットのDDLレプリケーションのセットアップ方法については、以下のddl filtersを参照してください。すべてのDDLおよびadminfunction呼び出しをレプリケートするデフォルトグループレプリケーションセット用の既存のDDLフィルターセットがあります。これは、グループの作成時に作成されますが、 BDRグループのデフォルトレプリケーションセットがreplicateDDLまたはBDRに望ましくない場合はドロップできます管理ファンクション呼び出し。

このファンクションは、DDLステートメントと同じレプリケーションメカニズムを使用します。つまり、レプリケーションはddl filters構成の影響を受けます。

ファンクションはDDLグローバルロックを取得します。

このファンクションはトランザクションです-効果はトランザクションのROLLBACKでロールバックでき、変更は現在のトランザクションに可視されます。

bdr.alter_replication_set

このファンクションは、既存のレプリケーションセットのオプションを変更します。

このコマンドの複製は、 DDLフィルタリング設定を含むDDLレプリケーション構成の影響を受けます。

あらすじ

bdr.alter_replication_set(set_name name,
   *                         replicate_insert boolean DEFAULT NULL,
   *                         replicate_update boolean DEFAULT NULL,
   *                         replicate_delete boolean DEFAULT NULL,
   *                         replicate_truncate boolean DEFAULT NULL,
   *                         autoadd_tables boolean DEFAULT NULL)

パラメーター

  • set_name-既存のレプリケーションセットの名前

  • replicate_insert-このテーブルに挿入するかどうかを示します レプリケーションセットを複製する必要があります

  • replicate_update-これのテーブルの更新かどうかを示します レプリケーションセットを複製する必要があります

  • replicate_delete-この中のテーブルから削除するかどうかを示します レプリケーションセットを複製する必要があります

  • replicate_truncate-この中のテーブルの切り捨てかどうかを示します レプリケーションセットを複製する必要があります

  • autoadd_tables-新しく作成された(将来の)テーブルが必要かどうかを示します このレプリケーションセットに追加されました

NULL(デフォルト)に設定されたオプションは、以前と同じままです。

注

このファンクションは、DDLステートメントと同じレプリケーションメカニズムを使用します。つまり、レプリケーションはddl filters構成の影響を受けます。

ファンクションはDDLグローバルロックを取得します。

このファンクションはトランザクションです-トランザクションのROLLBACKで効果をロールバックでき、変更は現在のトランザクションに可視されます。

bdr.drop_replication_set

このファンクションは、既存のレプリケーションセットを削除します。

このコマンドの複製は、 DDLフィルタリング設定を含むDDLレプリケーション構成の影響を受けます。

あらすじ

bdr.drop_replication_set(set_name name)

パラメーター

  • set_name-既存のレプリケーションセットの名前

注

このファンクションは、DDLステートメントと同じレプリケーションメカニズムを使用します。つまり、レプリケーションはddl filters構成の影響を受けます。

ファンクションはDDLグローバルロックを取得します。

このファンクションはトランザクションです-トランザクションのROLLBACKで効果をロールバックでき、変更は現在のトランザクションに可視されます。

!!! Warning * 少なくとも別のノードで使用されているレプリケーションセットを削除しないでください。削除すると、そのノードでレプリケーションが停止します。これが発生した場合は、影響を受けるノードをそのレプリケーションセットからサブスクライブ解除してください。同じ理由で、進行中の結合オペレーションがあり、結合されているノードがそのレプリケーションセットのメンバである場合、レプリケーションセットを削除しないでください。レプリケーションセットメンバーシップは、結合の開始時にのみチェックされます。これは、レプリケーションセットの使用に関する情報が各ノードに対してローカルであり、グループに参加する前にノードで構成できるためです。

以下で説明するalter_node_replication_setsを使用して、ノードのレプリケーションセットサブスクリプションを管理できます。

bdr.alter_node_replication_sets

このファンクションは、ノードが発行してサブスクライブするレプリケーションセットを変更します。

あらすじ

bdr.alter_node_replication_sets(node_name name,
   *                               set_names text[])

パラメーター

  • node_name-変更するノード。現在、ローカルノードである必要があります

  • set_names-指定された場所に複製するレプリケーションセットの配列 ノード;空の配列では、グループのデフォルトレプリケーションセットが使用されます

注

このファンクションはローカルノードでのみ実行され、いかなる方法でも複製されません。

このファンクションは、ノードが参加する前に実行されるように設計されているため、リストされているレプリケーションセットの存在はチェックされません。エラーを回避するために、レプリケーションセット名を正しく指定するよう注意してください。

これにより、BDRグループのパートであるノードだけでなく、まだグループに参加していないノードでファンクションを呼び出して、結合中に同期されるデータを制限できます。ただし、レプリケーションセットの設定に関係なく、スキーマは常に完全に同期されていることにノートしてください。つまり、レプリケーションセットで指定されたテーブルだけでなく、すべてのテーブルがコピーされます。不要なテーブルは、bdr.tablesカタログテーブルを参照して削除できます。これらは、 BDRの後のバージョンで自動的に削除される場合があります。これは、ddl filters構成がDDLのレプリケーションを妨げる場合でも、現在当てはまります。

これらのノードからこのファンクションが実行されるノードへの変更を実際に複製するために、この呼び出し後にノードがサブスクライブするレプリケーションセットは、他のノードによって公開される必要があります。

レプリケーションセットメンバーシップ

テーブルは、1つまたはマルチプルのレプリケーションセットに追加および削除できます。これは、これらのテーブルの変更のレプリケーション(DML)にのみ影響し、スキーマの変更(DDL)はDDLレプリケーションセットフィルターによって処理されます(以下のDDLレプリケーションフィルタリングを参照)。

レプリケーションは、ノードレプリケーションセットの構成と組み合わせてレプリケーションセットのテーブルメンバーシップを使用して、どのアクションをどのノードにレプリケートするかを決定します。決定は、すべてのメンバーシップとレプリケーションセットオプションのユニオンを使用して行われます。つまり、テーブルがINSERTのみをレプリケートレプリケーションセットAのメンバーであり、UPDATEのみをレプリケーションセットBの場合、ターゲットノードもレプリケーションセットAとBの両方にサブスクライブすると、INSERTとUPDATEの両方がレプリケートされます。

bdr.replication_set_add_table

このファンクションは、レプリケーションセットにテーブルを追加します。

これにより、レプリケーションセットにテーブルが追加され、この時点から(またはトランザクションコミットではなく)変更のレプリケーションがスタートされます。テーブルにノード上にある既存のデータは同期されません。

このコマンドの複製は、 DDLフィルタリング設定を含むDDLレプリケーション構成の影響を受けます。

あらすじ

bdr.replication_set_add_table(relation regclass,
   *                             set_name name DEFAULT NULL,
   *                             columns text[] DEFAULT NULL,
   *                             row_filter text DEFAULT NULL)

パラメーター

  • relation-テーブルの名前またはOID

  • set_name-レプリケーションセットの名前。 NULL(デフォルト)の場合、 BDR グループのデフォルトレプリケーションセットが使用されます

  • columns-将来の使用のために予約(現在は何も行わず、NULLでなければなりません)

  • row_filter-複製された行のフィルタリングに使用されるSQL式。 この式が定義されていない場合(つまり、NULL-デフォルト)、すべての行が送信されます

row_filterは、ブール値を生成する式を指定します。NULLを使用します。TrueまたはUnknownと評価される式は、行を複製します。 False値は行を複製しません。式にはサブクエリを含めることはできず、複製される現在の行の列以外の変数を参照することもできません。 systemcolumnsは被参照できません。

row_filterは、ターゲットノードではなく、オリジンノードで実行されます。これにより、この特定のテーブルのレプリケーションに追加のCPUオーバーヘッドがかかりますが、フィルター処理された行のデータ送信が完全に回避されるため、ネットワーク帯域幅が削減され、ターゲットノードのオーバーヘッドが適用されます。

row_filterは、特定のテーブルのTRUNCATEコマンドを削除しません。TRUNCATEコマンドは、レプリケーションセットレベルでフィルタリングできます。先に。

テーブルの一部の列だけを複製することは可能です。edReplicating between nodes with differences。

注

このファンクションは、DDLステートメントと同じレプリケーションメカニズムを使用します。つまり、レプリケーションはddl filters構成の影響を受けます。

ファンクションは、row_filterがNULLでない場合、レプリケーションセットに追加されているリレーションでDMLグローバルロックを取得します。それ以外の場合は、DDLグローバルロックのみを取得します。

このファンクションはトランザクションです-効果はトランザクションのROLLBACKでロールバックでき、変更は現在のトランザクションに可視されます。

bdr.replication_set_remove_table

このファンクションは、レプリケーションセットからテーブルを削除します。

このコマンドの複製は、 DDLフィルタリング設定を含むDDLレプリケーション構成の影響を受けます。

あらすじ

bdr.replication_set_remove_table(relation regclass,
   *                                set_name name DEFAULT NULL)

パラメーター

  • relation-テーブルの名前またはOID

  • set_name-レプリケーションセットの名前。 NULL(デフォルト)の場合、 BDR グループのデフォルトレプリケーションセットが使用されます

注

このファンクションは、DDLステートメントと同じレプリケーションメカニズムを使用します。つまり、レプリケーションはddl filters構成の影響を受けます。

ファンクションはDDLグローバルロックを取得します。

このファンクションはトランザクションです-効果はトランザクションのROLLBACKでロールバックでき、変更は現在のトランザクションに可視されます。

複製セットのリスト

既存のレプリケーションセットは、次のクエリーでリストできます。

SELECT set_name
FROM bdr.replication_sets;

このクエリーを使用して、特定の複製セット内のすべてのテーブルをリストできます。

SELECT nspname, relname
FROM bdr.tables
WHERE set_name = 'myrepset';

上記のセクション外部キーの動作で、参照テーブルが被参照テーブルと同じレプリケーションセットに含まれていないすべての外部キーをリストするクエリをレポートします。

次のSQLを使用して、現在のノードがパブリッシュおよびサブスクライブするレプリケーションセットを表示します。

SELECT s.node_id,
   *       s.node_name,
   *       COALESCE(
   *               i.pub_repsets, s.pub_repsets
   *       ) AS pub_repsets,
   *       COALESCE(
   *               i.sub_repsets, s.sub_repsets
   *       ) AS sub_repsets
FROM bdr.local_node_summary s
INNER JOIN bdr.node_local_info i ON i.node_id = s.node_id;

これにより、次のような出力が生成されます。

   * node_id   | node_name |    pub_repsets     |   sub_repsets
------------+-----------+----------------------------------------
 1834550102 | s01db01   | {bdrglobal,bdrs01} | {bdrglobal,bdrs01}
(1 row)

クラスター内のすべてのノードに対して同じクエリーを実行し、どのレプリケーションセットがすべてのノードに同時に関連付けられているかを取得するには、次のクエリーを使用できます。

WITH node_repsets AS (
   * SELECT jsonb_array_elements(
   *   bdr.run_on_all_nodes($$
   *       SELECT s.node_id,
   *       s.node_name,
   *       COALESCE(
   *               i.pub_repsets, s.pub_repsets
   *       ) AS pub_repsets,
   *       COALESCE(
   *               i.sub_repsets, s.sub_repsets
   *       ) AS sub_repsets
   * FROM bdr.local_node_summary s
   * INNER JOIN bdr.node_local_info i
   * ON i.node_id = s.node_id;
   *   $$)::jsonb
   * ) AS j
)
SELECT j->'response'->'command_tuples'->0->>'node_id' AS node_id,
   *      j->'response'->'command_tuples'->0->>'node_name' AS node_name,
   *      j->'response'->'command_tuples'->0->>'pub_repsets' AS pub_repsets,
   *      j->'response'->'command_tuples'->0->>'sub_repsets' AS sub_repsets
FROM node_repsets;;

これは、例、表示されます:

   * node_id   | node_name |    pub_repsets     |    sub_repsets
------------+-----------+----------------------------------------
 933864801  | s02db01   | {bdrglobal,bdrs02} | {bdrglobal,bdrs02}
 1834550102 | s01db01   | {bdrglobal,bdrs01} | {bdrglobal,bdrs01}
 3898940082 | s01db02   | {bdrglobal,bdrs01} | {bdrglobal,bdrs01}
 1102086297 | s02db02   | {bdrglobal,bdrs02} | {bdrglobal,bdrs02}
(4 rows)

DDLレプリケーションフィルタリング

デフォルトでは、サポートされているすべてのDDLのレプリケーションは、デフォルトのBDRgroupレプリケーションセットを介して行われます。これは、 BDRグループと同じ名前のDDLフィルターが存在することで実現されます。これは、 BDRグループの作成時にデフォルトのBDRgroupレプリケーションセットに自動的に追加されます。

上記は、すべての既存のレプリケーションセットのDDLレプリケーションフィルターを変更することで調整できます。これらのフィルターは、レプリケーションセットのテーブルメンバーシップに依存しません。データの変更と同様、各DDLステートメントは、複数のレプリケーションセットのマルチプルのフィルターと一致する場合でも、1回だけレプリケートされます。

次のクエリーを使用して、既存のDDLフィルターをリストできます。これは、コマンドタグとロール名前に適用される正規表現を各フィルターに表示します。

SELECT * FROM bdr.ddl_replication;

次の関数を使用して、 DDLフィルターを操作できます。これらはDDLと見なされるため、DDLreplicationおよびグローバルロックのサブジェクトになることに注意してください。

bdr.replication_set_add_ddl_filter

このファンクションは、レプリケーションセットにDDLフィルターを追加します。

指定されたフィルターに一致するDDLは、そのセットにサブスクライブされているノードに複製されます。これは、 BDR管理機能のレプリケーションにも影響します。

これはどのノードでもDDLの実行を妨げるものではなく、 DDLが他のノードに複製されるかどうかのみを変更することに注意してください。したがって、2つのノードの間にすべてのインデックスコマンドを除外するレプリケーションフィルターがある場合、各ノードに直接接続し、そのノードで目的のDDLを実行することにより、インデックスコマンドを自由に実行できます。

DDLフィルターは、command_tagおよびrole_nameを指定して、一部のDDLステートメントのみの複製を許可できます。 command_tagは、通常のPostgreSQLコマンドでEVENT TRIGGERsが使用するものと同じです。典型的な例は、ロジカルスタンバイ上の追加のインデックスコマンドが他のすべてのノードに複製されるのを防ぐフィルターを作成することです。

BDR管理関数の使用は、修飾されたファンクション名前にマッチングするタグ名を使用してフィルター処理できます(例、 bdr.replication_set_add_tableは同じ名前のファンクションのコマンドタグになります)。例、これにより、bdr.*を使用してすべてのBDR関数をフィルタリングできます。

role_nameは、コマンドを実行している現在のロールとのマッチングに使用されます。 command_tagとrole_nameは両方とも、大文字と小文字を区別する正規表現として評価されます。

あらすじ

bdr.replication_set_add_ddl_filter(set_name name,
   *                                  ddl_filter_name text,
   *                                  command_tag text,
   *                                  role_name text DEFAULT NULL)

パラメーター

  • set_name-レプリケーションセットの名前。 NULLの場合、 BDR グループのデフォルトレプリケーションセットが使用されます

  • ddl_filter_name- DDLフィルターの名前。これは全体で一意でなければなりません BDRグループ全体

  • command_tag-マッチングコマンドタグの正規表現。 NULLは すべてにマッチ

  • role_name-マッチングロール名前の正規表現。 NULLは すべての役割にマッチ

注

このファンクションは、DDLステートメントと同じレプリケーションメカニズムを使用します。つまり、レプリケーションはddl filters構成の影響を受けます。ノート-これは、ddlfilter構成への変更のレプリケーションが既存のddlフィルター構成の影響を受けることを意味します!

ファンクションはDDLグローバルロックを取得します。

このファンクションはトランザクションです-トランザクションのROLLBACKで効果をロールバックでき、変更は現在のトランザクションに可視されます。

定義されているレプリケーションフィルターをビューするには、bdr.ddl_replicationビューを使用します。

例

BDR管理機能のみを含めるには、次のようなフィルターを定義します。

SELECT bdr.replication_set_add_ddl_filter('mygroup', 'mygroup_admin', $$bdr\..*$$);

インデックスDDL以外のすべてを除外するには:

SELECT bdr.replication_set_add_ddl_filter('mygroup', 'index_filter',
   *        '^(?!(CREATE INDEX|DROP INDEX|ALTER INDEX)).*');

テーブルとインデックスに対するすべての操作を含め、他のすべてを除外するには、テーブル用とインデックス用の2つのフィルターを追加します。これは、複数のフィルターが許可されているすべてのDDLコマンドのユニオンを提供することを示しています。

SELECT bdr.replication_set_add_ddl_filter('bdrgroup','index_filter', '^((?!INDEX).)*$');
SELECT bdr.replication_set_add_ddl_filter('bdrgroup','table_filter', '^((?!TABLE).)*$');

bdr.replication_set_remove_ddl_filter

このファンクションは、レプリケーションセットからDDLフィルターを削除します。

このコマンドの複製は、 DDLフィルタリング設定自体を含むDDLレプリケーション構成の影響を受けます!

あらすじ

bdr.replication_set_remove_ddl_filter(set_name name,
   *                                     ddl_filter_name text)

パラメーター

  • set_name-レプリケーションセットの名前。 NULLの場合、 BDR グループのデフォルトレプリケーションセットが使用されます

  • ddl_filter_name-削除するDDLフィルターの名前

注

このファンクションは、DDLステートメントと同じレプリケーションメカニズムを使用します。これは、レプリケーションがddl filters構成の影響を受けることを意味します。これは、 DDLフィルター構成への変更のレプリケーションが既存のDDLフィルター構成の影響を受けることを意味することに注意してください。

ファンクションはDDLグローバルロックを取得します。

このファンクションはトランザクションです-トランザクションのROLLBACKで効果をロールバックでき、変更は現在のトランザクションに可視されます。