1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Logical replication

- Add PUBLICATION catalogs and DDL
- Add SUBSCRIPTION catalog and DDL
- Define logical replication protocol and output plugin
- Add logical replication workers

From: Petr Jelinek <petr@2ndquadrant.com>
Reviewed-by: Steve Singer <steve@ssinger.info>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Erik Rijkers <er@xs4all.nl>
Reviewed-by: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
This commit is contained in:
Peter Eisentraut
2017-01-19 12:00:00 -05:00
parent ba61a04bc7
commit 665d1fad99
119 changed files with 13354 additions and 95 deletions

View File

@ -240,6 +240,16 @@
<entry>functions and procedures</entry>
</row>
<row>
<entry><link linkend="catalog-pg-publication"><structname>pg_publication</structname></link></entry>
<entry>publications for logical replication</entry>
</row>
<row>
<entry><link linkend="catalog-pg-publication-rel"><structname>pg_publication_rel</structname></link></entry>
<entry>relation to publication mapping</entry>
</row>
<row>
<entry><link linkend="catalog-pg-range"><structname>pg_range</structname></link></entry>
<entry>information about range types</entry>
@ -285,6 +295,11 @@
<entry>planner statistics</entry>
</row>
<row>
<entry><link linkend="catalog-pg-subscription"><structname>pg_subscription</structname></link></entry>
<entry>logical replication subscriptions</entry>
</row>
<row>
<entry><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link></entry>
<entry>tablespaces within this database cluster</entry>
@ -5271,6 +5286,137 @@
</sect1>
<sect1 id="catalog-pg-publication">
<title><structname>pg_publication</structname></title>
<indexterm zone="catalog-pg-publication">
<primary>pg_publication</primary>
</indexterm>
<para>
The catalog <structname>pg_publication</structname> contains all
publications created in the database. For more on publications see
<xref linkend="logical-replication-publication">.
</para>
<table>
<title><structname>pg_publication</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>oid</structfield></entry>
<entry><type>oid</type></entry>
<entry></entry>
<entry>Row identifier (hidden attribute; must be explicitly selected)</entry>
</row>
<row>
<entry><structfield>pubname</structfield></entry>
<entry><type>Name</type></entry>
<entry></entry>
<entry>Name of the publication</entry>
</row>
<row>
<entry><structfield>pubowner</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the publication</entry>
</row>
<row>
<entry><structfield>puballtables</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>If true, this publication automatically includes all tables
in the database, including any that will be created in the future.
</entry>
</row>
<row>
<entry><structfield>pubinsert</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>If true, <command>INSERT</command> operations are replicated for
tables in the publication.</entry>
</row>
<row>
<entry><structfield>pubupdate</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>If true, <command>UPDATE</command> operations are replicated for
tables in the publication.</entry>
</row>
<row>
<entry><structfield>pubdelete</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>If true, <command>DELETE</command> operations are replicated for
tables in the publication.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="catalog-pg-publication-rel">
<title><structname>pg_publication_rel</structname></title>
<indexterm zone="catalog-pg-publication-rel">
<primary>pg_publication_rel</primary>
</indexterm>
<para>
The catalog <structname>pg_publication_rel</structname> contains the
mapping between relations and publications in the database. This is a
many-to-many mapping. See also <xref linkend="view-pg-publication-tables">
for a more user-friendly view of this information.
</para>
<table>
<title><structname>pg_publication_rel</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>prpubid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-publication"><structname>pg_publication</structname></link>.oid</literal></entry>
<entry>Reference to publication</entry>
</row>
<row>
<entry><structfield>prrelid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
<entry>Reference to relation</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="catalog-pg-range">
<title><structname>pg_range</structname></title>
@ -6150,6 +6296,109 @@
</sect1>
<sect1 id="catalog-pg-subscription">
<title><structname>pg_subscription</structname></title>
<indexterm zone="catalog-pg-subscription">
<primary>pg_subscription</primary>
</indexterm>
<para>
The catalog <structname>pg_subscription</structname> contains all existing
logical replication subscriptions. For more information about logical
replication see <xref linkend="logical-replication">.
</para>
<para>
Unlike most system catalogs, <structname>pg_subscription</structname> is
shared across all databases of a cluster: There is only one copy
of <structname>pg_subscription</structname> per cluster, not one per
database.
</para>
<para>
Access to this catalog is restricted from normal users. Normal users can
use the view <xref linkend="pg-stat-subscription"> to get some information
about subscriptions.
</para>
<table>
<title><structname>pg_subscription</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>oid</structfield></entry>
<entry><type>oid</type></entry>
<entry></entry>
<entry>Row identifier (hidden attribute; must be explicitly selected)</entry>
</row>
<row>
<entry><structfield>subdbid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-database"><structname>pg_database</structname></link>.oid</literal></entry>
<entry>OID of the database which the subscription resides in</entry>
</row>
<row>
<entry><structfield>subname</structfield></entry>
<entry><type>name</type></entry>
<entry></entry>
<entry>Name of the subscription</entry>
</row>
<row>
<entry><structfield>subowner</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the subscription</entry>
</row>
<row>
<entry><structfield>subenabled</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>If true, the subscription is enabled and should be replicating.</entry>
</row>
<row>
<entry><structfield>subconninfo</structfield></entry>
<entry><type>text</type></entry>
<entry></entry>
<entry>Connection string to the upstream database</entry>
</row>
<row>
<entry><structfield>subslotname</structfield></entry>
<entry><type>name</type></entry>
<entry></entry>
<entry>Name of the replication slot in the upstream database. Also used
for local replication origin name.</entry>
</row>
<row>
<entry><structfield>subpublications</structfield></entry>
<entry><type>text[]</type></entry>
<entry></entry>
<entry>Array of subscribed publication names. These reference the
publications on the publisher server. For more on publications
see <xref linkend="logical-replication-publication">.
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="catalog-pg-tablespace">
<title><structname>pg_tablespace</structname></title>
@ -7589,6 +7838,11 @@
<entry>prepared transactions</entry>
</row>
<row>
<entry><link linkend="view-pg-publication-tables"><structname>pg_publication_tables</structname></link></entry>
<entry>publications and their associated tables</entry>
</row>
<row>
<entry><link linkend="view-pg-replication-origin-status"><structname>pg_replication_origin_status</structname></link></entry>
<entry>information about replication origins, including replication progress</entry>
@ -8871,6 +9125,61 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
</sect1>
<sect1 id="view-pg-publication-tables">
<title><structname>pg_publication_tables</structname></title>
<indexterm zone="view-pg-publication-tables">
<primary>pg_publication_tables</primary>
</indexterm>
<para>
The view <structname>pg_publication_tables</structname> provides
information about the mapping between publications and the tables they
contain. Unlike the underlying
catalog <structname>pg_publication_rel</structname>, this view expands
publications defined as <literal>FOR ALL TABLES</literal>, so for such
publications there will be a row for each eligible table.
</para>
<table>
<title><structname>pg_publication_tables</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>pubname</structfield></entry>
<entry><type>name</type></entry>
<entry><literal><link linkend="catalog-pg-publication"><structname>pg_publication</structname></link>.pubname</literal></entry>
<entry>Name of publication</entry>
</row>
<row>
<entry><structfield>schemaname</structfield></entry>
<entry><type>name</type></entry>
<entry><literal><link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.nspname</literal></entry>
<entry>Name of schema containing table</entry>
</row>
<row>
<entry><structfield>tablename</structfield></entry>
<entry><type>name</type></entry>
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.relname</literal></entry>
<entry>Name of table</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="view-pg-replication-origin-status">
<title><structname>pg_replication_origin_status</structname></title>

