1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Introduce replication slots.

Replication slots are a crash-safe data structure which can be created
on either a master or a standby to prevent premature removal of
write-ahead log segments needed by a standby, as well as (with
hot_standby_feedback=on) pruning of tuples whose removal would cause
replication conflicts.  Slots have some advantages over existing
techniques, as explained in the documentation.

In a few places, we refer to the type of replication slots introduced
by this patch as "physical" slots, because forthcoming patches for
logical decoding will also have slots, but with somewhat different
properties.

Andres Freund and Robert Haas
This commit is contained in:
Robert Haas
2014-01-31 22:45:17 -05:00
parent 5bdef38b89
commit 858ec11858
42 changed files with 2356 additions and 62 deletions

View File

@@ -233,6 +233,11 @@
<entry>query rewrite rules</entry>
</row>
<row>
<entry><link linkend="catalog-pg-replication-slots"><structname>pg_replication_slots</structname></link></entry>
<entry>replication slot information</entry>
</row>
<row>
<entry><link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link></entry>
<entry>security labels on database objects</entry>
@@ -5157,6 +5162,100 @@
</sect1>
<sect1 id="catalog-pg-replication-slots">
<title><structname>pg_replication_slots</structname></title>
<indexterm zone="catalog-pg-replication-slots">
<primary>pg_replication_slots</primary>
</indexterm>
<para>
The <structname>pg_replication_slots</structname> view provides a listing
of all replication slots that currently exist on the database cluster,
along with their current state.
</para>
<para>
For more on replication slots,
see <xref linkend="streaming-replication-slots">.
</para>
<table>
<title><structname>pg_replication_slots</structname> Columns</title>
<tgroup cols="4">
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><structfield>slot_name</structfield></entry>
<entry><type>text</type></entry>
<entry></entry>
<entry>A unique, cluster-wide identifier for the replication slot</entry>
</row>
<row>
<entry><structfield>slot_type</structfield></entry>
<entry><type>text</type></entry>
<entry></entry>
<entry>The slot type - <literal>physical</> or <literal>logical</></entry>
</row>
<row>
<entry><structfield>datoid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-database"><structname>pg_database</structname></link>.oid</literal></entry>
<entry>The oid of the database this slot is associated with, or
null. Only logical slots have an associated database.</entry>
</row>
<row>
<entry><structfield>database</structfield></entry>
<entry><type>text</type></entry>
<entry><literal><link linkend="catalog-pg-database"><structname>pg_database</structname></link>.datname</literal></entry>
<entry>The name of the database this slot is associated with, or
null. Only logical slots have an associated database.</entry>
</row>
<row>
<entry><structfield>active</structfield></entry>
<entry><type>boolean</type></entry>
<entry></entry>
<entry>True if this slot is currently actively being used</entry>
</row>
<row>
<entry><structfield>xmin</structfield></entry>
<entry><type>xid</type></entry>
<entry></entry>
<entry>The oldest transaction that this slot needs the database to
retain. <literal>VACUUM</literal> cannot remove tuples deleted
by any later transaction.
</entry>
</row>
<row>
<entry><structfield>restart_lsn</structfield></entry>
<entry><type>text</type></entry>
<entry></entry>
<entry>The address (<literal>LSN</literal>) of oldest WAL which still
might be required by the consumer of this slot and thus won't be
automatically removed during checkpoints.
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="catalog-pg-seclabel">
<title><structname>pg_seclabel</structname></title>

View File

