Conflicts#
競合検出#
競合タイプのリスト#
PGDは、次の競合タイプを認識し、 conflict_type
パラメーターとして使用できます。
Conflict type |
Description |
|---|---|
insert_exists |
着信挿入は、主キーまたは一意キー/インデックスを介して既存の行と競合します。 |
update_differing |
着信更新のキー行はローカル行とは異なります。これは、 行バージョンの競合検出 を使用する場合にのみ発生する可能性があります。 |
update_origin_change |
着信更新は、別のノードによって最後に変更された行を変更しています。 |
update_missing |
着信更新は、存在しない行を変更しようとしています。 |
update_recently_deleted |
着信更新は、最近削除された行を変更しようとしています。 |
update_pkey_exists |
着信更新により、`PRIMARY KEY`が変更され、変更を適用しているノードに既に存在する値が変更されました。 |
multiple_unique_conflicts |
受信行は、ターゲットテーブルのUNIQUE / EXCLUDEインデックスごとに複数の行と競合します。 |
delete_recently_updated |
現在のノードまたは 行バージョンの競合検出 を使用している場合、行の最新の更新よりも古いコミットタイムスタンプを含む着信削除。 |
delete_missing |
着信削除は、存在しない行を削除しようとしています。 |
target_column_missing |
ターゲットテーブルには、受信行に存在する1つ以上の列がありません。 |
source_column_missing |
着信行には、ターゲットテーブルに存在する1つ以上の列がありません。 |
target_table_missing |
ターゲットテーブルがありません。 |
apply_error_ddl |
レプリケートされたDDLコマンドを適用するときにPostgresによってエラーがスローされました。 |
競合の解決#
ほとんどの競合は自動的に解決できます。
PGDは、last-update-winsメカニズム、より正確にはupdate_if_newer
競合リゾルバーにデフォルトで設定されます。このメカニズムでは、競合検出に使用される同じコミットタイムスタンプに基づいて、2つの競合する行の最後に挿入または変更された行を保持します。特定のコーナーケースのシナリオでの動作は、bdr.create_node_group
またはbdr.alter_node_group に使用される設定によって異なります。
PGDでは、次のファンクションを使用して競合解決のデフォルト動作をオーバーライドできます。
競合リゾルバーのリスト#
PGDではいくつかの競合リゾルバーが使用でき、処理できる競合タイプのカバレッジが異なります。
Resolver |
Description |
|---|---|
error |
エラーをスローし、レプリケーションを停止します。 |
skip |
リモート変更の処理をスキップし、次の変更でレプリケーションを続行します。 insert_exists、update_differing、update_origin_change、update_missing、update_recently_deleted、update_pkey_exists、delete_recently_updated、delete_missing、target_table_missing、target_column_missing、および`source_column_missing`競合タイプに使用できます。 |
skip_if_recently_dropped |
最近ダウンストリームで1日以内にドロップされたため、ダウンストリームが存在しないテーブル用の場合、リモート変更をスキップします。それ以外の場合はエラーをスローします。 `target_table_missing`競合タイプに使用できます。 <br/>この競合リゾルバーは、同じ名前のテーブルがドロップされた後すぐに再作成される場合、課題を引き起こす可能性があります。その場合、ノードのいずれかが、テーブルを再作成するDDLを参照する前に、再作成されたテーブルのDMLを参照する場合があります。次に、テーブルが最近ドロップされたと仮定して、リモートデータを誤ってスキップし、データ損失を引き起こします。このリゾルバーを使用する場合、ドロップされた直後にオブジェクト名を再利用しないことをお勧めします。 |
skip_transaction |
競合を生成したトランザクション全体をスキップします。 |
update_if_newer |
リモート行が競合するローカル行よりも後にコミットされた場合に更新されます元ノードの壁時計によって決定されます。タイムスタンプが同じ場合、ノードIDはタイブレーカーとして使用され、すべてのノードで同じ行が選択されるように保証されます。より高いノードIDが勝ちます。 insert_exists、update_differing、update_origin_change、および`update_pkey_exists`競合タイプに使用できます。 |
update |
レプリケートされたアクションを常に実行します。 insert_exists INSERT`を`UPDATE`に変更します 、`update_differing、update_origin_change、update_pkey_exists、および`delete_recently_updated` 削除を実行します。 |
insert_or_skip |
オリジンから送信された利用可能な情報から新しい行を構築し、 INSERTしようとします。完全な行を作成するための十分な情報がない場合、変更をスキップします。 `update_missing`および`update_recently_deleted`競合タイプに使用できます。 |
insert_or_error |
オリジンから送信された利用可能な情報から新しい行を構築し、挿入しようとします。完全な行を構築するために利用できる十分な情報がない場合、エラーをスローし、レプリケーションを停止します。完全な行を構築するために利用できる十分な情報がない場合、エラーをスローし、レプリケーションを停止します。 `update_missing`および`update_recently_deleted`競合タイプに使用できます。 |
ignore |
欠落しているターゲット列を無視して、処理を続行します。 `target_column_missing`競合タイプに使用できます。 |
ignore_if_null |
リモート行の追加列にNULL値が含まれる場合、欠落しているターゲット列を無視します。それ以外の場合は、エラーをスローし、レプリケーションを停止します。 `target_column_missing`競合タイプに使用できます。 |
use_default_value |
欠落している列値をデフォルト列のデフォルトの場合はNULLを含むで埋めて、処理を続行します。デフォルトまたは制約違反つまり、 NOT NULL列のNULLデフォルトの処理中にエラーが発生すると、レプリケーションが停止されます。 `source_column_missing`競合タイプに使用できます。 |
insert_exists 、update_differing 、update_origin_change
、update_missing 、multiple_unique_conflicts
、update_recently_deleted 、update_pkey_exists
、delete_recently_updated 、およびdelete_missing
競合タイプは、
Stream triggers を使用するユーザー定義ロジックでも解決できます。
このマトリックスは、各競合リゾルバーが処理できる競合タイプを示しています。
insert_exists |
update_differing |
update_origin_change |
update_missing |
update_recently_deleted |
update_pkey_exists |
delete_recently_updated |
delete_missing |
target_column_missing |
source_column_missing |
target_table_missing |
multiple_unique_conflicts |
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
error |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
skip |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
skip_if_recently_dropped |
X |
|||||||||||
update_if_newer |
X |
X |
X |
X |
X |
|||||||
update |
X |
X |
X |
X |
X |
X |
||||||
insert_or_skip |
X |
X |
||||||||||
insert_or_error |
X |
X |
||||||||||
ignore |
X |
|||||||||||
ignore_if_null |
X |
|||||||||||
use_default_value |
X |
|||||||||||
conflict_trigger |
X |
X |
X |
X |
X |
X |
X |
X |
X |
デフォルトの競合リゾルバー#
Conflict type |
Resolver |
|---|---|
insert_exists |
update_if_newer |
update_differing |
update_if_newer |
update_origin_change |
update_if_newer |
update_missing |
insert_or_skip |
update_recently_deleted |
skip |
update_pkey_exists |
update_if_newer |
multiple_unique_conflicts |
update_if_newer |
delete_recently_updated |
skip |
delete_missing |
skip |
target_column_missing |
ignore_if_null |
source_column_missing |
use_default_value |
target_table_missing (see note) |
skip_if_recently_dropped |
apply_error_ddl |
error |
競合解決は、競合リゾルバーが選択した解決の種類を表し、競合を解決するために実行された特定のアクションに対応します。
次の競合解決は、conflict_resolution
パラメーターで現在サポートされています。
Resolution |
Description |
|---|---|
apply_remote |
リモート着信行が適用されました。 |
skip |
行の処理はスキップされましたローカルでの変更は行われませんでした。 |
merge |
リモート行とローカル行からの情報をマージして、新しい行が作成されました。 |
user |
ユーザーコード競合トリガーは、ターゲットテーブルに書き込まれる行を生成しました。 |
競合ログ#
バージョン6.0以降、PGDはデフォルトでbdr.conflict_history
テーブルに競合をログに記録しません。これは、テーブルが大きくなり、パフォーマンスの問題を発生させる可能性があるためです。
bdr.alter_node_set_log_config ファンクションを使用して、競合ログを有効にできます。この機能を使用すると、ログに記録する競合を詳細に制御できます。または、次のようにすべての競合をログに記録するように設定できます。
SELECT bdr.alter_node_set_log_config(`nodename`, false, true, NULL, NULL);
名前付けノードでこのコマンドを実行して、その特定のノードでのすべての競合のログを有効にします。すべてのノードでロギングを有効にする場合は、 PGDグループの各ノードでこのコマンドを実行します。