View File

@ -3411,6 +3411,47 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
</variablelist>
</sect2>
<sect2 id="runtime-config-replication-subscriber">
<title>Subscribers</title>
<para>
These settings control the behavior of a logical replication subscriber.
Their values on the publisher are irrelevant.
</para>
<para>
Note that <varname>wal_receiver_timeout</varname> and
<varname>wal_retrieve_retry_interval</varname> configuration parameters
affect the logical replication workers as well.
</para>
<variablelist>
<varlistentry id="guc-max-logical-replication-workers" xreflabel="max_logical_replication_workers">
<term><varname>max_logical_replication_workers</varname> (<type>int</type>)
<indexterm>
<primary><varname>max_logical_replication_workers</> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Specifies maximum number of logical replication workers. This includes
both apply workers and table synchronization workers.
</para>
<para>
Logical replication workers are taken from the pool defined by
<varname>max_worker_processes</varname>.
</para>
<para>
The default value is 4.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1>
<sect1 id="runtime-config-query">

View File

@ -50,6 +50,7 @@
<!ENTITY config SYSTEM "config.sgml">
<!ENTITY user-manag SYSTEM "user-manag.sgml">
<!ENTITY wal SYSTEM "wal.sgml">
<!ENTITY logical-replication SYSTEM "logical-replication.sgml">
<!-- programmer's guide -->
<!ENTITY bgworker SYSTEM "bgworker.sgml">

View File

@ -18762,7 +18762,7 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
</row>
<row>
<entry>
<entry id="pg-replication-origin-advance">
<indexterm>
<primary>pg_replication_origin_advance</primary>
</indexterm>

View File

