aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/src/sgml/catalogs.sgml11
-rw-r--r--doc/src/sgml/config.sgml2
-rw-r--r--doc/src/sgml/func.sgml16
-rw-r--r--doc/src/sgml/indexam.sgml2
-rw-r--r--doc/src/sgml/logical-replication.sgml74
-rw-r--r--doc/src/sgml/protocol.sgml88
-rw-r--r--doc/src/sgml/ref/alter_subscription.sgml18
-rw-r--r--doc/src/sgml/ref/create_subscription.sgml87
-rw-r--r--doc/src/sgml/ref/pg_recvlogical.sgml10
9 files changed, 277 insertions, 31 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 0d23bc1b122..97f547b3cc4 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -8084,6 +8084,17 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
<row>
<entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subretaindeadtuples</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the information (e.g., dead tuples, commit timestamps, and
+ origins) on the subscriber that is useful for conflict detection is
+ retained.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
<structfield>subconninfo</structfield> <type>text</type>
</para>
<para>
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index c7acc0f182f..20ccb2d6b54 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -4965,6 +4965,8 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
new setting.
This setting has no effect if <varname>primary_conninfo</varname> is not
set or the server is not in standby mode.
+ The name cannot be <literal>pg_conflict_detection</literal> as it is
+ reserved for the conflict detection slot.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index f5a0e0954a1..de5b5929ee0 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -29592,7 +29592,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
</para>
<para>
Creates a new physical replication slot named
- <parameter>slot_name</parameter>. The optional second parameter,
+ <parameter>slot_name</parameter>. The name cannot be
+ <literal>pg_conflict_detection</literal> as it is reserved for the
+ conflict detection slot. The optional second parameter,
when <literal>true</literal>, specifies that the <acronym>LSN</acronym> for this
replication slot be reserved immediately; otherwise
the <acronym>LSN</acronym> is reserved on first connection from a streaming
@@ -29636,7 +29638,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<para>
Creates a new logical (decoding) replication slot named
<parameter>slot_name</parameter> using the output plugin
- <parameter>plugin</parameter>. The optional third
+ <parameter>plugin</parameter>. The name cannot be
+ <literal>pg_conflict_detection</literal> as it is reserved for
+ the conflict detection slot. The optional third
parameter, <parameter>temporary</parameter>, when set to true, specifies that
the slot should not be permanently stored to disk and is only meant
for use by the current session. Temporary slots are also
@@ -29666,6 +29670,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
<para>
Copies an existing physical replication slot named <parameter>src_slot_name</parameter>
to a physical replication slot named <parameter>dst_slot_name</parameter>.
+ The new slot name cannot be <literal>pg_conflict_detection</literal>,
+ as it is reserved for the conflict detection.
The copied physical slot starts to reserve WAL from the same <acronym>LSN</acronym> as the
source slot.
<parameter>temporary</parameter> is optional. If <parameter>temporary</parameter>
@@ -29688,8 +29694,10 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
Copies an existing logical replication slot
named <parameter>src_slot_name</parameter> to a logical replication
slot named <parameter>dst_slot_name</parameter>, optionally changing
- the output plugin and persistence. The copied logical slot starts
- from the same <acronym>LSN</acronym> as the source logical slot. Both
+ the output plugin and persistence. The new slot name cannot be
+ <literal>pg_conflict_detection</literal> as it is reserved for
+ the conflict detection. The copied logical slot starts from the same
+ <acronym>LSN</acronym> as the source logical slot. Both
<parameter>temporary</parameter> and <parameter>plugin</parameter> are
optional; if they are omitted, the values of the source slot are used.
The <literal>failover</literal> option of the source logical slot
diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml
index 1aa4741a8ea..63d7e376f19 100644
--- a/doc/src/sgml/indexam.sgml
+++ b/doc/src/sgml/indexam.sgml
@@ -147,7 +147,7 @@ typedef struct IndexAmRoutine
ambuild_function ambuild;
ambuildempty_function ambuildempty;
aminsert_function aminsert;
- aminsertcleanup_function aminsertcleanup;
+ aminsertcleanup_function aminsertcleanup; /* can be NULL */
ambulkdelete_function ambulkdelete;
amvacuumcleanup_function amvacuumcleanup;
amcanreturn_function amcanreturn; /* can be NULL */
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
index e26f7f59d4a..fcac55aefe6 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -1048,28 +1048,28 @@ HINT: To initiate replication, you must manually create the replication slot, e
defined) for each publication.
<programlisting><![CDATA[
/* pub # */ \dRp+
- Publication p1
- Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
-----------+------------+---------+---------+---------+-----------+----------
- postgres | f | t | t | t | t | f
+ Publication p1
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root
+----------+------------+---------+---------+---------+-----------+-------------------+----------
+ postgres | f | t | t | t | t | none | f
Tables:
- "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text))
+ "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text))
- Publication p2
- Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
-----------+------------+---------+---------+---------+-----------+----------
- postgres | f | t | t | t | t | f
+ Publication p2
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root
+----------+------------+---------+---------+---------+-----------+-------------------+----------
+ postgres | f | t | t | t | t | none | f
Tables:
- "public.t1"
- "public.t2" WHERE (e = 99)
+ "public.t1"
+ "public.t2" WHERE (e = 99)
- Publication p3
- Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
-----------+------------+---------+---------+---------+-----------+----------
- postgres | f | t | t | t | t | f
+ Publication p3
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root
+----------+------------+---------+---------+---------+-----------+-------------------+----------
+ postgres | f | t | t | t | t | none | f
Tables:
- "public.t2" WHERE (d = 10)
- "public.t3" WHERE (g = 10)
+ "public.t2" WHERE (d = 10)
+ "public.t3" WHERE (g = 10)
]]></programlisting></para>
<para>
@@ -1491,10 +1491,10 @@ Publications:
for each publication.
<programlisting>
/* pub # */ \dRp+
- Publication p1
- Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
-----------+------------+---------+---------+---------+-----------+----------
- postgres | f | t | t | t | t | f
+ Publication p1
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root
+----------+------------+---------+---------+---------+-----------+-------------------+----------
+ postgres | f | t | t | t | t | none | f
Tables:
"public.t1" (id, a, b, d)
</programlisting></para>
@@ -2397,6 +2397,12 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER
</para>
<para>
+ <link linkend="guc-max-replication-slots"><varname>max_replication_slots</varname></link>
+ must be set to at least 1 when <link linkend="sql-createsubscription-params-with-retain-dead-tuples"><literal>retain_dead_tuples</literal></link>
+ is enabled for any subscription.
+ </para>
+
+ <para>
<link linkend="guc-max-logical-replication-workers"><varname>max_logical_replication_workers</varname></link>
must be set to at least the number of subscriptions (for leader apply
workers), plus some reserve for the table synchronization workers and
@@ -2532,6 +2538,22 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER
dependencies on clusters before version 17.0 will silently be ignored.
</para>
+ <note>
+ <para>
+ Commit timestamps and origin data are not preserved during the upgrade.
+ As a result, even if
+ <link linkend="sql-createsubscription-params-with-retain-dead-tuples"><literal>retain_dead_tuples</literal></link>
+ is enabled, the upgraded subscriber may be unable to detect conflicts or
+ log relevant commit timestamps and origins when applying changes from the
+ publisher occurred before the upgrade. Additionally, immediately after the
+ upgrade, the vacuum may remove the deleted rows that are required for
+ conflict detection. This can affect the changes that were not replicated
+ before the upgrade. To ensure consistent conflict tracking, users should
+ ensure that all potentially conflicting changes are replicated to the
+ subscriber before initiating the upgrade.
+ </para>
+ </note>
+
<para>
There are some prerequisites for <application>pg_upgrade</application> to
be able to upgrade the subscriptions. If these are not met an error
@@ -2563,6 +2585,16 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER
subscriptions present in the old cluster.
</para>
</listitem>
+ <listitem>
+ <para>
+ If there are subscriptions with retain_dead_tuples enabled, the reserved
+ replication slot <quote><literal>pg_conflict_detection</literal></quote>
+ must not exist on the new cluster. Additionally, the
+ <link linkend="guc-wal-level"><varname>wal_level</varname></link> on the
+ new cluster must be set to <literal>replica</literal> or
+ <literal>logical</literal>.
+ </para>
+ </listitem>
</itemizedlist>
</sect2>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index e74b5be1eff..b115884acb3 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -2235,6 +2235,8 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
<para>
The name of the slot to create. Must be a valid replication slot
name (see <xref linkend="streaming-replication-slots-manipulation"/>).
+ The name cannot be <literal>pg_conflict_detection</literal> as it
+ is reserved for the conflict detection.
</para>
</listitem>
</varlistentry>
@@ -2653,6 +2655,65 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
</variablelist>
</listitem>
</varlistentry>
+
+ <varlistentry id="protocol-replication-primary-status-update">
+ <term>Primary status update (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('s')</term>
+ <listitem>
+ <para>
+ Identifies the message as a primary status update.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The latest WAL write position on the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The oldest transaction ID that is currently in the commit phase on
+ the server, along with its epoch. The most significant 32 bits are
+ the epoch. The least significant 32 bits are the transaction ID.
+ If no transactions are active on the server, this number will be
+ the next transaction ID to be assigned.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The next transaction ID to be assigned on the server, along with
+ its epoch. The most significant 32 bits are the epoch. The least
+ significant 32 bits are the transaction ID.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The server's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
</variablelist>
<para>
@@ -2797,6 +2858,33 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
</variablelist>
</listitem>
</varlistentry>
+
+ <varlistentry id="protocol-replication-standby-wal-status-request">
+ <term>Request primary status update (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('p')</term>
+ <listitem>
+ <para>
+ Identifies the message as a request for a primary status update.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The client's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml
index fdc648d007f..d48cdc76bd3 100644
--- a/doc/src/sgml/ref/alter_subscription.sgml
+++ b/doc/src/sgml/ref/alter_subscription.sgml
@@ -235,8 +235,9 @@ ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <
<link linkend="sql-createsubscription-params-with-password-required"><literal>password_required</literal></link>,
<link linkend="sql-createsubscription-params-with-run-as-owner"><literal>run_as_owner</literal></link>,
<link linkend="sql-createsubscription-params-with-origin"><literal>origin</literal></link>,
- <link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link>, and
- <link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>.
+ <link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link>,
+ <link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>, and
+ <link linkend="sql-createsubscription-params-with-retain-dead-tuples"><literal>retain_dead_tuples</literal></link>.
Only a superuser can set <literal>password_required = false</literal>.
</para>
@@ -261,8 +262,9 @@ ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <
</para>
<para>
- The <link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link>
- and <link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>
+ The <link linkend="sql-createsubscription-params-with-failover"><literal>failover</literal></link>,
+ <link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>, and
+ <link linkend="sql-createsubscription-params-with-retain-dead-tuples"><literal>retain_dead_tuples</literal></link>
parameters can only be altered when the subscription is disabled.
</para>
@@ -285,6 +287,14 @@ ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <
option is changed from <literal>true</literal> to <literal>false</literal>,
the publisher will replicate the transactions again when they are committed.
</para>
+
+ <para>
+ If the <link linkend="sql-createsubscription-params-with-retain-dead-tuples"><literal>retain_dead_tuples</literal></link>
+ option is altered to <literal>false</literal> and no other subscription
+ has this option enabled, the replication slot named
+ <quote><literal>pg_conflict_detection</literal></quote>, created to retain
+ dead tuples for conflict detection, will be dropped.
+ </para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml
index 57dec28a5df..b8cd15f3280 100644
--- a/doc/src/sgml/ref/create_subscription.sgml
+++ b/doc/src/sgml/ref/create_subscription.sgml
@@ -169,7 +169,9 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
<listitem>
<para>
Name of the publisher's replication slot to use. The default is
- to use the name of the subscription for the slot name.
+ to use the name of the subscription for the slot name. The name cannot
+ be <literal>pg_conflict_detection</literal> as it is reserved for the
+ conflict detection.
</para>
<para>
@@ -435,6 +437,89 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
</para>
</listitem>
</varlistentry>
+
+ <varlistentry id="sql-createsubscription-params-with-retain-dead-tuples">
+ <term><literal>retain_dead_tuples</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+
+ <para>
+ Note that the information useful for conflict detection is retained
+ only after the creation of the slot. You can verify the existence of
+ this slot by querying <link linkend="view-pg-replication-slots">pg_replication_slots</link>.
+ And even if multiple subscriptions on one node enable this option,
+ only one replication slot will be created. Also,
+ <varname>wal_level</varname> must be set to <literal>replica</literal>
+ or higher to allow the replication slot to be used.
+ </para>
+
+ <caution>
+ <para>
+ Note that the information for conflict detection cannot be purged if
+ the subscription is disabled; thus, the information will accumulate
+ until the subscription is enabled. To prevent excessive accumulation,
+ it is recommended to disable <literal>retain_dead_tuples</literal>
+ if the subscription will be inactive for an extended period.
+ </para>
+
+ <para>
+ Additionally when enabling <literal>retain_dead_tuples</literal> for
+ conflict detection in logical replication, it is important to design the
+ replication topology to balance data retention requirements with
+ overall system performance. This option provides minimal performance
+ overhead when applied appropriately. The following scenarios illustrate
+ effective usage patterns when enabling this option.
+ </para>
+
+ <para>
+ a. Large Tables with Bidirectional Writes:
+ For large tables subject to concurrent writes on both publisher and
+ subscriber nodes, publishers can define row filters when creating
+ publications to segment data. This allows multiple subscriptions
+ to replicate exclusive subsets of the table in parallel, optimizing
+ the throughput.
+ </para>
+
+ <para>
+ b. Write-Enabled Subscribers:
+ If a subscriber node is expected to perform write operations, replication
+ can be structured using multiple publications and subscriptions. By
+ distributing tables across these publications, the workload is spread among
+ several apply workers, improving concurrency and reducing contention.
+ </para>
+
+ <para>
+ c. Read-Only Subscribers:
+ In configurations involving single or multiple publisher nodes
+ performing concurrent write operations, read-only subscriber nodes may
+ replicate changes without seeing a performance impact if it does index
+ scan. However, if the subscriber is impacted due to replication lag or
+ scan performance (say due to sequential scans), it needs to follow one
+ of the two previous strategies to distribute the workload on the
+ subscriber.
+ </para>
+ </caution>
+
+ <para>
+ This option cannot be enabled if the publisher is a physical standby.
+ </para>
+
+ <para>
+ Enabling this option ensures retention of information useful for
+ conflict detection solely for changes occurring locally on the
+ publisher. For the changes originating from different origins,
+ reliable conflict detection cannot be guaranteed.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist></para>
</listitem>
diff --git a/doc/src/sgml/ref/pg_recvlogical.sgml b/doc/src/sgml/ref/pg_recvlogical.sgml
index f68182266a9..263ebdeeab4 100644
--- a/doc/src/sgml/ref/pg_recvlogical.sgml
+++ b/doc/src/sgml/ref/pg_recvlogical.sgml
@@ -53,6 +53,16 @@ PostgreSQL documentation
(<keycombo action="simul"><keycap>Control</keycap><keycap>C</keycap></keycombo>)
or <systemitem>SIGTERM</systemitem> signal.
</para>
+
+ <para>
+ When <application>pg_recvlogical</application> receives
+ a <systemitem>SIGHUP</systemitem> signal, it closes the current output file
+ and opens a new one using the filename specified by
+ the <option>--file</option> option. This allows us to rotate
+ the output file by first renaming the current file and then sending
+ a <systemitem>SIGHUP</systemitem> signal to
+ <application>pg_recvlogical</application>.
+ </para>
</refsect1>
<refsect1>