Skip to content

Commit 5a64a8a

Browse files
author
Commitfest Bot
committed
[CF 5378] v30 - Conflict detection for update_deleted in logical replication
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5378 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/TYAPR01MB572428A7A4A875C069567B8E94852@TYAPR01MB5724.jpnprd01.prod.outlook.com Author(s): Zhijie Hou
2 parents f8c115a + 8131dd0 commit 5a64a8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2178
-169
lines changed

doc/src/sgml/catalogs.sgml

+12
Original file line numberDiff line numberDiff line change
@@ -8088,6 +8088,18 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
80888088
</para></entry>
80898089
</row>
80908090

8091+
<row>
8092+
<entry role="catalog_table_entry"><para role="column_definition">
8093+
<structfield>subretainconflictinfo</structfield> <type>bool</type>
8094+
</para>
8095+
<para>
8096+
If true, the detection of <xref linkend="conflict-update-deleted"/> is
8097+
enabled and the information (e.g., dead tuples, commit timestamps, and
8098+
origins) on the subscriber that is still useful for conflict detection
8099+
is retained.
8100+
</para></entry>
8101+
</row>
8102+
80918103
<row>
80928104
<entry role="catalog_table_entry"><para role="column_definition">
80938105
<structfield>subconninfo</structfield> <type>text</type>

doc/src/sgml/config.sgml

+46
Original file line numberDiff line numberDiff line change
@@ -4945,6 +4945,8 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
49454945
new setting.
49464946
This setting has no effect if <varname>primary_conninfo</varname> is not
49474947
set or the server is not in standby mode.
4948+
The name cannot be <literal>pg_conflict_detection</literal>, as it is
4949+
reserved for logical replication conflict detection.
49484950
</para>
49494951
</listitem>
49504952
</varlistentry>
@@ -5377,6 +5379,50 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
53775379
</listitem>
53785380
</varlistentry>
53795381

5382+
<varlistentry id="guc-max-conflict-retention-duration" xreflabel="max_conflict_retention_duration">
5383+
<term><varname>max_conflict_retention_duration</varname> (<type>integer</type>)
5384+
<indexterm>
5385+
<primary><varname>max_conflict_retention_duration</varname> configuration parameter</primary>
5386+
</indexterm>
5387+
</term>
5388+
<listitem>
5389+
<para>
5390+
Maximum duration (in milliseconds) for which conflict
5391+
information can be retained for conflict detection by the apply worker.
5392+
The default value is <literal>0</literal>, indicating that conflict
5393+
information is retained until it is no longer needed for detection
5394+
purposes.
5395+
</para>
5396+
<para>
5397+
The replication slot
5398+
<quote><literal>pg_conflict_detection</literal></quote> that used to
5399+
retain conflict information will be invalidated if all apply workers
5400+
associated with the subscriptions, where
5401+
<literal>retain_conflict_info</literal> is enabled, confirm that the
5402+
retention duration exceeded the
5403+
<literal>max_conflict_retention_duration</literal>. If the replication
5404+
slot is invalidated, you can disable
5405+
<literal>retain_conflict_info</literal> and re-enable it after
5406+
confirming this replication slot has been dropped. Alternatively, the
5407+
invalidated slot will be automatically dropped and re-created once the
5408+
apply worker confirms that the retention duration is within the
5409+
specified limit.
5410+
</para>
5411+
<para>
5412+
This option is effective only if a subscription with
5413+
<literal>retain_conflict_info</literal> enabled is present, and the
5414+
associated apply worker is active.
5415+
</para>
5416+
<warning>
5417+
<para>
5418+
Note that setting a non-zero value for this option could lead to
5419+
conflict information being removed prematurely, potentially missing
5420+
some conflict detections.
5421+
</para>
5422+
</warning>
5423+
</listitem>
5424+
</varlistentry>
5425+
53805426
</variablelist>
53815427
</sect2>
53825428

doc/src/sgml/func.sgml

