<para>
Create some test tables on the publisher.
<programlisting>
-test_pub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
-CREATE TABLE
-test_pub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
-CREATE TABLE
-test_pub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
-CREATE TABLE
+/* pub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
+/* pub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
+/* pub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
</programlisting></para>
<para>
Create the same tables on the subscriber.
<programlisting>
-test_sub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
-CREATE TABLE
-test_sub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
-CREATE TABLE
-test_sub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
-CREATE TABLE
+/* sub # */ CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
+/* sub # */ CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
+/* sub # */ CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
</programlisting></para>
<para>
Insert data to the tables at the publisher side.
<programlisting>
-test_pub=# INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
-INSERT 0 3
-test_pub=# INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C');
-INSERT 0 3
-test_pub=# INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii');
-INSERT 0 3
+/* pub # */ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
+/* pub # */ INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C');
+/* pub # */ INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii');
</programlisting></para>
<para>
<link linkend="sql-createpublication-params-with-publish"><literal>publish</literal></link>
operations. The publication <literal>pub3b</literal> has a row filter (see
<xref linkend="logical-replication-row-filter"/>).
-<programlisting>
-test_pub=# CREATE PUBLICATION pub1 FOR TABLE t1;
-CREATE PUBLICATION
-test_pub=# CREATE PUBLICATION pub2 FOR TABLE t2 WITH (publish = 'truncate');
-CREATE PUBLICATION
-test_pub=# CREATE PUBLICATION pub3a FOR TABLE t3 WITH (publish = 'truncate');
-CREATE PUBLICATION
-test_pub=# CREATE PUBLICATION pub3b FOR TABLE t3 WHERE (e > 5);
-CREATE PUBLICATION
-</programlisting></para>
+<programlisting><![CDATA[
+/* pub # */ CREATE PUBLICATION pub1 FOR TABLE t1;
+/* pub # */ CREATE PUBLICATION pub2 FOR TABLE t2 WITH (publish = 'truncate');
+/* pub # */ CREATE PUBLICATION pub3a FOR TABLE t3 WITH (publish = 'truncate');
+/* pub # */ CREATE PUBLICATION pub3b FOR TABLE t3 WHERE (e > 5);
+]]></programlisting></para>
<para>
Create subscriptions for the publications. The subscription
<literal>sub3</literal> subscribes to both <literal>pub3a</literal> and
<literal>pub3b</literal>. All subscriptions will copy initial data by default.
<programlisting>
-test_sub=# CREATE SUBSCRIPTION sub1
-test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub1'
-test_sub-# PUBLICATION pub1;
-CREATE SUBSCRIPTION
-test_sub=# CREATE SUBSCRIPTION sub2
-test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub2'
-test_sub-# PUBLICATION pub2;
-CREATE SUBSCRIPTION
-test_sub=# CREATE SUBSCRIPTION sub3
-test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub3'
-test_sub-# PUBLICATION pub3a, pub3b;
-CREATE SUBSCRIPTION
+/* sub # */ CREATE SUBSCRIPTION sub1
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub1'
+/* sub - */ PUBLICATION pub1;
+/* sub # */ CREATE SUBSCRIPTION sub2
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub2'
+/* sub - */ PUBLICATION pub2;
+/* sub # */ CREATE SUBSCRIPTION sub3
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=sub3'
+/* sub - */ PUBLICATION pub3a, pub3b;
</programlisting></para>
<para>
Observe that initial table data is copied, regardless of the
<literal>publish</literal> operation of the publication.
<programlisting>
-test_sub=# SELECT * FROM t1;
+/* sub # */ SELECT * FROM t1;
a | b
---+-------
1 | one
3 | three
(3 rows)
-test_sub=# SELECT * FROM t2;
+/* sub # */ SELECT * FROM t2;
c | d
---+---
1 | A
it means the copied table <literal>t3</literal> contains all rows even when
they do not match the row filter of publication <literal>pub3b</literal>.
<programlisting>
-test_sub=# SELECT * FROM t3;
+/* sub # */ SELECT * FROM t3;
e | f
---+-----
1 | i
<para>
Insert more data to the tables at the publisher side.
<programlisting>
-test_pub=# INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six');
-INSERT 0 3
-test_pub=# INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F');
-INSERT 0 3
-test_pub=# INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi');
-INSERT 0 3
+/* pub # */ INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six');
+/* pub # */ INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F');
+/* pub # */ INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi');
</programlisting></para>
<para>
Now the publisher side data looks like:
<programlisting>
-test_pub=# SELECT * FROM t1;
+/* pub # */ SELECT * FROM t1;
a | b
---+-------
1 | one
6 | six
(6 rows)
-test_pub=# SELECT * FROM t2;
+/* pub # */ SELECT * FROM t2;
c | d
---+---
1 | A
6 | F
(6 rows)
-test_pub=# SELECT * FROM t3;
+/* pub # */ SELECT * FROM t3;
e | f
---+-----
1 | i
only replicate data that matches the row filter of <literal>pub3b</literal>.
Now the subscriber side data looks like:
<programlisting>
-test_sub=# SELECT * FROM t1;
+/* sub # */ SELECT * FROM t1;
a | b
---+-------
1 | one
6 | six
(6 rows)
-test_sub=# SELECT * FROM t2;
+/* sub # */ SELECT * FROM t2;
c | d
---+---
1 | A
3 | C
(3 rows)
-test_sub=# SELECT * FROM t3;
+/* sub # */ SELECT * FROM t3;
e | f
---+-----
1 | i
<para>
First, create a publication for the examples to use.
<programlisting>
-test_pub=# CREATE PUBLICATION pub1 FOR ALL TABLES;
-CREATE PUBLICATION
+/* pub # */ CREATE PUBLICATION pub1 FOR ALL TABLES;
</programlisting></para>
<para>
Example 1: Where the subscription says <literal>connect = false</literal>
<para>
Create the subscription.
<programlisting>
-test_sub=# CREATE SUBSCRIPTION sub1
-test_sub-# CONNECTION 'host=localhost dbname=test_pub'
-test_sub-# PUBLICATION pub1
-test_sub-# WITH (connect=false);
+/* sub # */ CREATE SUBSCRIPTION sub1
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub'
+/* sub - */ PUBLICATION pub1
+/* sub - */ WITH (connect=false);
WARNING: subscription was created, but is not connected
HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription.
-CREATE SUBSCRIPTION
</programlisting></para>
</listitem>
<listitem>
specified during <literal>CREATE SUBSCRIPTION</literal>, the name of the
slot to create is same as the subscription name, e.g. "sub1".
<programlisting>
-test_pub=# SELECT * FROM pg_create_logical_replication_slot('sub1', 'pgoutput');
+/* pub # */ SELECT * FROM pg_create_logical_replication_slot('sub1', 'pgoutput');
slot_name | lsn
-----------+-----------
sub1 | 0/19404D0
On the subscriber, complete the activation of the subscription. After
this the tables of <literal>pub1</literal> will start replicating.
<programlisting>
-test_sub=# ALTER SUBSCRIPTION sub1 ENABLE;
-ALTER SUBSCRIPTION
-test_sub=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE;
+/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
</programlisting></para>
</listitem>
</itemizedlist>
<para>
Create the subscription.
<programlisting>
-test_sub=# CREATE SUBSCRIPTION sub1
-test_sub-# CONNECTION 'host=localhost dbname=test_pub'
-test_sub-# PUBLICATION pub1
-test_sub-# WITH (connect=false, slot_name='myslot');
+/* sub # */ CREATE SUBSCRIPTION sub1
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub'
+/* sub - */ PUBLICATION pub1
+/* sub - */ WITH (connect=false, slot_name='myslot');
WARNING: subscription was created, but is not connected
HINT: To initiate replication, you must manually create the replication slot, enable the subscription, and refresh the subscription.
-CREATE SUBSCRIPTION
</programlisting></para>
</listitem>
<listitem>
On the publisher, manually create a slot using the same name that was
specified during <literal>CREATE SUBSCRIPTION</literal>, e.g. "myslot".
<programlisting>
-test_pub=# SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput');
+/* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput');
slot_name | lsn
-----------+-----------
myslot | 0/19059A0
On the subscriber, the remaining subscription activation steps are the
same as before.
<programlisting>
-test_sub=# ALTER SUBSCRIPTION sub1 ENABLE;
-ALTER SUBSCRIPTION
-test_sub=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE;
+/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
</programlisting></para>
</listitem>
</itemizedlist>
<literal>enabled = false</literal>, and
<literal>create_slot = false</literal> are also needed.
<programlisting>
-test_sub=# CREATE SUBSCRIPTION sub1
-test_sub-# CONNECTION 'host=localhost dbname=test_pub'
-test_sub-# PUBLICATION pub1
-test_sub-# WITH (slot_name=NONE, enabled=false, create_slot=false);
-CREATE SUBSCRIPTION
+/* sub # */ CREATE SUBSCRIPTION sub1
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub'
+/* sub - */ PUBLICATION pub1
+/* sub - */ WITH (slot_name=NONE, enabled=false, create_slot=false);
</programlisting></para>
</listitem>
<listitem>
<para>
On the publisher, manually create a slot using any name, e.g. "myslot".
<programlisting>
-test_pub=# SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput');
+/* pub # */ SELECT * FROM pg_create_logical_replication_slot('myslot', 'pgoutput');
slot_name | lsn
-----------+-----------
myslot | 0/1905930
On the subscriber, associate the subscription with the slot name just
created.
<programlisting>
-test_sub=# ALTER SUBSCRIPTION sub1 SET (slot_name='myslot');
-ALTER SUBSCRIPTION
+/* sub # */ ALTER SUBSCRIPTION sub1 SET (slot_name='myslot');
</programlisting></para>
</listitem>
<listitem>
<para>
The remaining subscription activation steps are same as before.
<programlisting>
-test_sub=# ALTER SUBSCRIPTION sub1 ENABLE;
-ALTER SUBSCRIPTION
-test_sub=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* sub # */ ALTER SUBSCRIPTION sub1 ENABLE;
+/* sub # */ ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
</programlisting></para>
</listitem>
</itemizedlist>
will return the relevant replication slots associated with the
failover-enabled subscriptions.
<programlisting>
-test_sub=# SELECT
+/* sub # */ SELECT
array_agg(quote_literal(s.subslotname)) AS slots
FROM pg_subscription s
WHERE s.subfailover AND
as they will either be dropped or re-created on the new primary server in those
cases.
<programlisting>
-test_sub=# SELECT
+/* sub # */ SELECT
array_agg(quote_literal(slot_name)) AS slots
FROM
(
Check that the logical replication slots identified above exist on
the standby server and are ready for failover.
<programlisting>
-test_standby=# SELECT slot_name, (synced AND NOT temporary AND NOT conflicting) AS failover_ready
+/* standby # */ SELECT slot_name, (synced AND NOT temporary AND NOT conflicting) AS failover_ready
FROM pg_replication_slots
WHERE slot_name IN
('sub1','sub2','sub3', 'pg_16394_sync_16385_7394666715149055164');
<para>
Create some tables to be used in the following examples.
<programlisting>
-test_pub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
-CREATE TABLE
-test_pub=# CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d));
-CREATE TABLE
-test_pub=# CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g));
-CREATE TABLE
+/* pub # */ CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
+/* pub # */ CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d));
+/* pub # */ CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g));
</programlisting></para>
<para>
<literal>p2</literal> has two tables. Table <literal>t1</literal> has no row
filter, and table <literal>t2</literal> has a row filter. Publication
<literal>p3</literal> has two tables, and both of them have a row filter.
-<programlisting>
-test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a > 5 AND c = 'NSW');
-CREATE PUBLICATION
-test_pub=# CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99);
-CREATE PUBLICATION
-test_pub=# CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10);
-CREATE PUBLICATION
-</programlisting></para>
+<programlisting><![CDATA[
+/* pub # */ CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a > 5 AND c = 'NSW');
+/* pub # */ CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99);
+/* pub # */ CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10);
+]]></programlisting></para>
<para>
<command>psql</command> can be used to show the row filter expressions (if
defined) for each publication.
-<programlisting>
-test_pub=# \dRp+
- Publication p1
+<programlisting><![CDATA[
+/* pub # */ \dRp+
+ Publication p1
Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
----------+------------+---------+---------+---------+-----------+----------
postgres | f | t | t | t | t | f
Tables:
- "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text))
+ "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text))
- Publication p2
+ Publication p2
Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
----------+------------+---------+---------+---------+-----------+----------
postgres | f | t | t | t | t | f
Tables:
- "public.t1"
- "public.t2" WHERE (e = 99)
+ "public.t1"
+ "public.t2" WHERE (e = 99)
- Publication p3
+ Publication p3
Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
----------+------------+---------+---------+---------+-----------+----------
postgres | f | t | t | t | t | f
Tables:
- "public.t2" WHERE (d = 10)
- "public.t3" WHERE (g = 10)
-</programlisting></para>
+ "public.t2" WHERE (d = 10)
+ "public.t3" WHERE (g = 10)
+]]></programlisting></para>
<para>
<command>psql</command> can be used to show the row filter expressions (if
of two publications, but has a row filter only in <literal>p1</literal>.
See that table <literal>t2</literal> is a member of two publications, and
has a different row filter in each of them.
-<programlisting>
-test_pub=# \d t1
+<programlisting><![CDATA[
+/* pub # */ \d t1
Table "public.t1"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
"p1" WHERE ((a > 5) AND (c = 'NSW'::text))
"p2"
-test_pub=# \d t2
+/* pub # */ \d t2
Table "public.t2"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
"p2" WHERE (e = 99)
"p3" WHERE (d = 10)
-test_pub=# \d t3
+/* pub # */ \d t3
Table "public.t3"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
"t3_pkey" PRIMARY KEY, btree (g)
Publications:
"p3" WHERE (g = 10)
-</programlisting></para>
+]]></programlisting></para>
<para>
On the subscriber node, create a table <literal>t1</literal> with the same
definition as the one on the publisher, and also create the subscription
<literal>s1</literal> that subscribes to the publication <literal>p1</literal>.
<programlisting>
-test_sub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
-CREATE TABLE
-test_sub=# CREATE SUBSCRIPTION s1
-test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
-test_sub-# PUBLICATION p1;
-CREATE SUBSCRIPTION
+/* sub # */ CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
+/* sub # */ CREATE SUBSCRIPTION s1
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1'
+/* sub - */ PUBLICATION p1;
</programlisting></para>
<para>
Insert some rows. Only the rows satisfying the <literal>t1 WHERE</literal>
clause of publication <literal>p1</literal> are replicated.
<programlisting>
-test_pub=# INSERT INTO t1 VALUES (2, 102, 'NSW');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES (3, 103, 'QLD');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES (4, 104, 'VIC');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES (5, 105, 'ACT');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES (6, 106, 'NSW');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES (7, 107, 'NT');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES (8, 108, 'QLD');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES (9, 109, 'NSW');
-INSERT 0 1
-
-test_pub=# SELECT * FROM t1;
+/* pub # */ INSERT INTO t1 VALUES (2, 102, 'NSW');
+/* pub # */ INSERT INTO t1 VALUES (3, 103, 'QLD');
+/* pub # */ INSERT INTO t1 VALUES (4, 104, 'VIC');
+/* pub # */ INSERT INTO t1 VALUES (5, 105, 'ACT');
+/* pub # */ INSERT INTO t1 VALUES (6, 106, 'NSW');
+/* pub # */ INSERT INTO t1 VALUES (7, 107, 'NT');
+/* pub # */ INSERT INTO t1 VALUES (8, 108, 'QLD');
+/* pub # */ INSERT INTO t1 VALUES (9, 109, 'NSW');
+
+/* pub # */ SELECT * FROM t1;
a | b | c
---+-----+-----
2 | 102 | NSW
(8 rows)
</programlisting>
<programlisting>
-test_sub=# SELECT * FROM t1;
+/* sub # */ SELECT * FROM t1;
a | b | c
---+-----+-----
6 | 106 | NSW
<literal>p1</literal>. The <command>UPDATE</command> replicates
the change as normal.
<programlisting>
-test_pub=# UPDATE t1 SET b = 999 WHERE a = 6;
-UPDATE 1
+/* pub # */ UPDATE t1 SET b = 999 WHERE a = 6;
-test_pub=# SELECT * FROM t1;
+/* pub # */ SELECT * FROM t1;
a | b | c
---+-----+-----
2 | 102 | NSW
(8 rows)
</programlisting>
<programlisting>
-test_sub=# SELECT * FROM t1;
+/* sub # */ SELECT * FROM t1;
a | b | c
---+-----+-----
9 | 109 | NSW
transformed into an <command>INSERT</command> and the change is replicated.
See the new row on the subscriber.
<programlisting>
-test_pub=# UPDATE t1 SET a = 555 WHERE a = 2;
-UPDATE 1
+/* pub # */ UPDATE t1 SET a = 555 WHERE a = 2;
-test_pub=# SELECT * FROM t1;
+/* pub # */ SELECT * FROM t1;
a | b | c
-----+-----+-----
3 | 103 | QLD
(8 rows)
</programlisting>
<programlisting>
-test_sub=# SELECT * FROM t1;
+/* sub # */ SELECT * FROM t1;
a | b | c
-----+-----+-----
9 | 109 | NSW
transformed into a <command>DELETE</command> and the change is replicated.
See that the row is removed from the subscriber.
<programlisting>
-test_pub=# UPDATE t1 SET c = 'VIC' WHERE a = 9;
-UPDATE 1
+/* pub # */ UPDATE t1 SET c = 'VIC' WHERE a = 9;
-test_pub=# SELECT * FROM t1;
+/* pub # */ SELECT * FROM t1;
a | b | c
-----+-----+-----
3 | 103 | QLD
(8 rows)
</programlisting>
<programlisting>
-test_sub=# SELECT * FROM t1;
+/* sub # */ SELECT * FROM t1;
a | b | c
-----+-----+-----
6 | 999 | NSW
<para>
Create a partitioned table on the publisher.
<programlisting>
-test_pub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
-CREATE TABLE
-test_pub=# CREATE TABLE child PARTITION OF parent DEFAULT;
-CREATE TABLE
+/* pub # */ CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
+/* pub # */ CREATE TABLE child PARTITION OF parent DEFAULT;
</programlisting>
Create the same tables on the subscriber.
<programlisting>
-test_sub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
-CREATE TABLE
-test_sub=# CREATE TABLE child PARTITION OF parent DEFAULT;
-CREATE TABLE
+/* sub # */ CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
+/* sub # */ CREATE TABLE child PARTITION OF parent DEFAULT;
</programlisting></para>
<para>
publication parameter <literal>publish_via_partition_root</literal> is set
as true. There are row filters defined on both the partitioned table
(<literal>parent</literal>), and on the partition (<literal>child</literal>).
-<programlisting>
-test_pub=# CREATE PUBLICATION p4 FOR TABLE parent WHERE (a < 5), child WHERE (a >= 5)
-test_pub-# WITH (publish_via_partition_root=true);
-CREATE PUBLICATION
-</programlisting>
-<programlisting>
-test_sub=# CREATE SUBSCRIPTION s4
-test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s4'
-test_sub-# PUBLICATION p4;
-CREATE SUBSCRIPTION
+<programlisting><![CDATA[
+/* pub # */ CREATE PUBLICATION p4 FOR TABLE parent WHERE (a < 5), child WHERE (a >= 5)
+/* pub - */ WITH (publish_via_partition_root=true);
+]]></programlisting>
+<programlisting>
+/* sub # */ CREATE SUBSCRIPTION s4
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s4'
+/* sub - */ PUBLICATION p4;
</programlisting></para>
<para>
<literal>parent</literal> (because <literal>publish_via_partition_root</literal>
is true).
<programlisting>
-test_pub=# INSERT INTO parent VALUES (2), (4), (6);
-INSERT 0 3
-test_pub=# INSERT INTO child VALUES (3), (5), (7);
-INSERT 0 3
+/* pub # */ INSERT INTO parent VALUES (2), (4), (6);
+/* pub # */ INSERT INTO child VALUES (3), (5), (7);
-test_pub=# SELECT * FROM parent ORDER BY a;
+/* pub # */ SELECT * FROM parent ORDER BY a;
a
---
2
(6 rows)
</programlisting>
<programlisting>
-test_sub=# SELECT * FROM parent ORDER BY a;
+/* sub # */ SELECT * FROM parent ORDER BY a;
a
---
2
Repeat the same test, but with a different value for <literal>publish_via_partition_root</literal>.
The publication parameter <literal>publish_via_partition_root</literal> is
set as false. A row filter is defined on the partition (<literal>child</literal>).
+<programlisting><![CDATA[
+/* pub # */ DROP PUBLICATION p4;
+/* pub # */ CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a >= 5)
+/* pub - */ WITH (publish_via_partition_root=false);
+]]></programlisting>
<programlisting>
-test_pub=# DROP PUBLICATION p4;
-DROP PUBLICATION
-test_pub=# CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a >= 5)
-test_pub-# WITH (publish_via_partition_root=false);
-CREATE PUBLICATION
-</programlisting>
-<programlisting>
-test_sub=# ALTER SUBSCRIPTION s4 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* sub # */ ALTER SUBSCRIPTION s4 REFRESH PUBLICATION;
</programlisting></para>
<para>
row filter of <literal>child</literal> (because
<literal>publish_via_partition_root</literal> is false).
<programlisting>
-test_pub=# TRUNCATE parent;
-TRUNCATE TABLE
-test_pub=# INSERT INTO parent VALUES (2), (4), (6);
-INSERT 0 3
-test_pub=# INSERT INTO child VALUES (3), (5), (7);
-INSERT 0 3
+/* pub # */ TRUNCATE parent;
+/* pub # */ INSERT INTO parent VALUES (2), (4), (6);
+/* pub # */ INSERT INTO child VALUES (3), (5), (7);
-test_pub=# SELECT * FROM parent ORDER BY a;
+/* pub # */ SELECT * FROM parent ORDER BY a;
a
---
2
(6 rows)
</programlisting>
<programlisting>
-test_sub=# SELECT * FROM child ORDER BY a;
+/* sub # */ SELECT * FROM child ORDER BY a;
a
---
5
<para>
Create a table <literal>t1</literal> to be used in the following example.
<programlisting>
-test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id));
-CREATE TABLE
+/* pub # */ CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id));
</programlisting></para>
<para>
replicated. Notice that the order of column names in the column list does
not matter.
<programlisting>
-test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d);
-CREATE PUBLICATION
+/* pub # */ CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d);
</programlisting></para>
<para>
<literal>psql</literal> can be used to show the column lists (if defined)
for each publication.
<programlisting>
-test_pub=# \dRp+
+/* pub # */ \dRp+
Publication p1
Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
----------+------------+---------+---------+---------+-----------+----------
<literal>psql</literal> can be used to show the column lists (if defined)
for each table.
<programlisting>
-test_pub=# \d t1
+/* pub # */ \d t1
Table "public.t1"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
<literal>s1</literal> that subscribes to the publication
<literal>p1</literal>.
<programlisting>
-test_sub=# CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id));
-CREATE TABLE
-test_sub=# CREATE SUBSCRIPTION s1
-test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
-test_sub-# PUBLICATION p1;
-CREATE SUBSCRIPTION
+/* sub # */ CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id));
+/* sub # */ CREATE SUBSCRIPTION s1
+/* sub - */ CONNECTION 'host=localhost dbname=test_pub application_name=s1'
+/* sub - */ PUBLICATION p1;
</programlisting></para>
<para>
On the publisher node, insert some rows to table <literal>t1</literal>.
<programlisting>
-test_pub=# INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2');
-INSERT 0 1
-test_pub=# INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3');
-INSERT 0 1
-test_pub=# SELECT * FROM t1 ORDER BY id;
+/* pub # */ INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1');
+/* pub # */ INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2');
+/* pub # */ INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3');
+/* pub # */ SELECT * FROM t1 ORDER BY id;
id | a | b | c | d | e
----+-----+-----+-----+-----+-----
1 | a-1 | b-1 | c-1 | d-1 | e-1
Only data from the column list of publication <literal>p1</literal> is
replicated.
<programlisting>
-test_sub=# SELECT * FROM t1 ORDER BY id;
+/* sub # */ SELECT * FROM t1 ORDER BY id;
id | b | a | d
----+-----+-----+-----
1 | b-1 | a-1 | d-1
For example, note below that subscriber table generated column value comes from the
subscriber column's calculation.
<programlisting>
-test_pub=# CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a + 1) STORED);
-CREATE TABLE
-test_pub=# INSERT INTO tab_gen_to_gen VALUES (1),(2),(3);
-INSERT 0 3
-test_pub=# CREATE PUBLICATION pub1 FOR TABLE tab_gen_to_gen;
-CREATE PUBLICATION
-test_pub=# SELECT * FROM tab_gen_to_gen;
+/* pub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a + 1) STORED);
+/* pub # */ INSERT INTO tab_gen_to_gen VALUES (1),(2),(3);
+/* pub # */ CREATE PUBLICATION pub1 FOR TABLE tab_gen_to_gen;
+/* pub # */ SELECT * FROM tab_gen_to_gen;
a | b
---+---
1 | 2
3 | 4
(3 rows)
-test_sub=# CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a * 100) STORED);
-CREATE TABLE
-test_sub=# CREATE SUBSCRIPTION sub1 CONNECTION 'dbname=test_pub' PUBLICATION pub1;
-CREATE SUBSCRIPTION
-test_sub=# SELECT * from tab_gen_to_gen;
+/* sub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a * 100) STORED);
+/* sub # */ CREATE SUBSCRIPTION sub1 CONNECTION 'dbname=test_pub' PUBLICATION pub1;
+/* sub # */ SELECT * from tab_gen_to_gen;
a | b
---+----
1 | 100
<link linkend="sql-altersubscription-params-disable"><command>ALTER SUBSCRIPTION ... DISABLE</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
</programlisting>
</para>
</step>
<xref linkend="two-node-cluster-disable-subscriptions-node2"/>
and now, e.g.:
<programlisting>
-node2=# CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
-CREATE TABLE
+/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-enable"><command>ALTER SUBSCRIPTION ... ENABLE</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-refresh-publication"><command>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-disable"><command>ALTER SUBSCRIPTION ... DISABLE</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-disable"><command>ALTER SUBSCRIPTION ... DISABLE</command></link>,
e.g.:
<programlisting>
-node3=# ALTER SUBSCRIPTION sub1_node2_node3 DISABLE;
-ALTER SUBSCRIPTION
+/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 DISABLE;
</programlisting>
</para>
</step>
<xref linkend="cascaded-cluster-disable-sub-node1-node2"/>
and now, e.g.:
<programlisting>
-node2=# CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
-CREATE TABLE
+/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-enable"><command>ALTER SUBSCRIPTION ... ENABLE</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-refresh-publication"><command>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
</programlisting>
</para>
</step>
<xref linkend="cascaded-cluster-disable-sub-node2-node3"/> and now,
e.g.:
<programlisting>
-node3=# CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
-CREATE TABLE
+/* node3 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-enable"><command>ALTER SUBSCRIPTION ... ENABLE</command></link>,
e.g.:
<programlisting>
-node3=# ALTER SUBSCRIPTION sub1_node2_node3 ENABLE;
-ALTER SUBSCRIPTION
+/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 ENABLE;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-refresh-publication"><command>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</command></link>,
e.g.:
<programlisting>
-node3=# ALTER SUBSCRIPTION sub1_node2_node3 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* node3 # */ ALTER SUBSCRIPTION sub1_node2_node3 REFRESH PUBLICATION;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-disable"><command>ALTER SUBSCRIPTION ... DISABLE</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 DISABLE;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-enable"><command>ALTER SUBSCRIPTION ... ENABLE</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 ENABLE;
</programlisting>
</para>
</step>
<literal>node2</literal> between <xref linkend="circular-cluster-disable-sub-node2"/>
and now, e.g.:
<programlisting>
-node1=# CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
-CREATE TABLE
+/* node1 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-refresh-publication"><command>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</command></link>,
e.g.:
<programlisting>
-node1=# ALTER SUBSCRIPTION sub1_node2_node1 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 REFRESH PUBLICATION;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-disable"><command>ALTER SUBSCRIPTION ... DISABLE</command></link>,
e.g.:
<programlisting>
-node1=# ALTER SUBSCRIPTION sub1_node2_node1 DISABLE;
-ALTER SUBSCRIPTION
+/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 DISABLE;
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-enable"><command>ALTER SUBSCRIPTION ... ENABLE</command></link>,
e.g.:
<programlisting>
-node1=# ALTER SUBSCRIPTION sub1_node2_node1 ENABLE;
-ALTER SUBSCRIPTION
+/* node1 # */ ALTER SUBSCRIPTION sub1_node2_node1 ENABLE;
</programlisting>
</para>
</step>
the upgraded <literal>node1</literal> between <xref linkend="circular-cluster-disable-sub-node1"/>
and now, e.g.:
<programlisting>
-node2=# CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
-CREATE TABLE
+/* node2 # */ CREATE TABLE distributors (did integer PRIMARY KEY, name varchar(40));
</programlisting>
</para>
</step>
<link linkend="sql-altersubscription-params-refresh-publication"><command>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</command></link>,
e.g.:
<programlisting>
-node2=# ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
-ALTER SUBSCRIPTION
+/* node2 # */ ALTER SUBSCRIPTION sub1_node1_node2 REFRESH PUBLICATION;
</programlisting>
</para>
</step>