From 508a24849f7ce177a8fa2d8da8daa9193570ee59 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Mon, 8 Aug 2022 18:28:06 +1000 Subject: [PATCH v1] Column Lists - new pgdocs section Add a new logical replication pgdocs section for "Column Lists" (analogous to the Row Filters page). Also update xrefs to that new page from CREATE/ALTER PUBLICATION. --- doc/src/sgml/logical-replication.sgml | 196 +++++++++++++++++++++++++++++++ doc/src/sgml/ref/alter_publication.sgml | 11 +- doc/src/sgml/ref/create_publication.sgml | 4 +- 3 files changed, 201 insertions(+), 10 deletions(-) diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index bdf1e7b..af0310d 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -1089,6 +1089,202 @@ test_sub=# SELECT * FROM child ORDER BY a; + + Column Lists + + + By default, all columns of a published table will be replicated to the + appropriate subscribers. The subscriber table must have at least all the + columns of the published table. However, if a column list + is specified then only the columns named in the list will be replicated. + This means the subscriber-side table only needs to have those columns named + by the column list. A user might choose to use column lists for behavioral, + security or performance reasons. + + + + Column List Rules + + + A column list is specified per table following the tablename, and enclosed by + parenthesis. The column name order of the list has no effect. See + for details. + + + + When a column list is specified, only the named columns are replicated. + If no column list is specified, all columns of the table are replicated + through this publication, including any columns added later. This means + a column list which names all columns is not quite the same as having no + column list at all. For example, if additional columns are added to the + table, then (after a REFRESH PUBLICATION) if there was + a column list only those named columns will continue to be replicated. + + + + + + Column List Restrictions + + + Column list can contain only simple column references. Complex + expressions, function calls etc. are not allowed. + + + + If a publication publishes UPDATE or + DELETE operations, any column list must include the table's + replica identity columns (see ). + If a publication publishes only INSERT operations, then + the column list is arbitrary and may omit some replica identity columns. + + + + Furthermore, if the table uses REPLICA IDENTITY FULL, + specifying a column list is not allowed. + + + + + + Partitioned Tables + + + For partitioned tables, the publication parameter + publish_via_partition_root determines which column list + is used. If publish_via_partition_root is + true, the root partitioned table's column list is used. + Otherwise, if publish_via_partition_root is + false (default), each partition's column list is used. + + + + + + Combining Multiple Column Lists + + + + It is not supported to have a subscription comprising several publications + where the same table has been published with different column lists. + This means changing the column lists of the tables being subscribed could + cause inconsistency of column lists among publications, in which case + the will be successful but later the + WalSender on the publisher, or the subscriber may throw an error. In this + scenario, the user needs to recreate the subscription after adjusting the + column list or drop the problematic publication using + ALTER SUBSCRIPTION ... DROP PUBLICATION and then add it + back after adjusting the column list. + + + Background: The main purpose of the column list feature is to allow statically + different table shapes on publisher and subscriber or hide sensitive + column data. In both cases, it doesn't seem to make sense to combine + column lists. + + + + + + + Examples + + + Create a table t1 to be used in the following example. + +test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id)); +CREATE TABLE +test_pub=# + + + + Create a publication p1. A column list is defined for + table t1 to reduce the number of columns that will be + replicated. + +test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, a, b, c); +CREATE PUBLICATION +test_pub=# + + + + psql can be used to show the column lists (if defined) + for each publication. + +test_pub=# \dRp+ + Publication p1 + Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root +----------+------------+---------+---------+---------+-----------+---------- + postgres | f | t | t | t | t | f +Tables: + "public.t1" (id, a, b, c) + + + + psql can be used to show the column lists (if defined) + for each table. + +test_pub=# \d t1 + Table "public.t1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + id | integer | | not null | + a | text | | | + b | text | | | + c | text | | | + d | text | | | + e | text | | | +Indexes: + "t1_pkey" PRIMARY KEY, btree (id) +Publications: + "p1" (id, a, b, c) + + + + On the subscriber node, create a table t1 which now + only needs a subset of the columns that were on the publisher table + t1, and also create the subscription s1 + that subscribes to the publication p1. + +test_sub=# CREATE TABLE t1(id int, a text, b text, c 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 + + + + Insert some rows to table t1. + +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; + id | a | b | c | d | e +----+-----+-----+-----+-----+----- + 1 | a-1 | b-1 | c-1 | d-1 | e-1 + 2 | a-2 | b-2 | c-2 | d-2 | e-2 + 3 | a-3 | b-3 | c-3 | d-3 | e-3 +(3 rows) + + +test_sub=# SELECT * FROM t1 ORDER BY id; + id | a | b | c +----+-----+-----+----- + 1 | a-1 | b-1 | c-1 + 2 | a-2 | b-2 | c-2 + 3 | a-3 | b-3 | c-3 +(3 rows) + + + + + + Conflicts diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml index 3e338f4..a8f283d 100644 --- a/doc/src/sgml/ref/alter_publication.sgml +++ b/doc/src/sgml/ref/alter_publication.sgml @@ -118,15 +118,8 @@ ALTER PUBLICATION name RENAME TO for details. Note that a subscription having several publications in which the same table has been published - with different column lists is not supported. So, changing the column - lists of the tables being subscribed could cause inconsistency of column - lists among publications, in which case ALTER PUBLICATION - will be successful but later the WalSender on the publisher or the - subscriber may throw an error. In this scenario, the user needs to - recreate the subscription after adjusting the column list or drop the - problematic publication using - ALTER SUBSCRIPTION ... DROP PUBLICATION and then add - it back after adjusting the column list. + with different column lists is not supported. See + for details of potential problems when altering column lists. diff --git a/doc/src/sgml/ref/create_publication.sgml b/doc/src/sgml/ref/create_publication.sgml index 2d6de8d..5669d51 100644 --- a/doc/src/sgml/ref/create_publication.sgml +++ b/doc/src/sgml/ref/create_publication.sgml @@ -90,7 +90,9 @@ CREATE PUBLICATION name When a column list is specified, only the named columns are replicated. If no column list is specified, all columns of the table are replicated - through this publication, including any columns added later. + through this publication, including any columns added later. See + for details about column + lists. -- 1.8.3.1