+11-3
Original file line numberDiff line numberDiff line change
@@ -29710,7 +29710,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2971029710
</para>
2971129711
<para>
2971229712
Creates a new physical replication slot named
29713-
<parameter>slot_name</parameter>. The optional second parameter,
29713+
<parameter>slot_name</parameter>. The name cannot be
29714+
<literal>pg_conflict_detection</literal>, as it is reserved for
29715+
logical replication conflict detection. The optional second parameter,
2971429716
when <literal>true</literal>, specifies that the <acronym>LSN</acronym> for this
2971529717
replication slot be reserved immediately; otherwise
2971629718
the <acronym>LSN</acronym> is reserved on first connection from a streaming
@@ -29754,7 +29756,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2975429756
<para>
2975529757
Creates a new logical (decoding) replication slot named
2975629758
<parameter>slot_name</parameter> using the output plugin
29757-
<parameter>plugin</parameter>. The optional third
29759+
<parameter>plugin</parameter>. The name cannot be
29760+
<literal>pg_conflict_detection</literal>, as it is reserved for
29761+
logical replication conflict detection. The optional third
2975829762
parameter, <parameter>temporary</parameter>, when set to true, specifies that
2975929763
the slot should not be permanently stored to disk and is only meant
2976029764
for use by the current session. Temporary slots are also
@@ -29784,6 +29788,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2978429788
<para>
2978529789
Copies an existing physical replication slot named <parameter>src_slot_name</parameter>
2978629790
to a physical replication slot named <parameter>dst_slot_name</parameter>.
29791+
The new slot name cannot be <literal>pg_conflict_detection</literal>,
29792+
as it is reserved for logical replication conflict detection.
2978729793
The copied physical slot starts to reserve WAL from the same <acronym>LSN</acronym> as the
2978829794
source slot.
2978929795
<parameter>temporary</parameter> is optional. If <parameter>temporary</parameter>
@@ -29806,7 +29812,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
2980629812
Copies an existing logical replication slot
2980729813
named <parameter>src_slot_name</parameter> to a logical replication
2980829814
slot named <parameter>dst_slot_name</parameter>, optionally changing
29809-
the output plugin and persistence. The copied logical slot starts
29815+
the output plugin and persistence. The name cannot be
29816+
<literal>pg_conflict_detection</literal>, as it is reserved for
29817+
logical replication conflict detection. The copied logical slot starts
2981029818
from the same <acronym>LSN</acronym> as the source logical slot. Both
2981129819
<parameter>temporary</parameter> and <parameter>plugin</parameter> are
2981229820
optional; if they are omitted, the values of the source slot are used.

doc/src/sgml/logical-replication.sgml

+17-1
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,21 @@ test_sub=# SELECT * from tab_gen_to_gen;
18181818
</para>
18191819
</listitem>
18201820
</varlistentry>
1821+
<varlistentry id="conflict-update-deleted" xreflabel="update_deleted">
1822+
<term><literal>update_deleted</literal></term>
1823+
<listitem>
1824+
<para>
1825+
The tuple to be updated was deleted by another origin. The update will
1826+
simply be skipped in this scenario.
1827+
Note that this conflict can only be detected when
1828+
<xref linkend="guc-track-commit-timestamp"/>
1829+
and <link linkend="sql-createsubscription-params-with-retain-conflict-info"><literal>retain_conflict_info</literal></link>
1830+
are enabled. Note that if a tuple cannot be found due to the table being
1831+
truncated only a <literal>update_missing</literal> conflict will arise.
1832+
arise
1833+
</para>
1834+
</listitem>
1835+
</varlistentry>
18211836
<varlistentry id="conflict-update-origin-differs" xreflabel="update_origin_differs">
18221837
<term><literal>update_origin_differs</literal></term>
18231838
<listitem>
@@ -2408,7 +2423,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER
24082423
<para>
24092424
<link linkend="guc-max-replication-slots"><varname>max_replication_slots</varname></link>
24102425
must be set to at least the number of subscriptions expected to connect,
2411-
plus some reserve for table synchronization.
2426+
plus some reserve for table synchronization and one if
2427+
<link linkend="sql-createsubscription-params-with-retain-conflict-info"><literal>retain_conflict_info</literal></link> is enabled.
24122428
</para>
24132429

24142430
<para>

doc/src/sgml/monitoring.sgml

+24
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,19 @@ description | Waiting for a newly initialized WAL file to reach durable storage
21092109
sender; NULL for parallel apply workers
21102110
</para></entry>
21112111
</row>
2112+
2113+
<row>
2114+
<entry role="catalog_table_entry"><para role="column_definition">
2115+
<structfield>retain_conflict_info</structfield> <type>boolean</type>
2116+
</para>
2117+
<para>
2118+
True if <link linkend="sql-createsubscription-params-with-retain-conflict-info"><literal>retain_conflict_info</literal></link>
2119+
is enabled and the duration for which conflict information is
2120+
retained for conflict detection by this apply worker does not exceed
2121+
<link linkend="guc-max-conflict-retention-duration"><literal>max_conflict_retention_duration</literal></link>; NULL for
2122+
parallel apply workers and table synchronization workers.
2123+
</para></entry>
2124+
</row>
21122125
</tbody>
21132126
</tgroup>
21142127
</table>
@@ -2194,6 +2207,17 @@ description | Waiting for a newly initialized WAL file to reach durable storage
21942207
</para></entry>
21952208
</row>
21962209

