BDR Support

LiveCompareは、 BDRノードおよび非BDRノードに対して使用できます。

logical_replication_mode = bdrを設定makeと、比較するすべてのデータベースが同じBDRクラスターに属しているとツールが想定します。次に、ノード名を接続として指定し、レプリケーションセットを指定してテーブルをフィルタリングできます。

例、 BDRクラスター内の任意のノードに接続できるとします。これをInitial Connectionと呼びましょう。最初にこのノードに接続することにより、LiveCompareはBDRメタデータを確認し、他のすべてのノードから接続情報を取得できます。

ここで、3つのBDRノードを比較することを検討してください。 LiveCompareはInitial Connectionから始まるノードに接続できるため、dsnやデータ接続の接続情報を定義する必要はありません。 node_nameを定義するだけです。 LiveCompareは、そのノードの接続情報についてBDRメタデータを検索し、ノードに接続します。

ノートがBDRメタデータを取得して他のすべてのノードに接続できるようにするには、LiveCompareがBDRビューbdr.node_summary、フィールドinterface_connstrから同じDSNを使用してそれらに接続できる必要があることに注意してください。この場合、postgres ユーザとして、Initial Connectionと同じマシンでLiveCompareを実行することをお勧めします。それが不可能な場合は、すべてのデータ接続でdsn属性を定義してください。

レプリケーションセットをテーブルフィルターとして指定することもできます。 LiveCompareは、 BDRメタデータを使用して、replication_sets設定で定義したレプリケーションセットに属するテーブルのみを考慮して、テーブルリストを作成します。

例、.iniファイルを作成して、3つのBDRノードを比較できます。

[General Settings]
logical_replication_mode = bdr
max_parallel_workers = 4

[Initial Connection]
dsn = port=5432 dbname=live user=postgres

[Node1 Connection]
node_name = node1

[Node2 Connection]
node_name = node2

[Node3 Connection]
node_name = node3

[Output Connection]
dsn = port=5432 dbname=liveoutput user=postgres

[Table Filter]
replication_sets = set_name = bdrgroup

LiveCompareにBDRクラスター内のすべてのアクティブノードを比較するように指示することもできます。そのためには、次のようにします。

  • General Settingsで、all_bdr_nodes = onを有効にします。

  • Initial Connectionを指定します。

  • 追加のデータ接続は必要ありません。

例:

[General Settings]
logical_replication_mode = bdr
max_parallel_workers = 4
all_bdr_nodes = on

[Initial Connection]
dsn = port=5432 dbname=live user=postgres

[Output Connection]
dsn = port=5432 dbname=liveoutput user=postgres

[Table Filter]
replication_sets = set_name = bdrgroup

all_bdr_nodes = onの場合、LiveCompareはInitial Connectionを使用してすべてのBDRノードのリストをフェッチします。追加のデータ接続は必要ありません。設定されている場合、データ接続のリストに追加されます。例、移行プロジェクトで役立つ単一のPostgres接続に対してBDRクラスター全体を比較することができます。

[General Settings]
logical_replication_mode = bdr
max_parallel_workers = 4
all_bdr_nodes = on

[Initial Connection]
dsn = port=5432 dbname=live user=postgres

[Old Connection]
dsn = host=oldpg port=5432 dbname=live user=postgres

[Output Connection]
dsn = port=5432 dbname=liveoutput user=postgres

[Table Filter]
replication_sets = set_name = bdrgroup

設定node_nameおよびreplication_setsは、次のテクノロジーでサポートされています。

BDR 1、2、3、および4。 - pglogical 2および3。

BDRの代わりにノートメタデータフェッチを有効にするには、logical_replication_mode = bdrではなくlogical_replication_mode = pglogicalを設定するだけです。

BDR監視ノード

BDRのレプリケーションセットを使用して、特定のテーブルをBDRレプリケーションに含めるように構成し、テーブルが属するレプリケーションセットにサブスクライブするようにノードを構成することにより、そのようなテーブルからデータを受信するノードを指定することもできます。これにより、 BDRシャーディングやBDRウィットネスノードの使用など、さまざまなアーキテクチャが可能になります。

BDRウィットネスは、他のノードからDMLを複製しない通常のBDRノードです。証人の目的は、ラフトコンセンサス投票で定足数を提供することです( BDR証人ノードの詳細については、 BDRの文書を参照してください)。レプリケーションセットの構成方法に応じて、WitnessはDDLをレプリケートする場合とレプリケートしない場合があります。つまり、 BDR証人には次の2つのタイプがあります。

  • データもテーブルもない完全に空のノード。または

  • 他のノードからDDLを複製するノード。したがって、空のテーブルがあります。

