]> begriffs open source - ai-pg/blob - full-docs/src/sgml/html/logical-replication-subscription.html
WIP: toc builder
[ai-pg] / full-docs / src / sgml / html / logical-replication-subscription.html
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>29.2. Subscription</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-publication.html" title="29.1. Publication" /><link rel="next" href="logical-replication-failover.html" title="29.3. Logical Replication Failover" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">29.2. Subscription</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-publication.html" title="29.1. Publication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 29. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 29. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-failover.html" title="29.3. Logical Replication Failover">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-SUBSCRIPTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">29.2. Subscription <a href="#LOGICAL-REPLICATION-SUBSCRIPTION" class="id_link">#</a></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-SLOT">29.2.1. Replication Slot Management</a></span></dt><dt><span class="sect2"><a href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES">29.2.2. Examples: Set Up Logical Replication</a></span></dt><dt><span class="sect2"><a href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES-DEFERRED-SLOT">29.2.3. Examples: Deferred Replication Slot Creation</a></span></dt></dl></div><p>
3    A <em class="firstterm">subscription</em> is the downstream side of logical
4    replication.  The node where a subscription is defined is referred to as
5    the <em class="firstterm">subscriber</em>.  A subscription defines the connection
6    to another database and set of publications (one or more) to which it wants
7    to subscribe.
8   </p><p>
9    The subscriber database behaves in the same way as any other PostgreSQL
10    instance and can be used as a publisher for other databases by defining its
11    own publications.
12   </p><p>
13    A subscriber node may have multiple subscriptions if desired.  It is
14    possible to define multiple subscriptions between a single
15    publisher-subscriber pair, in which case care must be taken to ensure
16    that the subscribed publication objects don't overlap.
17   </p><p>
18    Each subscription will receive changes via one replication slot (see
19    <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="26.2.6. Replication Slots">Section 26.2.6</a>).  Additional replication
20    slots may be required for the initial data synchronization of
21    pre-existing table data and those will be dropped at the end of data
22    synchronization.
23   </p><p>
24    A logical replication subscription can be a standby for synchronous
25    replication (see <a class="xref" href="warm-standby.html#SYNCHRONOUS-REPLICATION" title="26.2.8. Synchronous Replication">Section 26.2.8</a>).  The standby
26    name is by default the subscription name.  An alternative name can be
27    specified as <code class="literal">application_name</code> in the connection
28    information of the subscription.
29   </p><p>
30    Subscriptions are dumped by <code class="command">pg_dump</code> if the current user
31    is a superuser.  Otherwise a warning is written and subscriptions are
32    skipped, because non-superusers cannot read all subscription information
33    from the <code class="structname">pg_subscription</code> catalog.
34   </p><p>
35    The subscription is added using <a class="link" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><code class="command">CREATE SUBSCRIPTION</code></a> and
36    can be stopped/resumed at any time using the
37    <a class="link" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><code class="command">ALTER SUBSCRIPTION</code></a> command and removed using
38    <a class="link" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION"><code class="command">DROP SUBSCRIPTION</code></a>.
39   </p><p>
40    When a subscription is dropped and recreated, the synchronization
41    information is lost.  This means that the data has to be resynchronized
42    afterwards.
43   </p><p>
44    The schema definitions are not replicated, and the published tables must
45    exist on the subscriber.  Only regular tables may be
46    the target of replication.  For example, you can't replicate to a view.
47   </p><p>
48    The tables are matched between the publisher and the subscriber using the
49    fully qualified table name.  Replication to differently-named tables on the
50    subscriber is not supported.
51   </p><p>
52    Columns of a table are also matched by name.  The order of columns in the
53    subscriber table does not need to match that of the publisher.  The data
54    types of the columns do not need to match, as long as the text
55    representation of the data can be converted to the target type.  For
56    example, you can replicate from a column of type <code class="type">integer</code> to a
57    column of type <code class="type">bigint</code>.  The target table can also have
58    additional columns not provided by the published table.  Any such columns
59    will be filled with the default value as specified in the definition of the
60    target table. However, logical replication in binary format is more
61    restrictive. See the
62    <a class="link" href="sql-createsubscription.html#SQL-CREATESUBSCRIPTION-PARAMS-WITH-BINARY"><code class="literal">binary</code></a>
63    option of <code class="command">CREATE SUBSCRIPTION</code> for details.
64   </p><div class="sect2" id="LOGICAL-REPLICATION-SUBSCRIPTION-SLOT"><div class="titlepage"><div><div><h3 class="title">29.2.1. Replication Slot Management <a href="#LOGICAL-REPLICATION-SUBSCRIPTION-SLOT" class="id_link">#</a></h3></div></div></div><p>
65     As mentioned earlier, each (active) subscription receives changes from a
66     replication slot on the remote (publishing) side.
67    </p><p>
68     Additional table synchronization slots are normally transient, created
69     internally to perform initial table synchronization and dropped
70     automatically when they are no longer needed. These table synchronization
71     slots have generated names: <span class="quote">“<span class="quote"><code class="literal">pg_%u_sync_%u_%llu</code></span>”</span>
72     (parameters: Subscription <em class="parameter"><code>oid</code></em>,
73     Table <em class="parameter"><code>relid</code></em>, system identifier <em class="parameter"><code>sysid</code></em>)
74    </p><p>
75     Normally, the remote replication slot is created automatically when the
76     subscription is created using <a class="link" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION">
77     <code class="command">CREATE SUBSCRIPTION</code></a> and it
78     is dropped automatically when the subscription is dropped using
79     <a class="link" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION"><code class="command">DROP SUBSCRIPTION</code></a>.
80     In some situations, however, it can
81     be useful or necessary to manipulate the subscription and the underlying
82     replication slot separately.  Here are some scenarios:
83
84     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
85        When creating a subscription, the replication slot already exists.  In
86        that case, the subscription can be created using
87        the <code class="literal">create_slot = false</code> option to associate with the
88        existing slot.
89       </p></li><li class="listitem"><p>
90        When creating a subscription, the remote host is not reachable or in an
91        unclear state.  In that case, the subscription can be created using
92        the <code class="literal">connect = false</code> option.  The remote host will then not
93        be contacted at all.  This is what <span class="application">pg_dump</span>
94        uses.  The remote replication slot will then have to be created
95        manually before the subscription can be activated.
96       </p></li><li class="listitem"><p>
97        When dropping a subscription, the replication slot should be kept.
98        This could be useful when the subscriber database is being moved to a
99        different host and will be activated from there.  In that case,
100        disassociate the slot from the subscription using
101        <a class="link" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><code class="command">ALTER SUBSCRIPTION</code></a>
102        before attempting to drop the subscription.
103       </p></li><li class="listitem"><p>
104        When dropping a subscription, the remote host is not reachable.  In
105        that case, disassociate the slot from the subscription
106        using <code class="command">ALTER SUBSCRIPTION</code> before attempting to drop
107        the subscription.  If the remote database instance no longer exists, no
108        further action is then necessary.  If, however, the remote database
109        instance is just unreachable, the replication slot (and any still
110        remaining table synchronization slots) should then be
111        dropped manually; otherwise it/they would continue to reserve WAL and might
112        eventually cause the disk to fill up.  Such cases should be carefully
113        investigated.
114       </p></li></ul></div><p>
115    </p></div><div class="sect2" id="LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES"><div class="titlepage"><div><div><h3 class="title">29.2.2. Examples: Set Up Logical Replication <a href="#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES" class="id_link">#</a></h3></div></div></div><p>
116      Create some test tables on the publisher.
117 </p><pre class="programlisting">
118 /* pub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
119 /* pub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
120 /* pub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
121 </pre><p>
122      Create the same tables on the subscriber.
123 </p><pre class="programlisting">
124 /* sub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
125 /* sub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
126 /* sub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
127 </pre><p>
128      Insert data to the tables at the publisher side.
129 </p><pre class="programlisting">
130 /* pub # */ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
131 /* pub # */ INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C');
132 /* pub # */ INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii');
133 </pre><p>
134      Create publications for the tables. The publications <code class="literal">pub2</code>
135      and <code class="literal">pub3a</code> disallow some
136      <a class="link" href="sql-createpublication.html#SQL-CREATEPUBLICATION-PARAMS-WITH-PUBLISH"><code class="literal">publish</code></a>
137      operations. The publication <code class="literal">pub3b</code> has a row filter (see
138      <a class="xref" href="logical-replication-row-filter.html" title="29.4. Row Filters">Section 29.4</a>).
139 </p><pre class="programlisting">
140 /* pub # */ CREATE PUBLICATION pub1 FOR TABLE t1;
141 /* pub # */ CREATE PUBLICATION pub2 FOR TABLE t2 WITH (publish = 'truncate');
142 /* pub # */ CREATE PUBLICATION pub3a FOR TABLE t3 WITH (publish = 'truncate');
143 /* pub # */ CREATE PUBLICATION pub3b FOR TABLE t3 WHERE (e &gt; 5);
144 </pre><p>
145      Create subscriptions for the publications. The subscription
146      <code class="literal">sub3</code> subscribes to both <code class="literal">pub3a</code> and
147      <code class="literal">pub3b</code>. All subscriptions will copy initial data by default.
148 </p><pre class="programlisting">
149 /* sub # */ CREATE SUBSCRIPTION sub1
150 /* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub1'
151 /* sub - */ PUBLICATION pub1;
152 /* sub # */ CREATE SUBSCRIPTION sub2
153 /* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub2'
154 /* sub - */ PUBLICATION pub2;
155 /* sub # */ CREATE SUBSCRIPTION sub3
156 /* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub3'
157 /* sub - */ PUBLICATION pub3a, pub3b;
158 </pre><p>
159      Observe that initial table data is copied, regardless of the
160      <code class="literal">publish</code> operation of the publication.
161 </p><pre class="programlisting">
162 /* sub # */ SELECT * FROM t1;
163  a |   b
164 ---+-------
165  1 | one
166  2 | two
167  3 | three
168 (3 rows)
169
170 /* sub # */ SELECT * FROM t2;
171  c | d
172 ---+---
173  1 | A
174  2 | B
175  3 | C
176 (3 rows)
177 </pre><p>
178      Furthermore, because the initial data copy ignores the <code class="literal">publish</code>
179      operation, and because publication <code class="literal">pub3a</code> has no row filter,
180      it means the copied table <code class="literal">t3</code> contains all rows even when
181      they do not match the row filter of publication <code class="literal">pub3b</code>.
182 </p><pre class="programlisting">
183 /* sub # */ SELECT * FROM t3;
184  e |  f
185 ---+-----
186  1 | i
187  2 | ii
188  3 | iii
189 (3 rows)
190 </pre><p>
191     Insert more data to the tables at the publisher side.
192 </p><pre class="programlisting">
193 /* pub # */ INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six');
194 /* pub # */ INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F');
195 /* pub # */ INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi');
196 </pre><p>
197     Now the publisher side data looks like:
198 </p><pre class="programlisting">
199 /* pub # */ SELECT * FROM t1;
200  a |   b
201 ---+-------
202  1 | one
203  2 | two
204  3 | three
205  4 | four
206  5 | five
207  6 | six
208 (6 rows)
209
210 /* pub # */ SELECT * FROM t2;
211  c | d
212 ---+---
213  1 | A
214  2 | B
215  3 | C
216  4 | D
217  5 | E
218  6 | F
219 (6 rows)
220
221 /* pub # */ SELECT * FROM t3;
222  e |  f
223 ---+-----
224  1 | i
225  2 | ii
226  3 | iii
227  4 | iv
228  5 | v
229  6 | vi
230 (6 rows)
231 </pre><p>
232     Observe that during normal replication the appropriate
233     <code class="literal">publish</code> operations are used. This means publications
234     <code class="literal">pub2</code> and <code class="literal">pub3a</code> will not replicate the
235     <code class="literal">INSERT</code>. Also, publication <code class="literal">pub3b</code> will
236     only replicate data that matches the row filter of <code class="literal">pub3b</code>.
237     Now the subscriber side data looks like:
238 </p><pre class="programlisting">
239 /* sub # */ SELECT * FROM t1;
240  a |   b
241 ---+-------
242  1 | one
243  2 | two
244  3 | three
245  4 | four
246  5 | five
247  6 | six
248 (6 rows)
249
250 /* sub # */ SELECT * FROM t2;
251  c | d
252 ---+---
253  1 | A
254  2 | B
255  3 | C
256 (3 rows)
257
258 /* sub # */ SELECT * FROM t3;
259  e |  f
260 ---+-----
261  1 | i
262  2 | ii
263  3 | iii
264  6 | vi
265 (4 rows)
266 </pre></div><div class="sect2" id="LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES-DEFERRED-SLOT"><div class="titlepage"><div><div><h3 class="title">29.2.3. Examples: Deferred Replication Slot Creation <a href="#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES-DEFERRED-SLOT" class="id_link">#</a></h3></div></div></div><p>
267     There are some cases (e.g.
268     <a class="xref" href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-SLOT" title="29.2.1. Replication Slot Management">Section 29.2.1</a>) where, if the
269     remote replication slot was not created automatically, the user must create
270     it manually before the subscription can be activated. The steps to create
271     the slot and activate the subscription are shown in the following examples.
272     These examples specify the standard logical decoding output plugin
273     (<code class="literal">pgoutput</code>), which is what the built-in logical
274     replication uses.
275    </p><p>
276     First, create a publication for the examples to use.
277 </p><pre class="programlisting">
278 /* pub # */ CREATE PUBLICATION pub1 FOR ALL TABLES;
279 </pre><p>
280     Example 1: Where the subscription says <code class="literal">connect = false</code>
281    </p><p>
282     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
283        Create the subscription.
284 </p><pre class="programlisting">
285 /* sub # */ CREATE SUBSCRIPTION sub1
286 /* sub - */ CONNECTION 'host=localhost dbname=test_pub'
287 /* sub - */ PUBLICATION pub1
288 /* sub - */ WITH (connect=false);
289 WARNING:  subscription was created, but is not connected
290 HINT:  To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription.
291 </pre></li><li class="listitem"><p>
292        On the publisher, manually create a slot. Because the name was not
293        specified during <code class="literal">CREATE SUBSCRIPTION</code>, the name of the
294        slot to create is same as the subscription name, e.g. "sub1".
295 </p><pre class="programlisting">
296 /* pub # */ SELECT * FROM pg_create_logical_replication_slot('sub1', 'pgoutput');
297  slot_name |    lsn
298 -----------+-----------
299  sub1      | 0/19404D0
300 (1 row)
301 </pre></li><li class="listitem"><p>
302        On the subscriber, complete the activation of the subscription. After
303        this the tables of <code class="literal">pub1</code> will start replicating.
304 </p><pre class="programlisting">
305 /* sub # */ ALTER SUBSCRIPTION sub1 ENABLE;
306 /* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
307 </pre></li></ul></div><p>
308    </p><p>
309     Example 2: Where the subscription says <code class="literal">connect = false</code>,
310     but also specifies the
311     <a class="link" href="sql-createsubscription.html#SQL-CREATESUBSCRIPTION-PARAMS-WITH-SLOT-NAME"><code class="literal">slot_name</code></a>
312     option.
313     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
314        Create the subscription.
315 </p><pre class="programlisting">
316 /* sub # */ CREATE SUBSCRIPTION sub1
317 /* sub - */ CONNECTION 'host=localhost dbname=test_pub'
318 /* sub - */ PUBLICATION pub1
319 /* sub - */ WITH (connect=false, slot_name='myslot');
320 WARNING:  subscription was created, but is not connected
321 HINT:  To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription.
322 </pre></li><li class="listitem"><p>
323        On the publisher, manually create a slot using the same name that was
324        specified during <code class="literal">CREATE SUBSCRIPTION</code>, e.g. "myslot".
325 </p><pre class="programlisting">
326 /* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput');
327  slot_name |    lsn
328 -----------+-----------
329  myslot    | 0/19059A0
330 (1 row)
331 </pre></li><li class="listitem"><p>
332        On the subscriber, the remaining subscription activation steps are the
333        same as before.
334 </p><pre class="programlisting">
335 /* sub # */ ALTER SUBSCRIPTION sub1 ENABLE;
336 /* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
337 </pre></li></ul></div><p>
338    </p><p>
339     Example 3: Where the subscription specifies <code class="literal">slot_name = NONE</code>
340     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
341        Create the subscription. When <code class="literal">slot_name = NONE</code> then
342        <code class="literal">enabled = false</code>, and
343        <code class="literal">create_slot = false</code> are also needed.
344 </p><pre class="programlisting">
345 /* sub # */ CREATE SUBSCRIPTION sub1
346 /* sub - */ CONNECTION 'host=localhost dbname=test_pub'
347 /* sub - */ PUBLICATION pub1
348 /* sub - */ WITH (slot_name=NONE, enabled=false, create_slot=false);
349 </pre></li><li class="listitem"><p>
350        On the publisher, manually create a slot using any name, e.g. "myslot".
351 </p><pre class="programlisting">
352 /* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput');
353  slot_name |    lsn
354 -----------+-----------
355  myslot    | 0/1905930
356 (1 row)
357 </pre></li><li class="listitem"><p>
358        On the subscriber, associate the subscription with the slot name just
359        created.
360 </p><pre class="programlisting">
361 /* sub # */ ALTER SUBSCRIPTION sub1 SET (slot_name='myslot');
362 </pre></li><li class="listitem"><p>
363        The remaining subscription activation steps are same as before.
364 </p><pre class="programlisting">
365 /* sub # */ ALTER SUBSCRIPTION sub1 ENABLE;
366 /* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
367 </pre></li></ul></div><p>
368    </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-publication.html" title="29.1. Publication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 29. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-failover.html" title="29.3. Logical Replication Failover">Next</a></td></tr><tr><td width="40%" align="left" valign="top">29.1. Publication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 29.3. Logical Replication Failover</td></tr></table></div></body></html>