1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-22 14:32:25 +03:00

Detect and report update_deleted conflicts.

This enhancement builds upon the infrastructure introduced in commit
228c370868, which enables the preservation of deleted tuples and their
origin information on the subscriber. This capability is crucial for
handling concurrent transactions replicated from remote nodes.

The update introduces support for detecting update_deleted conflicts
during the application of update operations on the subscriber. When an
update operation fails to locate the target row-typically because it has
been concurrently deleted-we perform an additional table scan. This scan
uses the SnapshotAny mechanism and we do this additional scan only when
the retain_dead_tuples option is enabled for the relevant subscription.

The goal of this scan is to locate the most recently deleted tuple-matching
the old column values from the remote update-that has not yet been removed
by VACUUM and is still visible according to our slot (i.e., its deletion
is not older than conflict-detection-slot's xmin). If such a tuple is
found, the system reports an update_deleted conflict, including the origin
and transaction details responsible for the deletion.

This provides a groundwork for more robust and accurate conflict
resolution process, preventing unexpected behavior by correctly
identifying cases where a remote update clashes with a deletion from
another origin.

Author: Zhijie Hou <houzj.fnst@fujitsu.com>
Reviewed-by: shveta malik <shveta.malik@gmail.com>
Reviewed-by: Nisha Moond <nisha.moond412@gmail.com>
Reviewed-by: Dilip Kumar <dilipbalaut@gmail.com>
Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Discussion: https://postgr.es/m/OS0PR01MB5716BE80DAEB0EE2A6A5D1F5949D2@OS0PR01MB5716.jpnprd01.prod.outlook.com
This commit is contained in:
Amit Kapila
2025-08-04 04:02:47 +00:00
parent 5c8eda1f72
commit fd5a1a0c3e
16 changed files with 566 additions and 46 deletions

View File

@@ -8087,7 +8087,8 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
<structfield>subretaindeadtuples</structfield> <type>bool</type>
</para>
<para>
If true, the information (e.g., dead tuples, commit timestamps, and
If true, the detection of <xref linkend="conflict-update-deleted"/> is
enabled and the information (e.g., dead tuples, commit timestamps, and
origins) on the subscriber that is useful for conflict detection is
retained.
</para></entry>

View File

@@ -1804,6 +1804,22 @@ Publications:
</para>
</listitem>
</varlistentry>
<varlistentry id="conflict-update-deleted" xreflabel="update_deleted">
<term><literal>update_deleted</literal></term>
<listitem>
<para>
The tuple to be updated was concurrently deleted by another origin. The
update will simply be skipped in this scenario. Note that this conflict
can only be detected when
<link linkend="guc-track-commit-timestamp"><varname>track_commit_timestamp</varname></link>
and <link linkend="sql-createsubscription-params-with-retain-dead-tuples"><literal>retain_dead_tuples</literal></link>
are enabled. Note that if a tuple cannot be found due to the table being
truncated, only a <literal>update_missing</literal> conflict will
arise. Additionally, if the tuple was deleted by the same origin, an
<literal>update_missing</literal> conflict will arise.
</para>
</listitem>
</varlistentry>
<varlistentry id="conflict-update-missing" xreflabel="update_missing">
<term><literal>update_missing</literal></term>
<listitem>

View File

@@ -2223,6 +2223,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage
</para></entry>
</row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>confl_update_deleted</structfield> <type>bigint</type>
</para>
<para>
Number of times the tuple to be updated was concurrently deleted by
another source during the application of changes. See <xref linkend="conflict-update-deleted"/>
for details about this conflict.
</para></entry>
</row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>confl_update_missing</structfield> <type>bigint</type>

View File

@@ -445,10 +445,11 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
Specifies whether the information (e.g., dead tuples, commit
timestamps, and origins) required for conflict detection on the
subscriber is retained. The default is <literal>false</literal>.
If set to <literal>true</literal>, a physical replication slot named
<quote><literal>pg_conflict_detection</literal></quote> will be
created on the subscriber to prevent the conflict information from
being removed.
If set to <literal>true</literal>, the detection of
<xref linkend="conflict-update-deleted"/> is enabled, and a physical
replication slot named <quote><literal>pg_conflict_detection</literal></quote>
created on the subscriber to prevent the information for detecting
conflicts from being removed.
</para>
<para>