最初のケースでは、 BDR Witnessが比較に含まれていても(手動で[Connections]の下で、またはall_bdr_nodes = onを使用して)、Witnessにはテーブルがないため、次のメッセージがログに記録されます。

Table public.tbl does not exist on connection node1

一方、2番目のケースでは、 BDRウィットネスにテーブルが存在します。しかし、証人に欠けているデータを分岐としてレポートするのは正しくありません。そのため、各テーブルについて、LiveCompareは比較に含まれる各ノードに関する次の情報をチェックします。

  • ノードがサブスクライブレプリケーションセット。

  • テーブルが関連付けられているレプリケーションセット。

  • レプリケーションセット(存在する場合)フィルターreplication_setsで定義されたユーザ Table Filterの下。

レプリケーションセットの3つのリストすべての積部分が空の場合( BDRウィットネスの場合)、LiveCompareはこれをログに記録します。

Table public.tbl is not subscribed on connection node1

どちらの場合も、その特定のテーブルの比較は、テーブルが存在するノードで行われ、テーブルはレプリケーションセットの構成に従ってレプリケートされます。

BDRクラスターの違い

LiveCompareはローカルノードのみに変更を加えます。修正の変更が他のノードに複製されないことが重要です。

logical_replication_mode = bdrの場合、LiveCompareは最初にbdr_local_only_originというレプリケーションオリジンが既に存在するかどうかを確認します(レプリケーションオリジンの名前は、difference_fix_replication_originの設定を調整することで構成できます)。 bdr_local_only_originというレプリケーションオリジンがまだ存在しない場合、LiveCompareはすべてのBDR接続でそれを作成します。

重要 : BDR 3.6.18では、ローカルのみのトランザクションの適用に使用される新しい事前作成されたbdr_local_only_originレプリケーションオリジンが導入されていることにノートしてください。したがって、LiveCompareがBDR 3.6.18に接続されている場合、このレプリケーションオリジンは作成されません。

LiveCompareは、以下を考慮して適用スクリプトを生成します。

  • レプリケーションオリジンを使用するように現在のトランザクションを設定します bdr_local_only_origin。したがって、実行されるDMLにはxminが関連付けられます。 bdr_local_only_origin;

  • 現在のトランザクションの日時を過去に設定します。 BDRは、データベース、LiveCompare DMLで実行されている実際のDMLと競合します。 常に対立を失います。

LiveCompare修正スクリプトをBDRノードに適用した後、次のクエリーを使用して、LiveCompareによって挿入または更新された行を正確に取得できます(mytableを任意のテーブルの名前に置き換えます)。

with lc_origin as (
    select roident
    from pg_replication_origin
    where roname = bdr_local_only_origin
)
select t.*
from mytable t
inner join lc_origin r
on r.roident = bdr.pg_xact_origin(t.xmin);

(削除された行は表示されなくなり可視。)

LiveCompareがメタデータを適切にフェッチオーダーには、少なくともbdr_superuser権限を持つPostgreSQLユーザが必要であることにノートしてください。

PostgreSQLユーザがbdr_superuserまたはPostgreSQLのスーパーユーザ権限を持っている場合、レプリケーション起点元に関する上記のすべての手順は出力スクリプトにのみ適用されます。それ以外の場合、LiveCompareは、レプリケーションオリジンを関連付けずに修正を生成します(SET LOCAL bdr.xact_replication = offを使用すると、トランザクションレプリケーションは引き続き無効になります)。ただし、DMLスクリプトを適用する場合は、レプリケーションオリジンを使用することをお勧めします。そうしないと、競合の解決に関してLiveCompareが通常のユーザアプリケーションと同じ優先順位を持つことになります。また、修正に関連付けられたレプリケーションオリジンがないため、LiveCompareによって修正されたすべての行をリストする上記のクエリーは使用できません。

