选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

文档 / SQL 命令 / 逻辑复制

SQL COMMAND · 逻辑复制

CREATE PUBLICATION

定义一个新的发布

CREATE逻辑复制引入 10(基线)现存至 20 devel2 次语法变更

动词
CREATE
对象
PUBLICATION
引入版本
10(基线)
状态
现存
语法变更次数
2
手册小节数
6

本站手册 · 18官方文档 ↗

版本轨迹

相对 PostgreSQL 17 语法未变,正文有更新。

语法铁道图 PostgreSQL 18

沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。

CREATE PUBLICATION name FOR ALL TABLES FOR publication_object , WITH ( publication_parameter = value , )
publication_object
TABLE table_and_columns , TABLES IN SCHEMA schema_name CURRENT_SCHEMA ,
table_and_columns
ONLY table_name * ( column_name , ) WHERE ( expression )

语法概要

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

其中publication_object可以是:

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

其中table_and_columns为:

    [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ]

PostgreSQL 18 手册 · 查看完整参考页

描述

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

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

参数

name

新发布的名称。

FOR TABLE

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

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

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

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

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

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

FOR ALL TABLES

将该发布标记为复制数据库中所有表的更改,包括未来创建的表。

FOR TABLES IN SCHEMA

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

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

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

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

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

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

publish (string)

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

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

publish_generated_columns (enum)

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

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

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

Note

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

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

publish_via_partition_root (boolean)

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

订阅可能会组合多个发布。如果任一已订阅发布以 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操作,则列列表没有限制。

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

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

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

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

对于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 的扩展。

又见

语法演化

相邻大版本之间的差异,新的在前。版本号链接到对应快照。

  1. PostgreSQL 20← 19正文更新

    正文更新
  2. PostgreSQL 19← 18语法变化

    + [ FOR { publication_object [, ... ] | publication_all_object [, ... ] } ]+ 其中publication_all_object可以是:+ + ALL TABLES [ EXCEPT ( except_table_object [, ... ] ) ]+ ALL SEQUENCES+ + table_object [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ]+ 其中except_table_object为:+ + TABLE table_object [, ... ]+ + 其中table_object为:+ + [ ONLY ] table_name [ * ]− [ FOR ALL TABLES− | FOR publication_object [, ... ] ]− [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ]正文更新
  3. PostgreSQL 18← 17正文更新

    正文更新
  4. PostgreSQL 17← 16正文更新

    正文更新
  5. PostgreSQL 16← 15正文更新

    正文更新
  6. PostgreSQL 15← 14正文更新

    正文更新
  7. PostgreSQL 14← 13语法变化

    + [ FOR ALL TABLES+ | FOR publication_object [, ... ] ]+ + 其中publication_object可以是:+ + TABLE table_and_columns [, ... ]+ TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ]+ + 其中table_and_columns为:+ + [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ]− [ FOR TABLE [ ONLY ] table_name [ * ] [, ...]− | FOR ALL TABLES ]正文更新
  8. PostgreSQL 13← 12正文更新

    正文更新
  9. PostgreSQL 12← 11正文更新

    正文更新
  10. PostgreSQL 11← 10正文更新

    正文更新

同组命令

命令动词对象版本变动最近变更
LOGICAL REPLICATION逻辑复制6 条
CREATE PUBLICATIONCREATEPUBLICATION 192 次
定义一个新的发布现存
ALTER PUBLICATIONALTERPUBLICATION 192 次
修改发布的定义现存
DROP PUBLICATIONDROPPUBLICATION
移除一个发布现存
CREATE SUBSCRIPTIONCREATESUBSCRIPTION 191 次
定义一个新的订阅现存
ALTER SUBSCRIPTIONALTERSUBSCRIPTION 192 次
修改订阅的定义现存
DROP SUBSCRIPTIONDROPSUBSCRIPTION
移除一个订阅现存