@ -0,0 +1,396 @@
<!-- doc/src/sgml/logical-replication.sgml -->
<chapter id="logical-replication">
<title>Logical Replication</title>
<para>
Logical replication is a method of replicating data objects and their
changes, based upon their replication identity (usually a primary key). We
use the term logical in contrast to physical replication, which uses exact
block addresses and byte-by-byte replication. PostgreSQL supports both
mechanisms concurrently, see <xref linkend="high-availability">. Logical
replication allows fine-grained control over both data replication and
security.
</para>
<para>
Logical replication uses a <firstterm>publish</firstterm>
and <firstterm>subscribe</firstterm> model with one or
more <firstterm>subscribers</firstterm> subscribing to one or more
<firstterm>publications</firstterm> on a <firstterm>publisher</firstterm>
node. Subscribers pull data from the publications they subscribe to and may
subsequently re-publish data to allow cascading replication or more complex
configurations.
</para>
<para>
Logical replication sends the changes on the publisher to the subscriber as
they occur in real-time. The subscriber applies the data in the same order
as the publisher so that transactional consistency is guaranteed for
publications within a single subscription. This method of data replication
is sometimes referred to as transactional replication.
</para>
<para>
The typical use-cases for logical replication are:
<itemizedlist>
<listitem>
<para>
Sending incremental changes in a single database or a subset of a
database to subscribers as they occur.
</para>
</listitem>
<listitem>
<para>
Firing triggers for individual changes as they are incoming to
subscriber.
</para>
</listitem>
<listitem>
<para>
Consolidating multiple databases into a single one (for example for
analytical purposes).
</para>
</listitem>
<listitem>
<para>
Replicating between different major versions of PostgreSQL.
</para>
</listitem>
<listitem>
<para>
Giving access to replicated data to different groups of users.
</para>
</listitem>
<listitem>
<para>
Sharing a subset of the database between multiple databases.
</para>
</listitem>
</itemizedlist>
</para>
<para>
The subscriber database behaves in the same way as any other PostgreSQL
instance and can be used as a publisher for other databases by defining its
own publications. When the subscriber is treated as read-only by
application, there will be no conflicts from a single subscription. On the
other hand, if there are other writes done either by application or other
subscribers to the same set of tables conflicts can arise.
</para>
<sect1 id="logical-replication-publication">
<title>Publication</title>
<para>
A <firstterm>publication</firstterm> object can be defined on any physical
replication master. The node where a publication is defined is referred to
as <firstterm>publisher</firstterm>. A publication is a set of changes
generated from a group of tables, and might also be described as a change
set or replication set. Each publication exists in only one database.
</para>
<para>
Publications are different from schemas and do not affect how the table is
accessed. Each table can be added to multiple publications if needed.
Publications may currently only contain tables. Objects must be added
explicitly, except when a publication is created for <literal>ALL
TABLES</literal>.
</para>
<para>
Publications can choose to limit the changes they produce to show
any combination of <command>INSERT</command>, <command>UPDATE</command>, and
<command>DELETE</command> in a similar way to the way triggers are fired by
particular event types. If a table without a <literal>REPLICA
IDENTITY</literal> is added to a publication that
replicates <command>UPDATE</command> or <command>DELETE</command>
operations then subsequent <command>UPDATE</command>
or <command>DELETE</command> operations will fail on the publisher.
</para>
<para>
Every publication can have multiple subscribers.
</para>
<para>
A publication is created using the <xref linkend="sql-createpublication">
command and may be later altered or dropped using corresponding commands.
</para>
<para>
The individual tables can be added and removed dynamically using
<xref linkend="sql-alterpublication">. Both the <literal>ADD
TABLE</literal> and <literal>DROP TABLE</literal> operations are
transactional; so the table will start or stop replicating at the correct
snapshot once the transaction has committed.
</para>
</sect1>
<sect1 id="logical-replication-subscription">
<title>Subscription</title>
<para>
A <firstterm>subscription</firstterm> is the downstream side of logical
replication. The node where a subscription is defined is referred to as
the <firstterm>subscriber</firstterm>. Subscription defines the connection
to another database and set of publications (one or more) to which it wants
to be subscribed.
</para>
<para>
The subscriber database behaves in the same way as any other PostgreSQL
instance and can be used as a publisher for other databases by defining its
own publications.
</para>
<para>
A subscriber node may have multiple subscriptions if desired. It is
possible to define multiple subscriptions between a single
publisher-subscriber pair, in which case extra care must be taken to ensure
that the subscribed publication objects don't overlap.
</para>
<para>
Each subscription will receive changes via one replication slot (see
<xref linkend="streaming-replication-slots">).
</para>
<para>
Subscriptions are not dumped by <command>pg_dump</command> by default but
can be requested using the command-line
option <option>--subscriptions</option>.
</para>
<para>
The subscription is added using <xref linkend="sql-createsubscription"> and
can be stopped/resumed at any time using the
<xref linkend="sql-altersubscription"> command and removed using
<xref linkend="sql-dropsubscription">.
</para>
<para>
When a subscription is dropped and recreated, the synchronization
information is lost. This means that the data has to be resynchronized
afterwards.
</para>
<para>
The schema definitions are not replicated and the published tables must
exist on the subsriber for replication to work. Only regular tables may be
the target of replication. For example, you can't replicate to a view.
</para>
<para>
The tables are matched between the publisher and the subscriber using the
fully qualified table name. Replication to differently-named tables on the
subscriber is not supported.
</para>
<para>
Columns of a table are also matched by name. A different order of columns
in the target table is allowed, but the column types have to match.
</para>
</sect1>
<sect1 id="logical-replication-conflicts">
<title>Conflicts</title>
<para>
The logical replication behaves similarly to normal DML operations in that
the data will be updated even if it was changed locally on the subscriber
node. If the incoming data violates any constraints the replication will
stop. This is referred to as a <firstterm>conflict</firstterm>. When
replicating <command>UPDATE</command> or <command>DELETE</command>
operations, missing data will not produce a conflict and such operations
will simply be skipped.
</para>
<para>
A conflict will produce an error and 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 on the subscriber so
that it does not conflict with the incoming change or by skipping the
transaction that conflicts with the existing data. The transaction can be
skipped by calling the <link linkend="pg-replication-origin-advance">
<function>pg_replication_origin_advance()</function></link> function with
a <parameter>node_name</parameter> corresponding to the subscription name.
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.
</para>
</sect1>
<sect1 id="logical-replication-architecture">
<title>Architecture</title>
<para>
Logical replication starts by copying a snapshot of the data on the
publisher database. Once that is done, changes on the publisher are sent
to the subscriber as they occur in real time. The subscriber applies data
in the order in which commits were made on the publisher so that
transactional consistency is guaranteed for the publications within any
single subscription.
</para>
<para>
Logical replication is built with an architecture similar to physical
streaming replication (see <xref linkend="streaming-replication">). It is
implemented by <quote>walsender</quote> and the <quote>apply</quote>
processes. The walsender starts logical decoding (described
in <xref linkend="logicaldecoding">) of the WAL and loads the standard
logical decoding plugin (pgoutput). The plugin transforms the changes read
from WAL to the logical replication protocol
(see <xref linkend="protocol-logical-replication">) and filters the data
according to the publication specification. The data is then continuously
transferred using the streaming replication protocol to the apply worker,
which maps the data to local tables and applies the individual changes as
they are received in exact transactional order.
</para>
<para>
The apply process on the subscriber database always runs with
<varname>session_replication_role</varname> set
to <literal>replica</literal>, which produces the usual effects on triggers
and constraints.
</para>
</sect1>
<sect1 id="logical-replication-monitoring">
<title>Monitoring</title>
<para>
Because logical replication is based on similar architecture as
<link linkend="streaming-replication">physical streaming replication</link>
the monitoring on a publication node is very similar to monitoring of
physical replication master
(see <xref linkend="streaming-replication-monitoring">).
</para>
<para>
The monitoring information about subscription is visible in
<link linkend="pg-stat-subscription"><literal>pg_stat_subscription</literal></link>.
This view contains one row for every subscription worker. A subscription
can have zero or more active subscription workers depending on its state.
</para>
<para>
Normally, there is a single apply process running for an enabled
subscription. A disabled subscription or a crashed subscription will have
zero rows in this view.
</para>
</sect1>
<sect1 id="logical-replication-security">
<title>Security</title>
<para>
Logical replication connections occur in the same way as physical streaming
replication. It requires access to be specifically given using
<filename>pg_hba.conf</filename>. The role used for the replication
connection must have the <literal>REPLICATION</literal> attribute. This
gives a role access to both logical and physical replication.
</para>
<para>
To create a publication, the user must have the <literal>CREATE</literal>
privilege in the database.
</para>
<para>
To create a subscription, the user must be a superuser.
</para>
<para>
The subscription apply process will run in the local database with the
privileges of a superuser.
</para>
<para>
Privileges are only checked once at the start of a replication connection.
They are not re-checked as each change record is read from the publisher,
nor are they re-checked for each change when applied.
</para>
</sect1>
<sect1 id="logical-replication-config">
<title>Configuration Settings</title>
<para>
Logical replication requires several configuration options to be set.
</para>
<para>
On the publisher side, <varname>wal_level</varname> must be set to
<literal>logical</literal>, and <varname>max_replication_slots</varname>
has to be set to at least the number of subscriptions expected to connect.
And <varname>max_wal_senders</varname> should be set to at least the same
as <varname>max_replication_slots</varname> plus the number of physical replicas
that are connected at the same time.
</para>
<para>
The subscriber also requires the <varname>max_replication_slots</varname>
to be set. In this case it should be set to at least the number of
subscriptions that will be added to the subscriber.
<varname>max_logical_replication_workers</varname> has to be set to at
least the number of subscriptions. Additionally the
<varname>max_worker_processes</varname> may need to be adjusted to
accommodate for replication workers, at least
(<varname>max_logical_replication_workers</varname>
+ <literal>1</literal>). Note that some extensions and parallel queries
also take worker slots from <varname>max_worker_processes</varname>.
</para>
</sect1>
<sect1 id="logical-replication-quick-setup">
<title>Quick Setup</title>
<para>
First set the configuration options in <filename>postgresql.conf</filename>:
<programlisting>
wal_level = logical
</programlisting>
The other required settings have default values that are sufficient for a
basic setup.
</para>
<para>
<filename>pg_hba.conf</filename> needs to be adjusted to allow replication
(the values here depend on your actual network configuration and user you
want to use for connecting):
<programlisting>
host replication repuser 0.0.0.0/0 md5
</programlisting>
</para>
<para>
Then on the publisher database:
<programlisting>
CREATE PUBLICATION mypub FOR TABLE users, departments;
</programlisting>
</para>
<para>
And on the subscriber database:
<programlisting>
CREATE SUBSCRIPTION mysub CONNECTION 'dbname=foo host=bar user=repuser' PUBLICATION mypub;
</programlisting>
</para>
<para>
The above will start the replication process of changes to
<literal>users</literal> and <literal>departments</literal> tables.
</para>
</sect1>
</chapter>