2210+
<row>
2211+
<entry role="catalog_table_entry"><para role="column_definition">
2212+
<structfield>confl_update_deleted</structfield> <type>bigint</type>
2213+
</para>
2214+
<para>
2215+
Number of times the tuple to be updated was deleted by another origin
2216+
during the application of changes. See <xref linkend="conflict-update-deleted"/>
2217+
for details about this conflict.
2218+
</para></entry>
2219+
</row>
2220+
21972221
<row>
21982222
<entry role="catalog_table_entry"><para role="column_definition">
21992223
<structfield>confl_update_origin_differs</structfield> <type>bigint</type>

doc/src/sgml/protocol.sgml

+92
Original file line numberDiff line numberDiff line change
@@ -2220,6 +2220,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
22202220
<para>
22212221
The name of the slot to create. Must be a valid replication slot
22222222
name (see <xref linkend="streaming-replication-slots-manipulation"/>).
2223+
The name cannot be <literal>pg_conflict_detection</literal>, as it
2224+
is reserved for logical replication conflict detection.
22232225
</para>
22242226
</listitem>
22252227
</varlistentry>
@@ -2638,6 +2640,69 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
26382640
</variablelist>
26392641
</listitem>
26402642
</varlistentry>
2643+
2644+
<varlistentry id="protocol-replication-primary-status-update">
2645+
<term>Primary status update (B)</term>
2646+
<listitem>
2647+
<variablelist>
2648+
<varlistentry>
2649+
<term>Byte1('s')</term>
2650+
<listitem>
2651+
<para>
2652+
Identifies the message as a primary status update.
2653+
</para>
2654+
</listitem>
2655+
</varlistentry>
2656+
2657+
<varlistentry>
2658+
<term>Int64</term>
2659+
<listitem>
2660+
<para>
2661+
The latest WAL write position on the server.
2662+
</para>
2663+
</listitem>
2664+
</varlistentry>
2665+
2666+
<varlistentry>
2667+
<term>Int32</term>
2668+
<listitem>
2669+
<para>
2670+
The oldest transaction ID that is currently in the commit
2671+
phase on the server.
2672+
</para>
2673+
</listitem>
2674+
</varlistentry>
2675+
2676+
<varlistentry>
2677+
<term>Int32</term>
2678+
<listitem>
2679+
<para>
2680+
The next transaction ID to be assigned on the server.
2681+
</para>
2682+
</listitem>
2683+
</varlistentry>
2684+
2685+
<varlistentry>
2686+
<term>Int32</term>
2687+
<listitem>
2688+
<para>
2689+
The epoch of the next transaction ID to be assigned.
2690+
</para>
2691+
</listitem>
2692+
</varlistentry>
2693+
2694+
<varlistentry>
2695+
<term>Int64</term>
2696+
<listitem>
2697+
<para>
2698+
The server's system clock at the time of transmission, as
2699+
microseconds since midnight on 2000-01-01.
2700+
</para>
2701+
</listitem>
2702+
</varlistentry>
2703+
</variablelist>
2704+
</listitem>
2705+
</varlistentry>
26412706
</variablelist>
26422707

26432708
<para>
@@ -2782,6 +2847,33 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
27822847
</variablelist>
27832848
</listitem>
27842849
</varlistentry>
2850+
2851+
<varlistentry id="protocol-replication-standby-wal-status-request">
2852+
<term>Request primary status update (F)</term>
2853+
<listitem>
2854+
<variablelist>
2855+
<varlistentry>
2856+
<term>Byte1('p')</term>
2857+
<listitem>
2858+
<para>
2859+
Identifies the message as a request for a primary status update.
2860+
</para>
2861+
</listitem>
2862+
</varlistentry>
2863+
2864+
<varlistentry>
2865+
<term>Int64</term>
2866+
<listitem>
2867+
<para>
2868+
The client's system clock at the time of transmission, as
2869+
microseconds since midnight on 2000-01-01.
2870+
</para>
2871+
</listitem>
2872+
</varlistentry>
2873+
</variablelist>
2874+
</listitem>
2875+
</varlistentry>
2876+
27852877
</variablelist>
27862878
</listitem>
27872879
</varlistentry>