BDR 3.6.18とBDR 3.7.0の間では、次の機能が使用されます。

  • bdr.difference_fix_origin_create():LiveCompareによって実行され、 difference_fix_replication_originで指定されたレプリケーションオリジン(デフォルトで このレプリケーションオリジンが存在しない場合、bdr_local_only_origin)に設定されます。

  • bdr.difference_fix_session_setup():生成されたDMLスクリプトに含まれるため、 トランザクションは、で指定されたレプリケーションオリジンに関連付けられています difference_fix_replication_origin;

  • bdr.difference_fix_xact_set_avoid_conflict():生成されたDMLに含まれます スクリプトにより、トランザクションは過去(2010-01-01)に設定されるため、修正 LiveCompareによって適用されたトランザクションは、競合がある場合、常に失われます。

上記の関数には、 PostgreSQLスーパーユーザではなくbdr_superuserが必要です。 BDR 3.7.0以降、これらの機能は廃止されました。 LiveCompareは、 PostgreSQLスーパーユーザとして実行している場合、代わりに次の関数を使用して上記と同じアクションを実行します。

  • pg_replication_origin_create(origin_name);

  • pg_replication_origin_session_setup();

  • pg_replication_origin_xact_setup()。

PostgreSQLスーパーユーザが使用されていない場合、LiveCompareは生成されたDMLトランザクションに以下のみを含めます。

SET LOCAL bdr.xact_replication = off;

BDRの競合

LiveCompareには、conflictsという実行モードがあります。この実行モードは、 BDRクラスターに固有です。 BDR 3.6、 BDR 3.7、またはBDR 4クラスターでのみ機能します。

compareモードはテーブルのすべてのコンテンツを全体として比較するために使用されますが、conflictsモードは、 BDR 3.6の場合はbdr.apply_logに、 BDRの場合はbdr.conflict_historyに登録されている既存の競合に関連するタプル/テーブルにのみフォーカスします3.7およびBDR 4。

とはいえ、conflicts実行モードは、特定のテーブルから特定のタプルを検査するだけなので、compareモードよりもはるかに高速に実行されると予想されます。同時に、同じ理由でcompare モードほど完全ではありません。

この実行モードの主な目的は、 BDRによって実行されている自動競合解決がノード間で一貫していることを確認することです。つまり、 BDRが競合を解決した後、クラスターは一貫した状態になります。

一般的なユースケースでは、自動競合解決によりクラスターの一貫性が保証されますが、自動競合解決によりノード間でタプルが発散することが知られているいくつかのケースがあります。したがって、LiveCompareのconflicts実行モードは、時間と結果のバランスが取れた状態で、整合性の確認と保証にヘルプます。

競合の例 ----------~~~

node3で次のクエリーを実行ことを想像してください。

SELECT c.reloid::regclass,
       s.origin_name,
       c.local_time,
       c.key_tuple,
       c.local_tuple,
       c.remote_tuple,
       c.apply_tuple,
       c.conflict_type,
       c.conflict_resolution
FROM bdr.conflict_history c
INNER JOIN bdr.subscription_summary s
ON s.sub_id = c.sub_id;

bdr.conflict_historyで次の競合を確認できます。

reloid              | tbl
origin_name         | node2
local_time          | 2021-05-13 19:17:43.239744+00
key_tuple           | {"a":null,"b":3,"c":null}
local_tuple         |
remote_tuple        |
apply_tuple         |
conflict_type       | delete_missing
conflict_resolution | skip

これは、DELETEがnode2からnode3に到着したときに、tblの表にb = 3の行がないことを意味します。ただし、INSERTはnode1からnode3に後で到着し、b = 3の行をnode3に追加した可能性があります。これが、node3の現在のシチュエーションです。

bdrdb=# SELECT * FROM tbl WHERE b = 3;
 a | b |  c
---+---+-----
 x | 3 | foo
(1 row)

ノードnode1およびnode2では、これが表示されます:

bdrdb=# SELECT * FROM tbl WHERE b = 3;
 a | b | c
---+---+---
(0 rows)

BDRクラスターは分岐しています。

このような相違を検出して修正するオーダーに、LiveCompareをcompareモードで実行できますが、比較セットのサイズに応じて(イメージテーブルtblが非常にラージ)、長時間、さらには数時間かかる場合があります。

これは、conflictsモードが役立つシチュエーションです。この場合、delete_missingの競合は可視からのみ表示されますが、LiveCompareは競合のログに記録された行(key_tuple、local_tuple、remote_tupleおよびapply_tuple)からPK値を抽出し、影響を受けるテーブルでのみ自動クラスタ全体の比較を実行できます。すでにPK値でフィルタリングしています。次に、比較により、クラスター内のすべてのノードの現在の行バージョンがチェックされます。

