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

31.5. コンフリクト #

<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 <command>ALTER SUBSCRIPTION ... SKIP</command> 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 <command>ALTER SUBSCRIPTION ... DISABLE</command> or, the subscription can be used with the <link linkend="sql-createsubscription-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システムビューで確認できます。 トランザクション全体をスキップすることは、いかなる制約にも違反しない可能性のある変更をスキップすることを含むことに注意してください。 これは容易にサブスクライバーを不整合にする可能性があります。 《機械翻訳》制約に違反する変更を含むトランザクションの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-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を参照してください。