doc/src/sgml/ref/alter_subscription.sgml

+10-2
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,9 @@ ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <
235235
<link linkend="sql-createsubscription-params-with-password-required"><literal>password_required</literal></link>,
236236
<link linkend="sql-createsubscription-params-with-run-as-owner"><literal>run_as_owner</literal></link>,
237237
<link linkend="sql-createsubscription-params-with-origin"><literal>origin</literal></link>,
238-
<link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link>, and
239-
<link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>.
238+
<link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link>,
239+
<link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>, and
240+
<link linkend="sql-createsubscription-params-with-retain-conflict-info"><literal>retain_conflict_info</literal></link>.
240241
Only a superuser can set <literal>password_required = false</literal>.
241242
</para>
242243

@@ -285,6 +286,13 @@ ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <
285286
option is changed from <literal>true</literal> to <literal>false</literal>,
286287
the publisher will replicate the transactions again when they are committed.
287288
</para>
289+
290+
<para>
291+
If the <link linkend="sql-createsubscription-params-with-retain-conflict-info"><literal>retain_conflict_info</literal></link>
292+
option is altered to <literal>false</literal> and no other subscription
293+
has this option enabled, the additional replication slot that was created
294+
to retain conflict information will be dropped.
295+
</para>
288296
</listitem>
289297
</varlistentry>
290298

doc/src/sgml/ref/create_subscription.sgml

+32-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
169169
<listitem>
170170
<para>
171171
Name of the publisher's replication slot to use. The default is
172-
to use the name of the subscription for the slot name.
172+
to use the name of the subscription for the slot name. The name cannot
173+
be <literal>pg_conflict_detection</literal>, as it is reserved for
174+
logical replication conflict detection.
173175
</para>
174176

175177
<para>
@@ -435,6 +437,35 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
435437
</para>
436438
</listitem>
437439
</varlistentry>
440+
441+
<varlistentry id="sql-createsubscription-params-with-retain-conflict-info">
442+
<term><literal>retain_conflict_info</literal> (<type>boolean</type>)</term>
443+
<listitem>
444+
<para>
445+
Specifies whether the information (e.g., dead tuples, commit
446+
timestamps, and origins) on the subscriber that is still useful for
447+
conflict detection is retained. The default is
448+
<literal>false</literal>. If set to true, the detection of
449+
<xref linkend="conflict-update-deleted"/> is enabled, and an
450+
additional replication slot named
451+
<quote><literal>pg_conflict_detection</literal></quote> will be
452+
created on the subscriber to prevent the conflict information from
453+
being removed.
454+
</para>
455+
456+
<para>
457+
Note that the information useful for conflict detection is retained
458+
only after the creation of the additional slot. You can verify the
459+
existence of this slot by querying <link linkend="view-pg-replication-slots">pg_replication_slots</link>.<structfield>conflicting</structfield>
460+
And even if multiple subscriptions on one node enable this option,
461+
only one replication slot will be created.
462+
</para>
463+
464+
<para>
465+
This option cannot be enabled if the publisher is also a physical standby.
466+
</para>
467+
</listitem>
468+
</varlistentry>
438469
</variablelist></para>
439470

440471
</listitem>

doc/src/sgml/system-views.sgml

+11
Original file line numberDiff line numberDiff line change
@@ -2936,6 +2936,17 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
29362936
<xref linkend="guc-idle-replication-slot-timeout"/> duration.
29372937
</para>
29382938
</listitem>
2939+
<listitem>
2940+
<para>
2941+
<literal>conflict_retention_exceeds_max_duration</literal> means that
2942+
the duration for retaining conflict information, which is used
2943+
in logical replication conflict detection, has exceeded the maximum
2944+
allowable limit. It is set only for the slot
2945+
<literal>pg_conflict_detection</literal>, which is created when
2946+
<link linkend="sql-createsubscription-params-with-retain-conflict-info"><literal>retain_conflict_info</literal></link>
2947+
is enabled.
2948+
</para>
2949+
</listitem>
29392950
</itemizedlist>
29402951
</para></entry>
29412952
</row>

0 commit comments

Comments
 (0)