したがって、check.iniファイルを作成してall_bdr_nodes = onを設定します。つまり、LiveCompareにクラスター内のすべてのノードを比較するように指示します。

[General Settings]
logical_replication_mode = bdr
max_parallel_workers = 2
all_bdr_nodes = on

[Initial Connection]
dsn = dbname=bdrdb

[Output Connection]
dsn = dbname=liveoutput

LiveCompareをconflictsモードで実行するには:

livecompare check.ini --conflicts

実行後、コンソール出力に次のようなものが表示されます。

Elapsed time: 0:00:02.443557
Processed 1 conflicts about 1 tables from 3 connections using 2 workers.
Found 1 divergent conflicts in 1 tables.
Processed 1 rows in 1 tables from 3 connections using 2 workers.
Found 1 inconsistent rows in 1 tables.

フォルダー./lc_session_X/(Xが現在の比較セッションの番号)内で、LiveCompareはファイルconflicts_DAY.out(ファイル名前のDAYを現在の日付に置き換えます)を書き込み、すべての分岐競合に関する主な情報を表示します。

データベースliveoutputに接続すると、例次のクエリーを使用して、競合に関する詳細を確認できます。

SELECT *
FROM livecompare.vw_conflicts
WHERE session_id = 1
  AND conflict_id = 1
ORDER BY table_name,
         local_time,
         target_node;

次のようなものが表示されます。

session_id             | 1
table_name             | public.tbl
conflict_id            | 1
connection_id          | node3
origin_node            | node2
target_node            | node3
local_time             | 2021-05-13 19:17:43.239744+00
key_tuple              | {"a": null, "b": 3, "c": null}
local_tuple            |
remote_tuple           |
apply_tuple            |
conflict_type          | delete_missing
conflict_resolution    | skip
conflict_pk_value_list | {(3)}
difference_log_id_list | {1}
is_conflict_divergent  | t

is_conflict_divergent = trueは、LiveCompareが競合を比較し、競合によって報告されたテーブルと行で現在分岐しているノードを見つけたことを意味します。ビューlivecompare.vw_conflictsは、非分岐を含むすべての競合に関する情報を表示します。

LiveCompareは、DMLスクリプト./lc_session_X/apply_on_the_node3_DAY.sqlを自動的に生成します(ファイル名前のDAYを現在の日付に置き換えます)。

BEGIN;

SET LOCAL bdr.xact_replication = off;
SELECT pg_replication_origin_session_setup(bdr_local_only_origin);
SELECT pg_replication_origin_xact_setup(0/0, 2010-01-01::timestamptz);;

SET LOCAL ROLE postgres;
DELETE FROM public.tbl WHERE (b) = (3);

COMMIT;

LiveCompareは、他の2つのノードに行が存在しないため、DELETEにb = 3がnode3からの行にあることを提案しています。デフォルトでは、LiveCompareは大部分のノードに基づいて修正するDMLを提案します。

node3に対してこのDMLスクリプトを実行する場合:

psql -h node3 -f ./lc_session_X/apply_on_the_node3_DAY.sql

BDRクラスターの整合性が再び取れます。

--conflictsモードの比較は完全な--compareよりもはるかに高速であるため、競合の解決によりクラスタ全体の一貫性が保証されるように、--conflicts比較セッションをより頻繁にスケジュールすることを強くお勧めします。

BDR 3.7のbdr.conflict_historyまたはBDR 3.6のbdr.apply_logのデータを表示できるようにオーダーには、bdr_superuserまたはPostgreSQLスーパーユーザのユーザでLiveCompareを実行する必要があることにノートしてください。

競合フィルター --------------------~~~~

LiveCompareに、bdr.conflicts_historyまたはbdr.apply_logのいずれかの列で競合をフィルタリングするように指示することもできます。例:

[Conflicts Filter]
conflicts = table_name = public.tbl and conflict_type = delete_missing

ミキシング技術

node_nameおよびreplication_setsのメタデータはInitial Connectionでフェッチされることにノートしてください。したがって、それはpglogicalおよび/またはBDR対応のデータベースでなければなりません。

テーブルのリストは、最初のデータ接続で作成されます。したがって、replication_sets条件は最初の接続で有効である必要があります。

混在テクノロジーの比較を実行することは可能です、例:

BDR 1ノードとBDR 3ノード。 BDR 4ノードとバニラPostgresインスタンス。 - Vanilla Postgresインスタンスとpglogicalノード。