Replication sets

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

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

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

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

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

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

ノードが参加したら、レプリケーションセットからテーブルを削除できますが、再同期操作を使用して新しいテーブルを追加する必要があります。

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

BDRは、すべてのノードに複製セット定義を作成します。次に、 alter_node_replication_sets を使用して、各レプリケーションセットをパブリッシュまたはサブスクライブするように各ノードを定義できます。

関数を使用して、これらの定義を後で変更したり、複製セットを削除したりできます。

注釈

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

パーティション分割されたテーブルの動作

BDRはパーティションテーブルを透過的にサポートします。つまり、パーティションテーブルをレプリケーションセットに追加できます。いずれかのパーティションを含む変更は、ダウンストリームに複製されます。

注釈

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

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

注釈

ルートパーティションテーブルがレプリケーションセットの一部である場合、個々のパーティションのメンバーシップは無視されます。そのルートテーブルのメンバーシップのみが考慮されます。

外部キーの動作

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

BDRの現在のバージョンは、この条件を自動的にチェックまたは適用しません。レプリケーションセットにテーブルを追加する場合、データベース管理者は外部キーによって参照されるすべてのテーブルも追加されていることを確認する必要があります。

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

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 によって参照されるテーブルはそうではないことを意味します。

TRUNCATE CASCADE コマンドは、コマンドを複製する前に複製セットのメンバーシップを考慮します。例:

TRUNCATE table1 CASCADE;

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

TRUNCATE table1, referencing_table1, referencing_table2 ...

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

複製セットの管理。

bdr.alter_node_replication_sets を除き、以下の機能をDDL とみなします。 DDLレプリケーションとグローバルロックが現在アクティブな場合、それらに適用されます。

DMLおよびDDLレプリケーション を参照してください。

bdr.create_replication_set

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

このコマンドのレプリケーションは、 DDLDDL構成の影響を受けます。

概要

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および管理ファンクション呼び出しを複製するデフォルトのグループレプリケーションセット用に、既存のDDLフィルターが設定されています。グループの作成時に作成されますが、

BDRグループのデフォルトのレプリケーションセットでDDLまたは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 で効果をロールバックできます。変更は現在のトランザクションに表示されます。

警告

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

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 値は行を複製しません。式にサブクエリを含めたり、レプリケートされる現在の行の列以外の変数を参照したりすることはできません。システム列を参照することはできません。

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

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

テーブルの一部の列のみを複製できます。 違いのあるノード間の複製 を参照してください。

注意事項

このファンクションは、 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;

:ref:`外部キーの動作<外部キーの動作>`

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

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

SELECT node_id,
       node_name,
       COALESCE(
               pub_repsets, pub_repsets
       ) AS pub_repsets,
       COALESCE(
               sub_repsets, sub_repsets
       ) AS sub_repsets
  FROM bdr.local_node_summary;

このコードは次のような出力を生成します。

  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
          node_id,
          node_name,
          COALESCE(
                pub_repsets, pub_repsets
          ) AS pub_repsets,
          COALESCE(
                sub_repsets, sub_repsets
          ) AS sub_repsets
        FROM bdr.local_node_summary;
    $$)::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のレプリケーションは、デフォルトのBDRグループレプリケーションセットを介して発生します。これは、 BDRグループと同じ名前のDDLフィルターで実現されます。このフィルターは、 BDRグループの作成時にデフォルトのBDRグループレプリケーションセットに追加されます。

これを調整するには、既存のすべてのレプリケーションセットのDDLレプリケーションフィルターを変更します。これらのフィルターは、レプリケーションセットのテーブルメンバーシップとは無関係です。データの変更と同様に、各DDLステートメントは、複数のレプリケーションセットの複数のフィルターに一致した場合でも、1回のみレプリケートされます。

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

SELECT * FROM bdr.ddl_replication;

次の関数を使用して、 DDLフィルターを操作できます。これらはDDL と見なされるため、 DDLレプリケーションとグローバルロックの対象となります。

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,
                                   base_relation_name text DEFAULT NULL,
                                   query_match text DEFAULT NULL,
                                   exclusive boolean DEFAULT FALSE)

パラメーター

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

  • ddl_filter_name — DDLフィルターの名前。これはBDRグループ全体で一意である必要があります

  • command_tag —コマンドタグを一致させるための正規表現。 NULLはすべてに一致することを意味します

  • role_name —ロール名を一致させるための正規表現。 NULLはすべてのロールに一致することを意味します

  • base_relation_name —将来の使用のために予約されています。NULLである必要があります

  • query_match —クエリを照合するための正規表現。 NULLはすべてのクエリに一致することを意味します

  • exclusive — trueの場合、他の一致フィルターは考慮されません(つまり、排他フィルターのみが適用されます)。複数の排他フィルターが一致すると、エラーがスローされます。これは、メインの複製セットでデフォルトの複製を維持しながら、特定のコマンドを特定の複製セットにルーティングする場合に役立ちます。

注意事項

このファンクションは、 DDL ステートメントと同じ複製メカニズムを使用します。これは、レプリケーションが ddl filters 構成の影響を受けることを意味します。これは、ddlフィルター構成への変更のレプリケーションが既存の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 つのフィルターを追加します。1 つはテーブル用、もう 1 つはインデックス用です。これは、複数のフィルターが許可されたすべての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 で効果をロールバックできます。変更は現在のトランザクションに表示されます。