Home Explore Blog CI



postgresql

25th chunk of `doc/src/sgml/logical-replication.sgml`
7208df6113b0d1ee6c4e32212d3d8e967993d34870a7ac3d0000000100000fa0

   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>.
  </para>

  <para>
   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>

  <para>
   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:
<screen>
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
   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.
   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

Title: Conflict Resolution and Skipping Transactions in Logical Replication
Summary
This section describes how logical replication conflicts, caused by permission issues or row-level security, can halt replication. Resolution involves changing data/permissions on the subscriber or skipping the conflicting transaction. The error message in the subscriber's log provides details like LSN and replication origin, which can be used with `ALTER SUBSCRIPTION ... SKIP` or `pg_replication_origin_advance()` to skip the transaction. It warns that skipping the entire transaction may lead to inconsistency. The `DETAIL` line in the log, especially with `track_commit_timestamp` enabled, provides additional information about conflicting rows, helping users decide whether to keep the local change or adopt the remote one.