CREATE SUBSCRIPTION
CREATE SUBSCRIPTION — 定义一个新的订阅
大纲
CREATE SUBSCRIPTIONsubscription_nameCONNECTION 'conninfo' PUBLICATIONpublication_name[, ...] [ WITH (subscription_parameter[=value] [, ... ] ) ]
描述
CREATE SUBSCRIPTION 添加一个新的逻辑复制订阅。订阅名称必须与当前数据库中任何现有订阅的名称不同。
订阅表示与发布者的复制连接。因此,除了在本地系统目录中添加定义之外,该命令通常还会在发布者上创建一个复制槽。
除非订阅初始即被禁用,否则在执行该命令所在事务提交时,会启动一个逻辑复制工作进程为新订阅复制数据。
参数
subscription_name#新订阅的名称。
CONNECTION '#conninfo'定义如何连接到发布者数据库的 libpq 连接字符串。详情请参见第 34.1.1 节。
PUBLICATION#publication_name[, ...]要订阅的发布者上的发布名称。
WITH (#subscription_parameter[=value] [, ... ] )该子句为订阅指定可选参数。
下列参数控制订阅创建期间的行为:
connect(boolean) #指定
CREATE SUBSCRIPTION命令是否连接到发布者。默认值为true。将其设为false会强制把create_slot、enabled和copy_data的值设为false。(不能将connect设为false的同时,再把create_slot、enabled或copy_data设为true。)由于该选项为
false时不会建立连接,因此不会订阅任何表,所以即使之后启用了订阅,也不会复制任何内容。随后需要执行ALTER SUBSCRIPTION ... REFRESH PUBLICATION,才能订阅这些表。create_slot(boolean) #指定该命令是否应在发布者上创建复制槽。默认值为
true。如果设为false,则必须以其他方式自行创建发布者上的复制槽。enabled(boolean) #指定订阅是应当主动进行复制,还是仅完成设置但暂不启动。默认值为
true。slot_name(string) #要使用的发布者上的复制槽名称。默认使用订阅名称作为槽名。
将
slot_name设为NONE表示该订阅不关联任何复制槽。当打算稍后手工创建复制槽时,可使用此设置。这类订阅还必须同时将enabled和create_slot设为false。
下列参数控制订阅创建后的复制行为:
binary(boolean) #指定订阅是否请求发布者以二进制格式(而不是文本格式)发送数据。默认值为
false。即使启用了此选项,也只有具有二进制发送和接收函数的数据类型才会以二进制方式传输。在进行跨版本复制时,可能会出现这样的情况:发布者对某种数据类型有二进制发送函数,但订阅者缺少该类型的二进制接收函数。在这种情况下,数据传输会失败,因此不能使用
binary选项。copy_data(boolean) #指定复制开始时是否复制所订阅发布中的预先存在的数据。默认值为
true。如果这些发布包含
WHERE子句,将会影响被复制的数据。详情请参见注意。streaming(boolean) #指定是否为该订阅启用进行中事务的流式传输。默认情况下,所有事务都会先在发布者上被完全解码,然后才整体发送给订阅者。
synchronous_commit(enum) #该参数的值会覆盖此订阅应用工作进程中的 synchronous_commit 设置。默认值为
off。对逻辑复制来说,使用
off是安全的:如果订阅者因缺少同步而丢失了事务,数据会再次从发布者发送过来。在进行同步逻辑复制时,可能更适合使用不同的设置。逻辑复制工作进程会向发布者报告写入和刷盘位置,而在使用同步复制时,发布者会等待真正的刷盘完成。这意味着,当订阅被用于同步复制时,将订阅者的
synchronous_commit设为off可能会增加发布者上COMMIT的延迟。在这种场景下,将synchronous_commit设为local或更高可能更有利。two_phase(boolean) #指定是否为该订阅启用两阶段提交。默认值为
false。启用两阶段提交时,预备事务会在
PREPARE TRANSACTION时发送给订阅者,并且在订阅者上也会作为两阶段事务处理。否则,预备事务只有在提交时才会发送给订阅者,随后由订阅者立即处理。两阶段提交的实现要求复制已经成功完成初始表同步阶段。因此,即使订阅启用了
two_phase,内部的两阶段状态也会暂时保持为“pending”,直到初始化阶段完成。要了解实际的两阶段状态,请参见pg_subscription的subtwophasestate列。disable_on_error(boolean) #指定如果订阅工作进程在从发布者复制数据期间检测到任何错误,是否自动禁用该订阅。默认值为
false。
注解
关于如何在订阅与发布实例之间配置访问控制,详见第 31.9 节。
当创建复制槽时(这是默认行为),CREATE
SUBSCRIPTION 不能在事务块内部执行。
创建一个连接到同一数据库集簇的订阅(例如在同一集簇中的不同数据库之间复制,或者在同一数据库内复制)时,只有在复制槽不作为同一命令的一部分创建的情况下才会成功。否则,CREATE SUBSCRIPTION
调用将挂起。要实现这种用法,应分别创建复制槽(使用函数
pg_create_logical_replication_slot 并指定插件名
pgoutput),然后使用参数
create_slot = false 创建订阅。这是一个实现限制,未来版本中可能会解除。
如果发布中的任何表带有 WHERE 子句,则对
expression 求值为
false 或 NULL 的行不会被发布。如果订阅包含多个发布,且同一张表在这些发布中使用了不同的
WHERE 子句,那么只要任意一个表达式(针对相应的发布操作)满足,该行就会被发布。对于不同的
WHERE 子句,如果其中某个发布没有
WHERE 子句(针对相应的发布操作),或者该发布被声明为
FOR ALL TABLES
或
FOR TABLES IN SCHEMA,则无论其他表达式如何定义,该行都会被发布。如果订阅者使用的是 15 之前版本的 PostgreSQL,那么在初始数据同步阶段会忽略所有行过滤。在这种情况下,用户可能需要考虑删除那些初始复制过来、但与后续过滤不兼容的数据。由于初始数据同步在复制现有表数据时不会考虑发布的
publish
参数,因此有些使用 DML 时本不会复制的行,也可能在此阶段被复制。示例见第 31.2.2 节。
如果订阅包含多个发布,而其中同一张表使用了不同的列列表进行发布,则不受支持。
允许指定不存在的发布,以便用户稍后再创建这些发布。这意味着
pg_subscription
中可能包含不存在的发布。
示例
创建一个指向远端服务器的订阅,复制发布
mypublication 和 insert_only 中的表,并在提交时立即开始复制:
CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
PUBLICATION mypublication, insert_only;
创建一个指向远端服务器的订阅,复制 insert_only 发布中的表,并且要等到稍后启用时才开始复制。
CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
PUBLICATION insert_only
WITH (enabled = false);
兼容性
CREATE SUBSCRIPTION 是
PostgreSQL 扩展。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.