View File

@ -308,6 +308,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
</entry>
</row>
<row>
<entry><structname>pg_stat_subscription</><indexterm><primary>pg_stat_subscription</primary></indexterm></entry>
<entry>At least one row per subscription, showing information about
the subscription workers.
See <xref linkend="pg-stat-subscription"> for details.
</entry>
</row>
<row>
<entry><structname>pg_stat_ssl</><indexterm><primary>pg_stat_ssl</primary></indexterm></entry>
<entry>One row per connection (regular and replication), showing information about
@ -1545,6 +1553,72 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
connected server.
</para>
<table id="pg-stat-subscription" xreflabel="pg_stat_subscription">
<title><structname>pg_stat_subscription</structname> View</title>
<tgroup cols="3">
<thead>
<row>
<entry>Column</entry>
<entry>Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><structfield>subid</></entry>
<entry><type>oid</></entry>
<entry>OID of the subscription</entry>
</row>
<row>
<entry><structfield>subname</></entry>
<entry><type>text</></entry>
<entry>Name of the subscription</entry>
</row>
<row>
<entry><structfield>pid</></entry>
<entry><type>integer</></entry>
<entry>Process ID of the subscription worker process</entry>
</row>
<row>
<entry><structfield>received_lsn</></entry>
<entry><type>pg_lsn</></entry>
<entry>Last transaction log position received, the initial value of
this field being 0</entry>
</row>
<row>
<entry><structfield>last_msg_send_time</></entry>
<entry><type>timestamp with time zone</></entry>
<entry>Send time of last message received from origin WAL sender</entry>
</row>
<row>
<entry><structfield>last_msg_receipt_time</></entry>
<entry><type>timestamp with time zone</></entry>
<entry>Receipt time of last message received from origin WAL sender
</entry>
</row>
<row>
<entry><structfield>latest_end_lsn</></entry>
<entry><type>pg_lsn</></entry>
<entry>Last transaction log position reported to origin WAL sender
</entry>
</row>
<row>
<entry><structfield>latest_end_time</></entry>
<entry><type>timestamp with time zone</></entry>
<entry>Time of last transaction log position reported to origin WAL
sender</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
The <structname>pg_stat_subscription</structname> view will contain one
row per subscription for main worker (with null PID if the worker is
not running).
</para>
<table id="pg-stat-ssl-view" xreflabel="pg_stat_ssl">
<title><structname>pg_stat_ssl</structname> View</title>
<tgroup cols="3">

View File

@ -160,6 +160,7 @@
&monitoring;
&diskusage;
&wal;
&logical-replication;
&regress;
</part>

View File

