diff options
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/logical-replication.sgml | 103 |
1 files changed, 98 insertions, 5 deletions
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index a23a3d57e2b..885a2d70ae7 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -1579,8 +1579,91 @@ test_sub=# SELECT * FROM t1 ORDER BY id; 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. + operations, missing data is also considered as a + <firstterm>conflict</firstterm>, but does not result in an error and such + operations will simply be skipped. + </para> + + <para> + Additional logging is triggered in the following <firstterm>conflict</firstterm> + cases: + <variablelist> + <varlistentry> + <term><literal>insert_exists</literal></term> + <listitem> + <para> + Inserting a row that violates a <literal>NOT DEFERRABLE</literal> + unique constraint. Note that to log the origin and commit + timestamp details of the conflicting key, + <link linkend="guc-track-commit-timestamp"><varname>track_commit_timestamp</varname></link> + should be enabled on the subscriber. In this case, an error will be + raised until the conflict is resolved manually. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>update_differ</literal></term> + <listitem> + <para> + Updating a row that was previously modified by another origin. + Note that this conflict can only be detected when + <link linkend="guc-track-commit-timestamp"><varname>track_commit_timestamp</varname></link> + is enabled on the subscriber. Currenly, the update is always applied + regardless of the origin of the local row. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>update_exists</literal></term> + <listitem> + <para> + The updated value of a row violates a <literal>NOT DEFERRABLE</literal> + unique constraint. Note that to log the origin and commit + timestamp details of the conflicting key, + <link linkend="guc-track-commit-timestamp"><varname>track_commit_timestamp</varname></link> + should be enabled on the subscriber. In this case, an error will be + raised until the conflict is resolved manually. Note that when updating a + partitioned table, if the updated row value satisfies another partition + constraint resulting in the row being inserted into a new partition, the + <literal>insert_exists</literal> conflict may arise if the new row + violates a <literal>NOT DEFERRABLE</literal> unique constraint. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>update_missing</literal></term> + <listitem> + <para> + The tuple to be updated was not found. The update will simply be + skipped in this scenario. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>delete_differ</literal></term> + <listitem> + <para> + Deleting a row that was previously modified by another origin. Note that + this conflict can only be detected when + <link linkend="guc-track-commit-timestamp"><varname>track_commit_timestamp</varname></link> + is enabled on the subscriber. Currenly, the delete is always applied + regardless of the origin of the local row. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>delete_missing</literal></term> + <listitem> + <para> + The tuple to be deleted was not found. The delete will simply be + skipped in this scenario. + </para> + </listitem> + </varlistentry> + </variablelist> + Note that there are other conflict scenarios, such as exclusion constraint + violations. Currently, we do not provide additional details for them in the + log. </para> <para> @@ -1597,7 +1680,7 @@ test_sub=# SELECT * FROM t1 ORDER BY id; </para> <para> - A conflict will produce an error and will stop the replication; it must be + A conflict that produces an error 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. </para> @@ -1609,8 +1692,9 @@ test_sub=# SELECT * FROM t1 ORDER BY id; 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: <screen> -ERROR: duplicate key value violates unique constraint "test_pkey" -DETAIL: Key (c)=(1) already exists. +ERROR: conflict detected on relation "public.test": conflict=insert_exists +DETAIL: Key already exists in unique index "t_pkey", which was modified locally in transaction 740 at 2024-06-26 10:47:04.727375+08. +Key (c)=(1); existing local tuple (1, 'local'); remote tuple (1, 'remote'). CONTEXT: processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378 </screen> The LSN of the transaction that contains the change violating the constraint and @@ -1636,6 +1720,15 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER Please note that skipping the whole transaction includes skipping changes that might not violate any constraint. This can easily make the subscriber inconsistent. + The additional details regarding conflicting rows, such as their origin and + commit timestamp can be seen in the <literal>DETAIL</literal> line of the + log. But note that this information is only available when + <link linkend="guc-track-commit-timestamp"><varname>track_commit_timestamp</varname></link> + is enabled on the subscriber. Users can use this information to decide + whether to retain the local change or adopt the remote alteration. For + instance, the <literal>DETAIL</literal> line in the above log indicates that + the existing row was modified locally. Users can manually perform a + remote-change-win. </para> <para> |