@@ -2348,6 +2348,25 @@ include 'filename'
</listitem>
</varlistentry>
<varlistentry id="guc-max-replication-slots" xreflabel="max_replication_slots">
<term><varname>max_replication_slots</varname> (<type>integer</type>)</term>
<indexterm>
<primary><varname>max_replication_slots</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies the maximum number of replication slots
(see <xref linkend="streaming-replication-slots"> that the server
can support. The default is zero. This parameter can only be set at
server start.
<varname>wal_level</varname> must be set
to <literal>archive</literal> or higher to allow replication slots to
be used. Setting it to a lower value than the number of currently
existing replication slots will prevent the server from starting.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-wal-keep-segments" xreflabel="wal_keep_segments">
<term><varname>wal_keep_segments</varname> (<type>integer</type>)</term>
<indexterm>

View File

@@ -16290,6 +16290,76 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
</para>
</sect2>
<sect2 id="functions-replication">
<title>Replication Functions</title>
<para>
PostgreSQL exposes a number of functions for controlling and interacting
with replication features. See <xref linkend="streaming-replication">
and <xref linkend="streaming-replication-slots">.
</para>
<para>
Many of these functions have equivalent commands in the replication
protocol; see <xref linkend="protocol-replication">.
</para>
<para>
The sections <xref linkend="functions-snapshot-synchronization">, <xref
linkend="functions-recovery-control"> and <xref
linkend="functions-admin-backup"> are also relevant for replication.
</para>
<table id="functions-replication-table">
<title>Replication <acronym>SQL</acronym> Functions</title>
<tgroup cols="3">
<thead>
<row>
<entry>Function</entry>
<entry>Return Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<indexterm>
<primary>pg_create_physical_replication_slot</primary>
</indexterm>
<literal><function>pg_create_physical_replication_slot(<parameter>slotname</parameter> <type>text</type>, <parameter>plugin</parameter> <type>text</type>)</function></literal>
</entry>
<entry>
(<parameter>slotname</parameter> <type>text</type>, <parameter>xlog_position</parameter> <type>text</type>)
</entry>
<entry>
Creates a new physical replication slot named
<parameter>slotname</parameter>. Streaming changes from a physical slot
is only possible with the walsender protocol - see <xref
linkend="protocol-replication">. Corresponds to the walsender protocol
command <literal>CREATE_REPLICATION_SLOT ... PHYSICAL</literal>.
</entry>
</row>
<row>
<entry>
<indexterm>
<primary>pg_drop_replication_slot</primary>
</indexterm>
<literal><function>pg_drop_replication_slot(<parameter>slotname</parameter> <type>text</type>)</function></literal>
</entry>
<entry>
(<parameter>slotname</parameter> <type>text</type>)
</entry>
<entry>
Drops the physical or logical replication slot
named <parameter>slotname</parameter>. Same as walsender protocol
command <literal>DROP_REPLICATION_SLOT</>.
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
<sect2 id="functions-admin-dbobject">
<title>Database Object Management Functions</title>

View File

@@ -643,7 +643,9 @@ protocol to make nodes agree on a serializable transactional order.
entries in <filename>pg_hba.conf</> with the database field set to
<literal>replication</>. Also ensure <varname>max_wal_senders</> is set
to a sufficiently large value in the configuration file of the primary
server.
server. If replication slots will be used,
ensure that <varname>max_replication_slots</varname> is set sufficiently
high as well.
</para>
<para>
@@ -750,13 +752,14 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'
<para>
If you use streaming replication without file-based continuous
archiving, you have to set <varname>wal_keep_segments</> in the master
to a value high enough to ensure that old WAL segments are not recycled
too early, while the standby might still need them to catch up. If the
standby falls behind too much, it needs to be reinitialized from a new
base backup. If you set up a WAL archive that's accessible from the
standby, <varname>wal_keep_segments</> is not required as the standby can always
use the archive to catch up.
archiving, the server might recycle old WAL segments before the standby
has received them. If this occurs, the standby will need to be
reinitialized from a new base backup. You can avoid this by setting
<varname>wal_keep_segments</> to a value large enough to ensure that
WAL segments are not recycled too early, or by configuration a replication
slot for the standby. If you set up a WAL archive that's accessible from
the standby, these solutions are not required, since the standby can
always use the archive to catch up provided it retains enough segments.
</para>
<para>
@@ -871,6 +874,81 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
</sect3>
</sect2>
<sect2 id="streaming-replication-slots">
<title>Replication Slots</title>
<indexterm zone="high-availability">
<primary>Replication Slots</primary>
</indexterm>
<para>
Replication slots provide an automated way to ensure that the master does
not remove WAL segments until they have been received by all standbys,
and that the master does not remove rows which could cause a
<link linkend="hot-standby-conflict">recovery conflict</> even when the
standby is disconnected.
</para>
<para>
In lieu of using replication slots, it is possible to prevent the removal
of old WAL segments using <xref linkend="guc-wal-keep-segments">, or by
storing the segments in an archive using <xref linkend="restore-command">.
However, these methods often result in retaining more WAL segments than
required, whereas replication slots retain only the number of segments
known to be needed. An advantage of these methods is that they bound
the space requirement for <literal>pg_xlog</>; there is currently no way
to do this using replication slots.
</para>
<para>
Similarly, <varname>hot_standby_feedback</varname>
and <varname>vacuum_defer_cleanup_age</varname> provide protection against
relevant rows being removed by vacuum, but the former provides no
protection during any time period when the standby is not connected,
and the latter often needs to be set to a high value to provide adequate
protection. Replication slots overcome these disadvantages.
</para>
<sect3 id="streaming-replication-slots-manipulation">
<title>Querying and manipulating replication slots</title>
<para>
Each replication slot has a name, which can contain lower-case letters,
numbers, and the underscore character.
</para>
<para>
Existing replication slots and their state can be seen in the
<link linkend="catalog-pg-replication-slots"><structname>pg_replication_slots</structname></link>
view.
</para>
<para>
Slots can be created and dropped either via the streaming replication
protocol (see <xref linkend="protocol-replication">) or via SQL
functions (see <xref linkend="functions-replication">).
</para>
</sect3>
<sect3 id="streaming-replication-slots-config">
<title>Configuration Example</title>
<para>
You can create a replication slot like this:
<programlisting>
postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
slotname | xlog_position
-------------+---------------
node_a_slot |
postgres=# SELECT * FROM pg_replication_slots;
slot_name | slot_type | datoid | database | active | xmin | restart_lsn
-------------+-----------+--------+----------+--------+------+-------------
node_a_slot | physical | 0 | | f | |
(1 row)
</programlisting>
To configure the standby to use this slot, <varname>primary_slotname</>
should be configured in the standby's <filename>recovery.conf</>.
Here is a simple example:
<programlisting>
standby_mode = 'on'
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
primary_slotname = 'node_a_slot'
</programlisting>
</para>
</sect3>
</sect2>
<sect2 id="cascading-replication">
<title>Cascading Replication</title>

View File

@@ -1401,15 +1401,39 @@ The commands accepted in walsender mode are:
</varlistentry>
<varlistentry>
<term>START_REPLICATION <replaceable class="parameter">XXX/XXX</> TIMELINE <replaceable class="parameter">tli</></term>
<term><literal>CREATE_REPLICATION_SLOT</literal> <replaceable class="parameter">slotname</> <literal>PHYSICAL</literal></term>
<indexterm><primary>CREATE_REPLICATION_SLOT</primary></indexterm>
<listitem>
<para>
Create a physical replication
slot. See <xref linkend="streaming-replication-slots"> for more about
replication slots.
</para>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">slotname</></term>
<listitem>
<para>
The name of the slot to create. Must be a valid replication slot
name (see <xref linkend="streaming-replication-slots-manipulation">).
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>START_REPLICATION</literal> [<literal>SLOT</literal> <replaceable class="parameter">slotname</>] [<literal>PHYSICAL</literal>] <replaceable class="parameter">XXX/XXX</> <literal>TIMELINE</literal> <replaceable class="parameter">tli</></term>
<listitem>
<para>
Instructs server to start streaming WAL, starting at
WAL position <replaceable class="parameter">XXX/XXX</> on timeline
<replaceable class="parameter">tli</>.
The server can reply with an error, e.g. if the requested section of WAL
has already been recycled. On success, server responds with a
CopyBothResponse message, and then starts to stream WAL to the frontend.
WAL position <replaceable class="parameter">XXX/XXX</>. If specified,
streaming starts on timeline <replaceable class="parameter">tli</>;
otherwise, the server's current timeline is selected. The server can
reply with an error, e.g. if the requested section of WAL has already
been recycled. On success, server responds with a CopyBothResponse
message, and then starts to stream WAL to the frontend.
</para>
<para>
@@ -1443,6 +1467,14 @@ The commands accepted in walsender mode are:
client contains a message of one of the following formats:
</para>
<para>
If a slot's name is provided
via <replaceable class="parameter">slotname</>, it will be updated
as replication progresses so that the server knows which WAL segments -
and if <varname>hot_standby_feedback</> is on which transactions -
are still needed by the standby.
</para>
<para>
<variablelist>
<varlistentry>
@@ -1719,6 +1751,26 @@ The commands accepted in walsender mode are:
</listitem>
</varlistentry>
<varlistentry>
<term><literal>DROP_REPLICATION_SLOT</literal> <replaceable class="parameter">slotname</></term>
<listitem>
<para>
Drops a replication slot, freeing any reserved server-side resources. If
the slot is currently in use by an active connection, this command fails.
</para>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">slotname</></term>
<listitem>
<para>
The name of the slot to drop.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>BASE_BACKUP [<literal>LABEL</literal> <replaceable>'label'</replaceable>] [<literal>PROGRESS</literal>] [<literal>FAST</literal>] [<literal>WAL</literal>] [<literal>NOWAIT</literal>]</term>
<listitem>

View File

@@ -418,6 +418,22 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
</para>
</listitem>
</varlistentry>
<varlistentry id="primary-slotname" xreflabel="primary_slotname">
<term><varname>primary_slotname</varname> (<type>string</type>)</term>
<indexterm>
<primary><varname>primary_slotname</> recovery parameter</primary>
</indexterm>
<listitem>
<para>
Optionally specifies an existing replication slot to be used when
connecting to the primary via streaming replication to control
resource removal on the upstream node
(see <xref linkend="streaming-replication-slots">).
This setting has no effect if <varname>primary_conninfo</> is not
set.
</para>
</listitem>
</varlistentry>
<varlistentry id="trigger-file" xreflabel="trigger_file">
<term><varname>trigger_file</varname> (<type>string</type>)</term>
<indexterm>

View File

@@ -225,6 +225,24 @@ PostgreSQL documentation
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--slot</option></term>
<listitem>
<para>
Require <application>pg_receivexlog</application> to use an existing
replication slot (see <xref linkend="streaming-replication-slots">).
When this option is used, <application>pg_receivexlog</> will report
a flush position to the server, indicating when each segment has been
synchronized to disk so that the server can remove that segment if it
is not otherwise needed. When using this paramter, it is important
to make sure that <application>pg_receivexlog</> cannot become the
synchronous standby through an incautious setting of
<xref linkend="guc-synchronous-standby-names">; it does not flush
data frequently enough for this to work correctly.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>