@ -2122,6 +2122,119 @@ The commands accepted in walsender mode are:
</sect1>
<sect1 id="protocol-logical-replication">
<title>Logical Streaming Replication Protocol</title>
<para>
This section describes the logical replication protocol, which is the message
flow started by the <literal>START_REPLICATION</literal>
<literal>SLOT</literal> <replaceable class="parameter">slot_name</>
<literal>LOGICAL</literal> replication command.
</para>
<para>
The logical streaming replication protocol builds on the primitives of
the physical streaming replication protocol.
</para>
<sect2 id="protocol-logical-replication-params">
<title>Logical Streaming Replication Parameters</title>
<para>
The logical replication <literal>START_REPLICATION</literal> command
accepts following parameters:
<variablelist>
<varlistentry>
<term>
proto_version
</term>
<listitem>
<para>
Protocol version. Currently only version <literal>1</literal> is
supported.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
publication_names
</term>
<listitem>
<para>
Comma separated list of publication names for which to subscribe
(receive changes). The individual publication names are treated
as standard objects names and can be quoted the same as needed.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect2>
<sect2 id="protocol-logical-messages">
<title>Logical Replication Protocol Messages</title>
<para>
The individual protocol messages are discussed in the following
subsections. Individual messages are describer in
<xref linkend="protocol-logicalrep-message-formats"> section.
</para>
<para>
All top-level protocol messages begin with a message type byte.
While represented in code as a character, this is a signed byte with no
associated encoding.
</para>
<para>
Since the streaming replication protocol supplies a message length there
is no need for top-level protocol messages to embed a length in their
header.
</para>
</sect2>
<sect2 id="protocol-logical-messages-flow">
<title>Logical Replication Protocol Message Flow</title>
<para>
With the exception of the <literal>START_REPLICATION</literal> command and
the replay progress messages, all information flows only from the backend
to the frontend.
</para>
<para>
The logical replication protocol sends individual transactions one by one.
This means that all messages between a pair of Begin and Commit messages
belong to the same transaction.
</para>
<para>
Every sent transaction contains zero or more DML messages (Insert,
Update, Delete). In case of a cascaded setup it can also contain Origin
messages. The origin message indicated that the transaction originated on
different replication node. Since a replication node in the scope of logical
replication protocol can be pretty much anything, the only identifier
is the origin name. It's downstream's responsibility to handle this as
needed (if needed). The Origin message is always sent before any DML
messages in the transaction.
</para>
<para>
Every DML message contains an arbitrary relation ID, which can be mapped to
an ID in the Relation messages. The Relation messages describe the schema of the
given relation. The Relation message is sent for a given relation either
because it is the first time we send a DML message for given relation in the
current session or because the relation definition has changed since the
last Relation message was sent for it. The protocol assumes that the client
is capable of caching the metadata for as many relations as needed.
</para>
</sect2>
</sect1>
<sect1 id="protocol-message-types">
<title>Message Data Types</title>
@ -5149,6 +5262,614 @@ not line breaks.
</sect1>
<sect1 id="protocol-logicalrep-message-formats">
<title>Logical Replication Message Formats</title>
<para>
This section describes the detailed format of each logical replication message.
These messages are returned either by the replication slot SQL interface or are
sent by a walsender. In case of a walsender they are encapsulated inside the replication
protocol WAL messages as described in <xref linkend="protocol-replication">
and generally obey same message flow as physical replication.
</para>
<variablelist>
<varlistentry>
<term>
Begin
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Byte1('B')
</term>
<listitem>
<para>
Identifies the message as a begin message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int64
</term>
<listitem>
<para>
The final LSN of the transaction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int64
</term>
<listitem>
<para>
Commit timestamp of the transaction. The value is in number
of microseconds since PostgreSQL epoch (2000-01-01).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int32
</term>
<listitem>
<para>
Xid of the transaction.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Commit
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Byte1('C')
</term>
<listitem>
<para>
Identifies the message as a commit message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int64
</term>
<listitem>
<para>
The LSN of the commit.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int64
</term>
<listitem>
<para>
The end LSN of the transaction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int64
</term>
<listitem>
<para>
Commit timestamp of the transaction. The value is in number
of microseconds since PostgreSQL epoch (2000-01-01).
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Origin
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Byte1('O')
</term>
<listitem>
<para>
Identifies the message as an origin message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int64
</term>
<listitem>
<para>
The LSN of the commit on the origin server.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
String
</term>
<listitem>
<para>
Name of the origin.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Note that there can be multiple Origin messages inside a single transaction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Relation
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Byte1('R')
</term>
<listitem>
<para>
Identifies the message as a relation message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int32
</term>
<listitem>
<para>
ID of the relation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
String
</term>
<listitem>
<para>
Namespace (empty string for <literal>pg_catalog</literal>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
String
</term>
<listitem>
<para>
Relation name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int8
</term>
<listitem>
<para>
Replica identity setting for the relation (same as
<structfield>relreplident</structfield> in <structname>pg_class</structname>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int16
</term>
<listitem>
<para>
Number of columns.
</para>
</listitem>
</varlistentry>
</variablelist>
Next, the following message part appears for each column:
<variablelist>
<varlistentry>
<term>
Int8
</term>
<listitem>
<para>
Flags for the column. Currently can be either 0 for no flags
or 1 which marks the column as part of the key.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
String
</term>
<listitem>
<para>
Name of the column.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Insert
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Byte1('I')
</term>
<listitem>
<para>
Identifies the message as an insert message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int32
</term>
<listitem>
<para>
ID of the relation corresponding to the ID in the relation
message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Byte1('N')
</term>
<listitem>
<para>
Identifies the following TupleData message as a new tuple.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
TupleData
</term>
<listitem>
<para>
TupleData message part representing the contents of new tuple.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Update
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Byte1('U')
</term>
<listitem>
<para>
Identifies the message as an update message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int32
</term>
<listitem>
<para>
ID of the relation corresponding to the ID in the relation
message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Byte1('K')
</term>
<listitem>
<para>
Identifies the following TupleData submessage as a key.
This field is optional and is only present if
the update changed data in any of the column(s) that are
part of the REPLICA IDENTITY index.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Byte1('O')
</term>
<listitem>
<para>
Identifies the following TupleData submessage as an old tuple.
This field is optional and is only present if table in which
the update happened has REPLICA IDENTITY set to FULL.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
TupleData
</term>
<listitem>
<para>
TupleData message part representing the contents of the old tuple
or primary key. Only present if the previous 'O' or 'K' part
is present.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Byte1('N')
</term>
<listitem>
<para>
Identifies the following TupleData message as a new tuple.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
TupleData
</term>
<listitem>
<para>
TupleData message part representing the contents of a new tuple.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
The Update message may contain either a 'K' message part or an 'O' message part
or neither of them, but never both of them.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Delete
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Byte1('D')
</term>
<listitem>
<para>
Identifies the message as a delete message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int32
</term>
<listitem>
<para>
ID of the relation corresponding to the ID in the relation
message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Byte1('K')
</term>
<listitem>
<para>
Identifies the following TupleData submessage as a key.
This field is present if the table in which the delete has
happened uses an index as REPLICA IDENTITY.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Byte1('O')
</term>
<listitem>
<para>
Identifies the following TupleData message as a old tuple.
This field is is present if the table in which the delete has
happened has REPLICA IDENTITY set to FULL.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
TupleData
</term>
<listitem>
<para>
TupleData message part representing the contents of the old tuple
or primary key, depending on the previous field.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
The Delete message may contain either a 'K' message part or an 'O' message part,
but never both of them.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
Following message parts that are shared by above messages.
</para>
<variablelist>
<varlistentry>
<term>
TupleData
</term>
<listitem>
<para>
<variablelist>
<varlistentry>
<term>
Int16
</term>
<listitem>
<para>
Number of columns.
</para>
</listitem>
</varlistentry>
</variablelist>
Next, one of the following submessages appears for each column:
<variablelist>
<varlistentry>
<term>
Byte1('n')
</term>
<listitem>
<para>
Idenfifies the data as NULL value.
</para>
</listitem>
</varlistentry>
</variablelist>
Or
<variablelist>
<varlistentry>
<term>
Byte1('u')
</term>
<listitem>
<para>
Idenfifies unchanged TOASTed value (the actual value is not
sent).
</para>
</listitem>
</varlistentry>
</variablelist>
Or
<variablelist>
<varlistentry>
<term>
Byte1('t')
</term>
<listitem>
<para>
Idenfifies the data as text formatted value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Int32
</term>
<listitem>
<para>
Length of the column value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
String
</term>
<listitem>
<para>
The text value.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</listitem>
</varlistentry>
</variablelist>
</sect1>
<sect1 id="protocol-changes">
<title>Summary of Changes since Protocol 2.0</title>

View File

@ -26,11 +26,13 @@ Complete list of usable sgml source files in this directory.
<!ENTITY alterOperatorClass SYSTEM "alter_opclass.sgml">
<!ENTITY alterOperatorFamily SYSTEM "alter_opfamily.sgml">
<!ENTITY alterPolicy SYSTEM "alter_policy.sgml">
<!ENTITY alterPublication SYSTEM "alter_publication.sgml">
<!ENTITY alterRole SYSTEM "alter_role.sgml">
<!ENTITY alterRule SYSTEM "alter_rule.sgml">
<!ENTITY alterSchema SYSTEM "alter_schema.sgml">
<!ENTITY alterServer SYSTEM "alter_server.sgml">
<!ENTITY alterSequence SYSTEM "alter_sequence.sgml">
<!ENTITY alterSubscription SYSTEM "alter_subscription.sgml">
<!ENTITY alterSystem SYSTEM "alter_system.sgml">
<!ENTITY alterTable SYSTEM "alter_table.sgml">
<!ENTITY alterTableSpace SYSTEM "alter_tablespace.sgml">
@ -72,11 +74,13 @@ Complete list of usable sgml source files in this directory.
<!ENTITY createOperatorClass SYSTEM "create_opclass.sgml">
<!ENTITY createOperatorFamily SYSTEM "create_opfamily.sgml">
<!ENTITY createPolicy SYSTEM "create_policy.sgml">
<!ENTITY createPublication SYSTEM "create_publication.sgml">
<!ENTITY createRole SYSTEM "create_role.sgml">
<!ENTITY createRule SYSTEM "create_rule.sgml">
<!ENTITY createSchema SYSTEM "create_schema.sgml">
<!ENTITY createSequence SYSTEM "create_sequence.sgml">
<!ENTITY createServer SYSTEM "create_server.sgml">
<!ENTITY createSubscription SYSTEM "create_subscription.sgml">
<!ENTITY createTable SYSTEM "create_table.sgml">
<!ENTITY createTableAs SYSTEM "create_table_as.sgml">
<!ENTITY createTableSpace SYSTEM "create_tablespace.sgml">
@ -116,11 +120,13 @@ Complete list of usable sgml source files in this directory.
<!ENTITY dropOperatorFamily SYSTEM "drop_opfamily.sgml">
<!ENTITY dropOwned SYSTEM "drop_owned.sgml">
<!ENTITY dropPolicy SYSTEM "drop_policy.sgml">
<!ENTITY dropPublication SYSTEM "drop_publication.sgml">
<!ENTITY dropRole SYSTEM "drop_role.sgml">
<!ENTITY dropRule SYSTEM "drop_rule.sgml">
<!ENTITY dropSchema SYSTEM "drop_schema.sgml">
<!ENTITY dropSequence SYSTEM "drop_sequence.sgml">
<!ENTITY dropServer SYSTEM "drop_server.sgml">
<!ENTITY dropSubscription SYSTEM "drop_subscription.sgml">
<!ENTITY dropTable SYSTEM "drop_table.sgml">
<!ENTITY dropTableSpace SYSTEM "drop_tablespace.sgml">
<!ENTITY dropTransform SYSTEM "drop_transform.sgml">

View File

@ -0,0 +1,139 @@
<!--
doc/src/sgml/ref/alter_publication.sgml
PostgreSQL documentation
-->
<refentry id="SQL-ALTERPUBLICATION">
<indexterm zone="sql-alterpublication">
<primary>ALTER PUBLICATION</primary>
</indexterm>
<refmeta>
<refentrytitle>ALTER PUBLICATION</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>ALTER PUBLICATION</refname>
<refpurpose>change the definition of a publication</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> WITH ( <replaceable class="PARAMETER">option</replaceable> [, ... ] )
<phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase>
PUBLISH INSERT | NOPUBLISH INSERT
| PUBLISH UPDATE | NOPUBLISH UPDATE
| PUBLISH DELETE | NOPUBLISH DELETE
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> ADD TABLE <replaceable class="PARAMETER">table_name</replaceable> [, ...]
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> SET TABLE <replaceable class="PARAMETER">table_name</replaceable> [, ...]
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> DROP TABLE <replaceable class="PARAMETER">table_name</replaceable> [, ...]
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
The first variant of this command listed in the synopsis can change
all of the publication properties specified in
<xref linkend="sql-createpublication">. Properties not mentioned in the
command retain their previous settings. Database superusers can change any
of these settings for any role.
</para>
<para>
To alter the owner, you must also be a direct or indirect member of the
new owning role. The new owner has to be a superuser
</para>
<para>
The other variants of this command deal with the table membership of the
publication. The <literal>SET TABLE</literal> clause will replace the
list of tables in the publication with the specified one.
The <literal>ADD TABLE</literal> and
<literal>DROP TABLE</literal> will add and remove one or more tables from
the publication.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name of an existing publication whose definition is to be altered.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>PUBLISH INSERT</literal></term>
<term><literal>NOPUBLISH INSERT</literal></term>
<term><literal>PUBLISH UPDATE</literal></term>
<term><literal>NOPUBLISH UPDATE</literal></term>
<term><literal>PUBLISH DELETE</literal></term>
<term><literal>NOPUBLISH DELETE</literal></term>
<listitem>
<para>
These clauses alter properties originally set by
<xref linkend="SQL-CREATEPUBLICATION">. See there for more information.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">table_name</replaceable></term>
<listitem>
<para>
Name of an existing table.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Change the publication to not publish inserts:
<programlisting>
ALTER PUBLICATION noinsert WITH (NOPUBLISH INSERT);
</programlisting>
</para>
<para>
Add some tables to the publication:
<programlisting>
ALTER PUBLICATION mypublication ADD TABLE users, departments;
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>ALTER PUBLICATION</command> is a <productname>PostgreSQL</>
extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-createpublication"></member>
<member><xref linkend="sql-droppublication"></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -0,0 +1,139 @@
<!--
doc/src/sgml/ref/alter_subscription.sgml
PostgreSQL documentation
-->
<refentry id="SQL-ALTERSUBSCRIPTION">
<indexterm zone="sql-altersubscription">
<primary>ALTER SUBSCRIPTION</primary>
</indexterm>
<refmeta>
<refentrytitle>ALTER SUBSCRIPTION</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>ALTER SUBSCRIPTION</refname>
<refpurpose>change the definition of a subscription</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> WITH ( <replaceable class="PARAMETER">option</replaceable> [, ... ] ) ]
<phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase>
SLOT NAME = slot_name
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> CONNECTION 'conninfo'
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> SET PUBLICATION publication_name [, ...]
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> ENABLE
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> DISABLE
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>ALTER SUBSCRIPTION</command> can change most of the subscription
properties that can be specified
in <xref linkend="sql-createsubscription">.
</para>
<para>
To alter the owner, you must also be a direct or indirect member of the
new owning role. The new owner has to be a superuser
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name of a subscription whose properties are to be altered.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CONNECTION '<replaceable class="parameter">conninfo</replaceable>'</literal></term>
<term><literal>SET PUBLICATION <replaceable class="parameter">publication_name</replaceable></literal></term>
<term><literal>SLOT NAME = <replaceable class="parameter">slot_name</replaceable></literal></term>
<listitem>
<para>
These clauses alter properties originally set by
<xref linkend="SQL-CREATESUBSCRIPTION">. See there for more
information.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>ENABLE</literal></term>
<listitem>
<para>
Enables the previously disabled subscription, starting the logical
replication worker at the end of transaction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>DISABLE</literal></term>
<listitem>
<para>
Disables the running subscription, stopping the logical replication
worker at the end of transaction.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Change the publication subscribed by a subscription to
<literal>insert_only</literal>:
<programlisting>
ALTER SUBSCRIPTION mysub SET PUBLICATION insert_only;
</programlisting>
</para>
<para>
Disable (stop) the subscription:
<programlisting>
ALTER SUBSCRIPTION mysub DISABLE;
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>ALTER SUBSCRIPTION</command> is a <productname>PostgreSQL</>
extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-createsubscription"></member>
<member><xref linkend="sql-dropsubscription"></member>
<member><xref linkend="sql-createpublication"></member>
<member><xref linkend="sql-alterpublication"></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -0,0 +1,206 @@
<!--
doc/src/sgml/ref/create_publication.sgml
PostgreSQL documentation
-->
<refentry id="SQL-CREATEPUBLICATION">
<indexterm zone="sql-createpublication">
<primary>CREATE PUBLICATION</primary>
</indexterm>
<refmeta>
<refentrytitle>CREATE PUBLICATION</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>CREATE PUBLICATION</refname>
<refpurpose>define a new publication</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
[ FOR TABLE <replaceable class="parameter">table_name</replaceable> [, ...]
| FOR ALL TABLES ]
[ WITH ( <replaceable class="parameter">option</replaceable> [, ... ] ) ]
<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
PUBLISH INSERT | NOPUBLISH INSERT
| PUBLISH UPDATE | NOPUBLISH UPDATE
| PUBLISH DELETE | NOPUBLISH DELETE
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>CREATE PUBLICATION</command> adds a new publication
into the current database. The publication name must be distinct from
the name of any existing publication in the current database.
</para>
<para>
A publication is essentially a group of tables whose data changes are
intended to be replicated through logical replication. See
<xref linkend="logical-replication-publication"> for details about how
publications fit into the logical replication setup.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name of the new publication.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>FOR TABLE</literal></term>
<listitem>
<para>
Specifies a list of tables to add to the publication.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>FOR ALL TABLES</literal></term>
<listitem>
<para>
Marks the publication as one that replicates changes for all tables in
the database, including tables created in the future.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>PUBLISH INSERT</literal></term>
<term><literal>NOPUBLISH INSERT</literal></term>
<listitem>
<para>
These clauses determine whether the new publication will send
the <command>INSERT</command> operations to the subscribers.
<literal>PUBLISH INSERT</literal> is the default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>PUBLISH UPDATE</literal></term>
<term><literal>NOPUBLISH UPDATE</literal></term>
<listitem>
<para>
These clauses determine whether the new publication will send
the <command>UPDATE</command> operations to the subscribers.
<literal>PUBLISH UPDATE</literal> is the default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>PUBLISH DELETE</literal></term>
<term><literal>NOPUBLISH DELETE</literal></term>
<listitem>
<para>
These clauses determine whether the new publication will send
the <command>DELETE</command> operations to the subscribers.
<literal>PUBLISH DELETE</literal> is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
If neither <literal>FOR TABLE</literal> nor <literal>FOR ALL
TABLES</literal> is specified, then the publication starts out with an
empty set of tables. That is useful if tables are to be added later.
</para>
<para>
The creation of a publication does not start replication. It only defines
a grouping and filtering logic for future subscribers.
</para>
<para>
To create a publication, the invoking user must have the
<literal>CREATE</> privilege for the current database.
(Of course, superusers bypass this check.)
</para>
<para>
To add a table to a publication, the invoking user must have
<command>SELECT</command> privilege on given table. The
<command>FOR ALL TABLES</command> clause requires superuser.
</para>
<para>
The tables added to a publication that publishes <command>UPDATE</command>
and/or <command>DELETE</command> operations must have
<literal>REPLICA IDENTITY</> defined. Otherwise those operations will be
disallowed on those tables.
</para>
<para>
For an <command>INSERT ... ON CONFLICT</> command, the publication will
publish the operation that actually results from the command. So depending
of the outcome, it may be published as either <command>INSERT</command> or
<command>UPDATE</command>, or it may not be published at all.
</para>
<para>
<command>TRUNCATE</command> and other <acronym>DDL</acronym> operations
are not published.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Create a simple publication that just publishes all DML for tables in it:
<programlisting>
CREATE PUBLICATION mypublication;
</programlisting>
</para>
<para>
Create an insert-only publication:
<programlisting>
CREATE PUBLICATION insert_only WITH (NOPUBLISH UPDATE, NOPUBLISH DELETE);
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>CREATE PUBLICATION</command> is a <productname>PostgreSQL</>
extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-alterpublication"></member>
<member><xref linkend="sql-droppublication"></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -0,0 +1,176 @@
<!--
doc/src/sgml/ref/create_subscription.sgml
PostgreSQL documentation
-->
<refentry id="SQL-CREATESUBSCRIPTION">
<indexterm zone="sql-createsubscription">
<primary>CREATE SUBSCRIPTION</primary>
</indexterm>
<refmeta>
<refentrytitle>CREATE SUBSCRIPTION</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>CREATE SUBSCRIPTION</refname>
<refpurpose>define a new subscription</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
CREATE SUBSCRIPTION <replaceable class="PARAMETER">subscription_name</replaceable> CONNECTION 'conninfo' PUBLICATION { publication_name [, ...] } [ WITH ( <replaceable class="PARAMETER">option</replaceable> [, ... ] ) ]
<phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase>
| ENABLED | DISABLED
| CREATE SLOT | NOCREATE SLOT
| SLOT NAME = slot_name
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>CREATE SUBSCRIPTION</command> adds a new subscription for a
current database. The subscription name must be distinct from the name of
any existing subscription in the database.
</para>
<para>
The subscription represents a replication connection to the publisher. As
such this command does not only add definitions in the local catalogs but
also creates a replication slot on the publisher.
</para>
<para>
A logical replication worker will be started to replicate data for the new
subscription at the commit of the transaction where this command is run.
</para>
<para>
Additional info about subscriptions and logical replication as a whole
can is available at <xref linkend="logical-replication-subscription"> and
<xref linkend="logical-replication">.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">subscription_name</replaceable></term>
<listitem>
<para>
The name of the new subscription.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CONNECTION '<replaceable class="parameter">conninfo</replaceable>'</literal></term>
<listitem>
<para>
The connection string to the publisher.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>PUBLICATION <replaceable class="parameter">publication_name</replaceable></literal></term>
<listitem>
<para>
Name(s) of the publications on the publisher to subscribe to.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>ENABLED</literal></term>
<term><literal>DISABLED</literal></term>
<listitem>
<para>
Specifies whether the subscription should be actively replicating or
if it should be just setup but not started yet. Note that the
replication slot as described above is created in either case.
<literal>ENABLED</literal> is the default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CREATE SLOT</literal></term>
<term><literal>NOCREATE SLOT</literal></term>
<listitem>
<para>
Specifies whether the command should create the replication slot on the
publisher. <literal>CREATE SLOT</literal> is the default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SLOT NAME = <replaceable class="parameter">slot_name</replaceable></literal></term>
<listitem>
<para>
Name of the replication slot to use. The default behavior is to use
<literal>subscription_name</> for slot name.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Create a subscription to a remote server that replicates tables in
the publications <literal>mypubclication</literal> and
<literal>insert_only</literal> and starts replicating immediately on
commit:
<programlisting>
CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb password=foopass'
PUBLICATION mypublication, insert_only;
</programlisting>
</para>
<para>
Create a subscription to a remote server that replicates tables in
the <literal>insert_only</literal> publication and does not start replicating
until enabled at a later time.
<programlisting>
CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb password=foopass'
PUBLICATION insert_only
WITH (DISABLED);
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>CREATE SUBSCRIPTION</command> is a <productname>PostgreSQL</>
extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-altersubscription"></member>
<member><xref linkend="sql-dropsubscription"></member>
<member><xref linkend="sql-createpublication"></member>
<member><xref linkend="sql-alterpublication"></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -0,0 +1,107 @@
<!--
doc/src/sgml/ref/drop_publication.sgml
PostgreSQL documentation
-->
<refentry id="SQL-DROPPUBLICATION">
<indexterm zone="sql-droppublication">
<primary>DROP PUBLICATION</primary>
</indexterm>
<refmeta>
<refentrytitle>DROP PUBLICATION</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>DROP PUBLICATION</refname>
<refpurpose>remove a publication</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
DROP PUBLICATION [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>DROP PUBLICATION</command> removes an existing publication from
the database.
</para>
<para>
A publication can only be dropped by its owner or a superuser.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><literal>IF EXISTS</literal></term>
<listitem>
<para>
Do not throw an error if the extension does not exist. A notice is issued
in this case.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name of an existing publication.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CASCADE</literal></term>
<term><literal>RESTRICT</literal></term>
<listitem>
<para>
These key words do not have any effect, since there are no dependencies
on publications.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Drop a publication:
<programlisting>
DROP PUBLICATION mypublication;
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>DROP PUBLICATION</command> is a <productname>PostgreSQL</>
extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-createpublication"></member>
<member><xref linkend="sql-alterpublication"></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -0,0 +1,110 @@
<!--
doc/src/sgml/ref/drop_subscription.sgml
PostgreSQL documentation
-->
<refentry id="SQL-DROPSUBSCRIPTION">
<indexterm zone="sql-dropsubscription">
<primary>DROP SUBSCRIPTION</primary>
</indexterm>
<refmeta>
<refentrytitle>DROP SUBSCRIPTION</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>DROP SUBSCRIPTION</refname>
<refpurpose>remove a subscription</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
DROP SUBSCRIPTION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ <replaceable class="parameter">DROP SLOT</replaceable> | <replaceable class="parameter">NODROP SLOT</replaceable> ]
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>DROP SUBSCRIPTION</command> removes a subscription from the
database cluster.
</para>
<para>
A subscription can only be dropped by a superuser.
</para>
<para>
The replication worker associated with the subscription will not stop until
after the transaction that issued this command has committed.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name of a subscription to be dropped.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">DROP SLOT</replaceable></term>
<term><replaceable class="parameter">NODROP SLOT</replaceable></term>
<listitem>
<para>
Specifies whether to drop the replication slot on the publisher. The
default is
<literal>DROP SLOT</literal>.
</para>
<para>
If the publisher is not reachable when the subscription is to be
dropped, then it is useful to specify <literal>NODROP SLOT</literal>.
But the replication slot on the publisher will then have to be removed
manually.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Drop a subscription:
<programlisting>
DROP SUBSCRIPTION mysub;
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>DROP SUBSCRIPTION</command> is a <productname>PostgreSQL</>
extension.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-createsubscription"></member>
<member><xref linkend="sql-altersubscription"></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -755,6 +755,15 @@ PostgreSQL documentation
</listitem>
</varlistentry>
<varlistentry>
<term><option>--include-subscriptions</option></term>
<listitem>
<para>
Include logical replication subscriptions in the dump.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--inserts</option></term>
<listitem>
@ -789,6 +798,18 @@ PostgreSQL documentation
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-create-subscription-slots</option></term>
<listitem>
<para>
When dumping logical replication subscriptions,
generate <command>CREATE SUBSCRIPTION</command> commands that do not
create the remote replication slot. That way, the dump can be
restored without requiring network access to the remote servers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-security-labels</option></term>
<listitem>

View File

@ -1600,6 +1600,34 @@ testdb=&gt;
</listitem>
</varlistentry>
<varlistentry>
<term><literal>\dRp[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
<listitem>
<para>
Lists replication publications.
If <replaceable class="parameter">pattern</replaceable> is
specified, only those publications whose names match the pattern are
listed.
If <literal>+</literal> is appended to the command name, the tables
associated with each publication are shown as well.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>\dRs[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
<listitem>
<para>
Lists replication subscriptions.
If <replaceable class="parameter">pattern</replaceable> is
specified, only those subscriptions whose names match the pattern are
listed.
If <literal>+</literal> is appended to the command name, additional
properties of the subscriptions are shown.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>\dT[S+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
<listitem>

View File

@ -54,11 +54,13 @@
&alterOperatorClass;
&alterOperatorFamily;
&alterPolicy;
&alterPublication;
&alterRole;
&alterRule;
&alterSchema;
&alterSequence;
&alterServer;
&alterSubscription;
&alterSystem;
&alterTable;
&alterTableSpace;
@ -100,11 +102,13 @@
&createOperatorClass;
&createOperatorFamily;
&createPolicy;
&createPublication;
&createRole;
&createRule;
&createSchema;
&createSequence;
&createServer;
&createSubscription;
&createTable;
&createTableAs;
&createTableSpace;
@ -144,11 +148,13 @@
&dropOperatorFamily;
&dropOwned;
&dropPolicy;
&dropPublication;
&dropRole;
&dropRule;
&dropSchema;
&dropSequence;
&dropServer;
&dropSubscription;
&dropTable;
&dropTableSpace;
&dropTSConfig;