↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10
预发布版本文档。 PostgreSQL 19beta4 为测试版本,最终发布内容可能有所不同。

CREATE PUBLICATION

CREATE PUBLICATION — 定义一个新的发布

大纲

CREATE PUBLICATION name
    [ FOR { publication_object [, ... ] | publication_all_object [, ... ] } ]
    [ WITH ( publication_parameter [= value] [, ... ] ) ]

其中publication_object可以是:

    TABLE table_and_columns [, ... ]
    TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ]

其中publication_all_object可以是:

    ALL TABLES [ EXCEPT ( except_table_object [, ... ] ) ]
    ALL SEQUENCES

其中table_and_columns为:

    table_object [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ]

其中except_table_object为:

    TABLE table_object [, ... ]

其中table_object为:

   [ ONLY ] table_name [ * ]

描述

CREATE PUBLICATION 向当前数据库中添加一个新发布。该发布的名称必须不同于当前数据库中任何现有发布的名称。

发布本质上是一组表,其数据更改会通过逻辑复制进行复制。有关发布在逻辑复制配置中如何工作的详细信息,请参见第 29.1 节。

参数

name #

新发布的名称。

FOR TABLE #

指定要加入该发布的表列表。如果在表名前指定了 ONLY,则只有该表会被加入发布。如果未指定 ONLY,则该表及其所有后代表(如果有)都会被加入。也可以在表名后指定 *,以显式表明包含后代表。不过,这不适用于分区表。分区表的各个分区始终会被隐式视为发布的一部分,因此永远不会被显式加入发布。

如果指定了可选的 WHERE 子句,它会定义一个行过滤器表达式。对于 expression 求值为 false 或 NULL 的行,不会被发布。注意,表达式外必须加括号。它对 TRUNCATE 命令没有影响。

指定列列表时,只复制其中列出的列。列列表也可以包含存储生成列。如果省略列列表,则该发布默认复制所有非生成列(包括今后新增的列)。如果将 publish_generated_columns 设为 stored,也可以复制存储生成列。指定列列表对 TRUNCATE 命令没有影响。有关列列表的详细信息,请参见第 29.5 节。

只有持久基表和分区表才能成为发布的一部分。临时表、不记录 WAL 的表、外部表、物化视图和常规视图都不能成为发布的一部分。

如果该发布还包含 FOR TABLES IN SCHEMA,则不支持指定列列表。

将分区表加入发布时,其所有现有分区和未来分区都会被隐式视为发布的一部分。因此,即使直接在某个分区上执行的操作,也会通过其祖先表所在的发布进行发布。

FOR TABLES IN SCHEMA #

将该发布标记为复制指定模式列表中所有表的更改,包括未来创建的表。

如果该发布还发布带有列列表的表,则不支持指定模式。

只有该模式中的持久基表和分区表会被纳入发布。该模式中的临时表、不记录 WAL 的表、外部表、物化视图和常规视图都不会成为发布的一部分。

当通过模式级发布来发布分区表时,其所有现有分区和未来分区都会被隐式视为发布的一部分,无论这些分区是否位于该发布模式中。因此,即使直接在某个分区上执行的操作,也会通过其祖先表所在的发布进行发布。

FOR ALL TABLES #

将该发布标记为复制数据库中所有表的更改,包括未来创建的表。EXCEPT 子句中列出的表会被排除在发布之外。

FOR ALL SEQUENCES #

将该发布标记为同步数据库中所有序列的更改,包括未来创建的序列。

只有持久序列会被纳入发布。临时序列和不记录 WAL 的序列会被排除在发布之外。

EXCEPT #

该子句指定要从发布中排除的表列表。

一旦某个表被排除,该排除就会应用于该表,而不受其名称或模式影响。重命名该表,或使用 ALTER TABLE ... SET SCHEMA 将其移动到另一个模式,都不会取消该排除。

对于继承表,如果在表名前指定了 ONLY,则只有该表会被排除在发布之外。如果未指定 ONLY,则该表及其所有后代表(如果有)都会被排除。也可以在表名后指定*,以显式表明后代表会被排除。

对于分区表,EXCEPT 中只能指定根分区表。这样会将根表及其所有分区都从复制中排除。可选的 ONLY 和* 对分区表没有影响。

如果订阅包含多个发布,则可能出现某个表或分区在一个发布中被包含,而在另一个发布的 EXCEPT 子句中被显式或隐式排除的情况。在这种情况下,该表或分区仍会被视为包含在复制中。

WITH ( publication_parameter [= value] [, ... ] ) #

该子句指定发布的可选参数。当发布表时可使用该子句。此子句不适用于序列。支持以下参数:

publish (string) #

该参数决定新发布会向订阅者发布哪些 DML 操作。其值是一个以逗号分隔的操作列表。允许的操作有 insert、update、delete 和 truncate。默认会发布所有操作,因此该选项的默认值为 'insert, update, delete, truncate'。

该参数只影响 DML 操作。特别是,逻辑复制的初始数据同步(参见第 29.10.1 节)在复制现有表数据时不会考虑该参数。

publish_generated_columns (enum) #

指定是否复制与该发布关联的表中存在的生成列。可选值为 none 和 stored。

默认值为 none,表示不会复制与该发布关联的表中的生成列。

如果设为 stored,则会复制与该发布关联的表中的存储生成列。

注意

如果订阅端版本早于 18,那么即使发布端的 publish_generated_columns 参数为 stored,初始表同步时也不会复制生成列。

