SQL COMMAND · 逻辑复制
CREATE PUBLICATION
定义一个新的发布
CREATE逻辑复制引入 10(基线)现存至 20 devel2 次语法变更
- 动词
CREATE- 对象
PUBLICATION- 分组
- 逻辑复制
- 引入版本
- 10(基线)
- 状态
- 现存
- 语法变更次数
- 2
- 手册小节数
- 6
版本轨迹
相对 PostgreSQL 17 语法未变,正文有更新。
语法铁道图 PostgreSQL 18
沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。
publication_object
table_and_columns
语法概要
CREATE PUBLICATIONname[ FOR ALL TABLES | FORpublication_object[, ... ] ] [ WITH (publication_parameter[=value] [, ... ] ) ] 其中publication_object可以是: TABLEtable_and_columns[, ... ] TABLES IN SCHEMA {schema_name| CURRENT_SCHEMA } [, ... ] 其中table_and_columns为: [ ONLY ]table_name[ * ] [ (column_name[, ... ] ) ] [ WHERE (expression) ]
描述
CREATE PUBLICATION向当前数据库中添加一个新发布。 该发布的名称必须不同于当前数据库中任何现有发布的名称。
发布本质上是一组表,其数据更改会通过逻辑复制进行复制。 有关发布在逻辑复制配置中如何工作的详细信息, 请参见Section 29.1。
参数
name新发布的名称。
FOR TABLE指定要加入该发布的表列表。如果在表名前指定了
ONLY, 则只有该表会被加入发布。如果未指定ONLY, 则该表及其所有后代表(如果有)都会被加入。也可以在表名后指定*,以显式表明包含后代表。不过,这不适用于分区表。 分区表的各个分区始终会被隐式视为发布的一部分,因此永远不会被显式加入发布。如果指定了可选的
WHERE子句,它会定义一个 行过滤器表达式。对于expression求值为false或NULL的行,不会被发布。 注意,表达式外必须加括号。它对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 操作。其值是一个以逗号分隔的操作列表。 允许的操作有
insert、update、delete和truncate。默认会发布所有操作, 因此该选项的默认值为'insert, update, delete, truncate'。该参数只影响 DML 操作。特别是,逻辑复制的初始数据同步 (参见Section 29.9.1)在复制现有表数据时 不会考虑该参数。
publish_generated_columns(enum)指定是否复制与该发布关联的表中存在的生成列。可选值为
none和stored。默认值为
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 TABLE、FOR ALL TABLES或 FOR TABLES IN SCHEMA,则该发布开始时不包含任何表。 这在稍后还要添加表或模式时很有用。
创建发布不会启动复制。它只为未来的订阅者定义分组和过滤逻辑。
要创建发布,调用用户必须具有当前数据库的CREATE权限。 (当然,超级用户会绕过这一检查。)
要向发布中添加表,调用用户必须拥有该表。使用FOR ALL TABLES 和FOR TABLES IN SCHEMA子句要求调用用户是超级用户。
如果某个发布发布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(默认值), 则取自分区本身。有关行过滤器的详细信息,请参见 Section 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是PostgreSQL 的扩展。
又见
语法演化
相邻大版本之间的差异,新的在前。版本号链接到对应快照。
PostgreSQL 20← 19正文更新
正文更新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 ) ]正文更新PostgreSQL 18← 17正文更新
正文更新PostgreSQL 17← 16正文更新
正文更新PostgreSQL 16← 15正文更新
正文更新PostgreSQL 15← 14正文更新
正文更新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 ]正文更新PostgreSQL 13← 12正文更新
正文更新PostgreSQL 12← 11正文更新
正文更新PostgreSQL 11← 10正文更新
正文更新
同组命令
| 命令 | 动词 | 对象 | 版本变动 | 最近变更 |
|---|---|---|---|---|
CREATE PUBLICATION | CREATE | PUBLICATION | 192 次 | |
| 定义一个新的发布 | 现存 | |||
ALTER PUBLICATION | ALTER | PUBLICATION | 192 次 | |
| 修改发布的定义 | 现存 | |||
DROP PUBLICATION | DROP | PUBLICATION | — | |
| 移除一个发布 | 现存 | |||
CREATE SUBSCRIPTION | CREATE | SUBSCRIPTION | 191 次 | |
| 定义一个新的订阅 | 现存 | |||
ALTER SUBSCRIPTION | ALTER | SUBSCRIPTION | 192 次 | |
| 修改订阅的定义 | 现存 | |||
DROP SUBSCRIPTION | DROP | SUBSCRIPTION | — | |
| 移除一个订阅 | 现存 | |||