バージョンごとのドキュメント一覧

29.6. コンフリクト #

<title>Conflicts</title>

Logical replication behaves similarly to normal DML operations in that the data will be updated even if it was changed locally on the subscriber node. If incoming data violates any constraints the replication will stop. This is referred to as a <firstterm>conflict</firstterm>. When replicating <command>UPDATE</command> or <command>DELETE</command> operations, missing data will not produce a conflict and such operations will simply be skipped. サブスクライバーノードでローカルにデータが変更された場合でも、データが更新されるという点では、論理レプリケーションは通常のDML操作と同じように振る舞います。 到着したデータが制約に違反すると、レプリケーションは停止します。 これは、コンフリクトと呼ばれます。 UPDATEあるいはDELETE操作をレプリケーションする場合は、存在しないデータによってコンフリクトは起こらず、そのような操作は単にスキップされます。

Logical replication operations are performed with the privileges of the role which owns the subscription. Permissions failures on target tables will cause replication conflicts, as will enabled <link linkend="ddl-rowsecurity">row-level security</link> on target tables that the subscription owner is subject to, without regard to whether any policy would ordinarily reject the <command>INSERT</command>, <command>UPDATE</command>, <command>DELETE</command> or <command>TRUNCATE</command> which is being replicated. This restriction on row-level security may be lifted in a future version of <productname>PostgreSQL</productname>. 論理レプリケーション操作は、サブスクリプションを所有するロールの権限を使用して実行されます。 ターゲットテーブルで権限が失敗すると、レプリケーション競合が発生します。 サブスクリプション所有者が適用されるターゲットテーブルで有効行レベルセキュリティになりますが、レプリケーションされているINSERTUPDATEDELETEまたはTRUNCATEをポリシーが通常拒否するかどうかには関係ありません。 行レベルセキュリティに対するこの制限は、PostgreSQLの将来のバージョンで解除される可能性があります。

A conflict will produce an error and will stop the replication; it must be resolved manually by the user. Details about the conflict can be found in the subscriber's server log. コンフリクトはエラーを生じさせ、レプリケーションを停止させます。 コンフリクトはユーザが手動で解消しなければなりません。 コンフリクトの詳細は、サブスクライバーのサーバログに出力されます。

The resolution can be done either by changing data or permissions on the subscriber so that it does not conflict with the incoming change or by skipping the transaction that conflicts with the existing data. When a conflict produces an error, the replication won't proceed, and the logical replication worker will emit the following kind of message to the subscriber's server log: この問題を解決するには、データを変更するか、サブスクライバーに対する権限を変更して、既存の変更でコンフリクトしないようにするか、既存のトランザクションと競合するデータをスキップします。 コンフリクトよってエラーが発生した場合、レプリケーションは処理を続行せず、論理レプリケーションワーカーは次のようなメッセージをサブスクライバーのサーバログに送信します。

ERROR:  duplicate key value violates unique constraint "test_pkey"
DETAIL:  Key (c)=(1) already exists.
CONTEXT:  processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378

The LSN of the transaction that contains the change violating the constraint and the replication origin name can be found from the server log (LSN 0/14C0378 and replication origin <literal>pg_16395</literal> in the above case). The transaction that produced the conflict can be skipped by using <link linkend="sql-altersubscription-params-skip"><command>ALTER SUBSCRIPTION ... SKIP</command></link> with the finish LSN (i.e., LSN 0/14C0378). The finish LSN could be an LSN at which the transaction is committed or prepared on the publisher. Alternatively, the transaction can also be skipped by calling the <link linkend="pg-replication-origin-advance"> <function>pg_replication_origin_advance()</function></link> function. Before using this function, the subscription needs to be disabled temporarily either by <link linkend="sql-altersubscription-params-disable"> <command>ALTER SUBSCRIPTION ... DISABLE</command></link> or, the subscription can be used with the <link linkend="sql-createsubscription-params-with-disable-on-error"><literal>disable_on_error</literal></link> option. Then, you can use <function>pg_replication_origin_advance()</function> function with the <parameter>node_name</parameter> (i.e., <literal>pg_16395</literal>) and the next LSN of the finish LSN (i.e., 0/14C0379). The current position of origins can be seen in the <link linkend="view-pg-replication-origin-status"> <structname>pg_replication_origin_status</structname></link> system view. Please note that skipping the whole transaction includes skipping changes that might not violate any constraint. This can easily make the subscriber inconsistent. 制約とレプリケーションの起点名に違反する変更を含むトランザクションのLSNは、サーバログ(LSN 0/14C0378とレプリケーション起点pg_16395)から見つけることができます。 競合を発生させたトランザクションは、終了LSN(LSN 0/14C0378)でALTER SUBSCRIPTION ... SKIPを使用してスキップできます。 終了LSNは、パブリッシャーでトランザクションがコミットまたは準備されたLSNにすることができます。 あるいは、pg_replication_origin_advance()関数を呼び出して、トランザクションをスキップすることもできます。 この関数を使用する前に、ALTER SUBSCRIPTION ... DISABLEを使用してサブスクリプションを一時的に無効にする必要があります。 また、サブスクリプションはdisable_on_errorオプションを使用して使用できます。 次に、pg_replication_origin_advance()関数をnode_name(pg_16395)と終了LSNの次のLSN(0/14C0379)と共に使用できます。 現在の起点の位置は、pg_replication_origin_statusシステムビューで確認できます。 トランザクション全体をスキップすることは、いかなる制約にも違反しない可能性のある変更をスキップすることを含むことに注意してください。 これは容易にサブスクライバーを不整合にする可能性があります。

When the <link linkend="sql-createsubscription-params-with-streaming"><literal>streaming</literal></link> mode is <literal>parallel</literal>, the finish LSN of failed transactions may not be logged. In that case, it may be necessary to change the streaming mode to <literal>on</literal> or <literal>off</literal> and cause the same conflicts again so the finish LSN of the failed transaction will be written to the server log. For the usage of finish LSN, please refer to <link linkend="sql-altersubscription"><command>ALTER SUBSCRIPTION ... SKIP</command></link>. streamingモードがparallelの場合、失敗したトランザクションの終了LSNはログに書き込まれないことがあります。 その場合、ストリーミングモードをonまたはoffに変更し、再度同じコンフリクトを起こすことで、失敗したトランザクションの終了LSNをサーバのログに書き込むようにする必要があるかもしれません。 終了LSNの使用方法については、ALTER SUBSCRIPTION ... SKIPを参照してください。