有关生成列逻辑复制的更多细节,请参见第 29.6 节。

publish_via_partition_root (boolean) #

该参数控制如何发布分区表(或其任一分区)上的更改。设为 true 时,更改会使用根分区表的标识和模式来发布。设为 false(默认值)时,更改会使用实际发生更改的各个分区的标识和模式来发布。启用该选项后,可以将这些更改复制到非分区表,或者复制到分区结构与发布端不同的分区表。

订阅可能会组合多个发布。如果任一已订阅发布以 publish_via_partition_root = true 发布某个分区表,那么该分区表(或其分区)上的更改将使用该分区表本身的标识和模式来发布,而不是使用各个分区的标识和模式。

该参数还会影响为分区选择行过滤器和列列表的方式;详见下文。

如果启用该选项,直接对分区执行的 TRUNCATE 操作不会被复制。

当指定 boolean 类型的参数时,可以省略 = value 部分,这等价于指定 TRUE。

注解

如果未指定 FOR TABLE、FOR TABLES IN SCHEMA、FOR ALL TABLES 或 FOR ALL SEQUENCES,则该发布开始时不包含任何表。这在稍后还要添加表或模式时很有用。

创建发布不会启动复制。它只为未来的订阅者定义分组和过滤逻辑。

要创建发布,调用用户必须具有当前数据库的 CREATE 权限。(当然,超级用户会绕过这一检查。)

要向发布中添加表,调用用户必须拥有该表。使用 FOR TABLES IN SCHEMA、FOR ALL TABLES 和 FOR ALL SEQUENCES 子句要求调用用户是超级用户。

如果某个发布发布 UPDATE 和/或 DELETE 操作,则加入该发布的表必须已经定义 REPLICA IDENTITY。否则,在这些表上将不允许执行这些操作。

任何列列表都必须包含 REPLICA IDENTITY 列,这样 UPDATE 或 DELETE 操作才能被发布。如果该发布只发布 INSERT 操作,则列列表没有限制。

行过滤表达式(即 WHERE 子句)必须只包含 REPLICA IDENTITY 所覆盖的列,这样 UPDATE 和 DELETE 操作才能被发布。对于发布 INSERT 操作,可以在 WHERE 表达式中使用任何列。行过滤器只允许简单表达式。它不能包含用户定义的函数、操作符、类型和排序规则、系统列引用,或非不可变内置函数。

属于 REPLICA IDENTITY 的生成列必须被显式发布,即要么将其列入列列表,要么启用 publish_generated_columns 选项,这样 UPDATE 和 DELETE 操作才能被发布。

如果指定了 FOR TABLES IN SCHEMA,并且该表属于所引用的模式,那么该表上的行过滤器就是多余的。

对于已发布的分区表,如果发布参数 publish_via_partition_root 为 true,则每个分区的行过滤器取自已发布的分区表;如果为 false(默认值),则取自分区本身。有关行过滤器的详细信息,请参见第 29.4 节。类似地,对于已发布的分区表,如果发布参数 publish_via_partition_root 为 true,则每个分区的列列表取自已发布的分区表;如果为 false,则取自分区本身。

对于 INSERT ... ON CONFLICT 命令,发布会发布该命令实际产生的操作。根据执行结果,它可能被发布为 INSERT 或 UPDATE,也可能根本不被发布。

对于 MERGE 命令,发布会为每一行被插入、更新或删除的记录发布一个 INSERT、UPDATE 或 DELETE。

将表 ATTACH 到某个分区树中,而该分区树的根通过 publish_via_partition_root 设为 true 的发布进行发布时,不会复制该表的现有内容。

COPY ... FROM 命令会作为 INSERT 操作发布。

DDL 操作不会被发布。

WHERE 子句表达式会使用复制连接所用的同一角色来执行。

示例

创建一个发布,发布两个表中的所有更改:

CREATE PUBLICATION mypublication FOR TABLE users, departments;

创建一个发布,发布活跃部门中的所有更改:

CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE);

创建一个发布,发布所有表的所有更改:

CREATE PUBLICATION alltables FOR ALL TABLES;

创建一个只发布 INSERT 操作、且只针对一个表的发布:

CREATE PUBLICATION insert_only FOR TABLE mydata
    WITH (publish = 'insert');

创建一个发布,发布表 users、departments 的所有更改,以及模式 production 中所有表的所有更改:

CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production;

创建一个发布,发布模式 marketing 和 sales 中所有表的所有更改:

CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;

创建一个发布,发布表 users 的所有更改,但只复制 user_id 和 firstname 两列:

CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname);

创建一个发布,用于同步所有序列:

CREATE PUBLICATION all_sequences FOR ALL SEQUENCES;

创建一个发布,发布所有表的所有更改,以及用于同步的所有序列:

CREATE PUBLICATION all_tables_sequences FOR ALL TABLES, ALL SEQUENCES;

创建一个发布,发布所有表的所有更改,但排除 users 和 departments:

CREATE PUBLICATION all_tables_except FOR ALL TABLES EXCEPT (TABLE users, departments);

创建一个发布,用于同步所有序列,并发布所有表的所有更改,但排除 users 和 departments:

CREATE PUBLICATION all_sequences_tables_except FOR ALL SEQUENCES, ALL TABLES EXCEPT (TABLE users, departments);

兼容性

CREATE PUBLICATION 是 PostgreSQL 的扩展。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.