2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不受支持的版本:11 / 10

CREATE PUBLICATION

CREATE PUBLICATION — 定义新的发布

语法

CREATE PUBLICATION name
    [ FOR ALL TABLES
      | FOR publication_object [, ... ] ]
    [ WITH ( publication_parameter [= value] [, ... ] ) ]

where publication_object is one of:

    TABLE [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] [, ... ]
    TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ]

描述

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

发布本质上是一组表的集合,其数据更改旨在通过逻辑复制进行复制。有关发布如何适应逻辑复制设置的详细信息,请参阅第 29.1 节

参数

name #

新发布的名称。

FOR TABLE #

指定要添加到发布的表列表。如果在表名前指定了ONLY,则仅将该表添加到发布中。如果未指定ONLY,则会添加该表及其所有后代表(如果有)。可选地,可以在表名后指定*以明确指示包含后代表。但是,这并不适用于分区表。分区表的各分区始终被隐式地视为发布的一部分,因此永远不会显式地添加到发布中。

如果指定了可选的WHERE子句,则它定义了一个行过滤器表达式。对于expression计算结果为假或空的行将不会发布。请注意,表达式周围需要括号。它对TRUNCATE命令没有影响。

当指定列列表时,仅复制指定的列。如果没有指定列列表,则通过此发布复制表的全部列,包括以后添加的任何列。它对TRUNCATE命令没有影响。有关列列表的详细信息,请参阅第 29.5 节

只有持久的基本表和分区表可以是发布的一部分。临时表、非日志表、外部表、物化视图和普通视图不能是发布的一部分。

当发布也发布FOR TABLES IN SCHEMA时,不支持指定列列表。

当将分区表添加到发布时,其所有现有和将来的分区都隐式地被视为发布的一部分。因此,即使直接对分区执行的操作也会通过其祖先所属的发布进行发布。

FOR ALL TABLES #

将发布标记为一个复制数据库中所有表(包括将来创建的表)更改的发布。

FOR TABLES IN SCHEMA #

将发布标记为一个复制指定架构列表中所有表(包括将来创建的表)更改的发布。

当发布还发布具有列列表的表时,不支持指定架构。

只有架构中存在的持久基本表和分区表将包含在发布中。架构中的临时表、非日志表、外部表、物化视图和普通视图将不会是发布的一部分。

当通过架构级发布发布分区表时,其所有现有和将来的分区都隐式地被视为发布的一部分,无论它们是否来自发布架构。因此,即使直接对分区执行的操作也会通过其祖先所属的发布进行发布。

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

此子句指定发布的可选参数。支持以下参数

publish (string) #

此参数确定新发布将向订阅者发布哪些DML操作。该值是操作的逗号分隔列表。允许的操作为insertupdatedeletetruncate。默认值为发布所有操作,因此此选项的默认值为'insert, update, delete, truncate'

此参数仅影响DML操作。特别是,逻辑复制的初始数据同步(请参阅第 29.8.1 节)在复制现有表数据时不会考虑此参数。

publish_via_partition_root (boolean) #

此参数确定发布中包含的分区表(或其分区)中的更改将使用分区表的标识和架构发布,而不是使用实际更改的各个分区的标识和架构;后者是默认值。启用此选项允许将更改复制到非分区表或由不同分区集组成的分区表中。

可能存在订阅组合多个发布的情况。如果任何已订阅的发布都设置了publish_via_partition_root = true,则该发布发布的分区表(或其分区)上的更改将使用该分区表的标识和架构发布,而不是使用各个分区的标识和架构。

此参数还影响如何为分区选择行过滤器和列列表;有关详细信息,请参见下文。

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

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

注释

如果未指定FOR TABLEFOR ALL TABLESFOR TABLES IN SCHEMA,则发布将从空表集开始。如果以后要添加表或架构,这很有用。

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

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

要将表添加到发布,调用用户必须对该表拥有所有权。 FOR ALL TABLESFOR TABLES IN SCHEMA子句要求调用用户为超级用户。

发布UPDATE和/或DELETE操作的发布中添加的表必须定义REPLICA IDENTITY。否则,将不允许对这些表执行这些操作。

任何列列表都必须包括REPLICA IDENTITY列,以便发布UPDATEDELETE操作。如果发布仅发布INSERT操作,则没有列列表限制。

为了发布UPDATEDELETE操作,行过滤器表达式(即WHERE子句)只能包含REPLICA IDENTITY涵盖的列。对于INSERT操作的发布,可以在WHERE表达式中使用任何列。行过滤器允许简单的表达式,这些表达式不包含用户定义函数、用户定义运算符、用户定义类型、用户定义排序规则、不可变的内置函数或对系统列的引用。

如果指定了FOR TABLES IN SCHEMA并且表属于引用的架构,则表的行过滤器将变得冗余。

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

对于INSERT ... ON CONFLICT命令,发布将发布命令产生的操作。根据结果,它可能发布为INSERTUPDATE,或者根本不发布。

对于MERGE命令,发布将为插入、更新或删除的每一行发布INSERTUPDATEDELETE

将表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');

创建一个发布,发布表usersdepartments的所有更改以及架构production中所有表的所有更改

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

创建一个发布,发布架构marketingsales中所有表的所有更改

CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;

创建一个发布物,发布表 users 的所有更改,但仅复制 user_idfirstname 列。

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

兼容性

CREATE PUBLICATIONPostgreSQL 的扩展。

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用 此表单 报告文档问题。