EDB Postgres Distributed support#

LiveCompareは、 EDB Postgres DistributedPGD、以前はBDRノードと同様に非PGDノードに対して使用できます。

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

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

次に、3つのPGDノードを比較するとします。 LiveCompareは初期接続から任意のノードに接続できるため、データ接続のdsn または接続情報を定義する必要はありません。 node_name を定義するだけで済みます。 LiveCompareは、そのノードの接続情報に関するPGDメタデータを検索し、ノードに接続します。

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

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

たとえば、 .ini ファイルを作成して、3つのPGDノードを比較できます。

[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

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

  1. General Settings の下で、all_bdr_nodes = on を有効にします。

  2. 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 設定を使用してすべてのPGDノードのリストを取得します。追加のデータ接続は必要ありませんが、設定すると、データ接続のリストに追加されます。たとえば、 PGDクラスター全体を単一のPostgres接続と比較できます。これは、移行プロジェクトに役立ちます。

[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 は、次のテクノロジーでサポートされています。

  • PGD 1、2、3、および4

  • pglogical 2および3

PGDの代わりにpgロジカルメタデータの取得を有効にするには、 logical_replication_mode = bdr の代わりにlogical_replication_mode = pglogical を設定します。

PGD監視ノード#

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

PGD監視は、他のノードからDMLをレプリケートしない通常のPGDノードです。 Witnessの目的は、Raftコンセンサス投票でクォーラムを提供することです。レプリケーションセットの構成は、監視がDDLをレプリケートするかどうかを決定します。これは、2種類のPGD証人が存在することを意味します。

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

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

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

Table public.tbl does not exist on connection node1

2番目のケースでは、テーブルはPGD監視に存在します。ただし、証人で不足しているデータを発散として報告するのは正しくありません。したがって、LiveCompareは、テーブルごとに、比較に含まれる各ノードに関する次の情報をチェックします。

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

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

  • Table Filter の下のフィルタreplication_sets で定義したレプリケーションセットがある場合

レプリケーションセットの3つのリストすべての交差が空の場合、PGD監視の場合、LiveCompareは次のメッセージをログに記録します。

Table public.tbl is not subscribed on connection node1

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

PGDクラスターの違い#

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

logical_replication_mode = bdr の場合、LiveCompareは最初にbdr_local_only_origin というレプリケーションオリジンが既に存在するかどうかを確認します。 difference_fix_replication_origin 設定を調整することにより、レプリケーションオリジンの名前を構成できます。

重要

PGD 3.6.18では、ローカル専用トランザクションを適用するために使用する新しい既存の`bdr_local_only_origin` レプリケーションオリジンを導入しました。 LiveCompareがPGD 3.6.18に接続されている場合、このレプリケーションオリジンは作成されません。

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

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

  • 現在のトランザクションの日時をはるかに過去に設定するため、データベースで実行されている実際のDMLとPGD競合がある場合、LiveCompare DMLは常に競合に負けます。

LiveCompare修正スクリプトをPGDノードに適用した後、次のクエリーを使用して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はレプリケーションオリジンを関連付けずに修正を生成します。ただし、DMLスクリプトを適用するときは、レプリケーションオリジンを使用することをお勧めします。それ以外の場合、LiveCompareは、競合の解決に関して通常のユーザーアプリケーションと同じ優先順位を持ちます。また、修正に関連付けられているレプリケーションオリジンが存在しないため、クエリを使用してLiveCompareによって修正されたすべての行をリストすることはできません。

PGD 3.6.18とPGD 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が必要です。 PGD 3.7.0以降、これらの機能は非推奨です。その場合、PostgreSQLスーパーユーザーとして実行している場合、LiveCompareは次の機能を使用して同じアクションを実行します。

  • 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;

PGDの競合#

LiveCompareには、conflicts と呼ばれる実行モードがあります。この実行モードは、PGDクラスターに固有です。 PGD 3.6、PGD 3.7、PGD 4、およびPGD 5クラスターでのみ動作します。

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

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

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

一般的なユースケースでは、自動競合解決によりクラスターの一貫性が保証されますが、自動競合解決がノード間で分岐したタプルを生成する可能性がある既知のケースがいくつかあります。したがって、 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)

PGDクラスターは発散しています。

このような相違を検出して修正するには、compare モードでLiveCompareを実行できます。ただし、比較セットのサイズによっては、テーブルtbl が非常に大きい場合、これには長時間、場合によっては数時間かかる場合があります。

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

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

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

[Initial Connection]
dsn = dbname=bdrdb

[Output Connection]
dsn = dbname=liveoutput

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

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つの行に存在しないため、node3 からb = 3 が存在する行をDELETE に提案しています。デフォルトでは、LiveCompareはノードの大部分に基づいて修正するDMLを提案します。

node3 に対してこのDMLスクリプトを実行すると、PGDクラスターの一貫性が再び高まります。

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

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

注釈

PGD 3.7の`bdr.conflict_history` またはPGD 3.6の`bdr.apply_log` のデータを表示するには、 bdr_superuserまたはPostgreSQLスーパーユーザーであるユーザーでLiveCompareを実行します。

PGD 3.7+のbdr.conflict_history またはPGD 3.6のbdr.apply_log のデータを表示できるようにするには、 bdr_superuserまたはPostgreSQLスーパーユーザーであるユーザーでLiveCompareを実行します。

競合フィルター#

bdr.conflicts_history またはbdr.apply_log の列で競合をフィルターするようにLiveCompareに指示することもできます。例

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

ミキシングテクノロジー#

node_name およびreplication_sets のメタデータは、初期接続で取得されます。したがって、pglogicalおよび/またはPGD対応データベースである必要があります。

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

混合テクノロジーの比較を実行できます。例

  • PGD 1ノードとPGD 3ノード

  • PGD 4ノードとバニラのPostgresインスタンス

  • Vanilla Postgresインスタンスとpg論理ノード