支持的版本: 当前 (17) / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10

CREATE SUBSCRIPTION

CREATE SUBSCRIPTION — 定义新的订阅

概要

CREATE SUBSCRIPTION subscription_name
    CONNECTION 'conninfo'
    PUBLICATION publication_name [, ...]
    [ WITH ( subscription_parameter [= value] [, ... ] ) ]

描述

CREATE SUBSCRIPTION 添加一个新的逻辑复制订阅。创建订阅的用户成为订阅的所有者。订阅名称必须与当前数据库中任何现有订阅的名称不同。

订阅表示与发布者的复制连接。因此,除了在本地目录中添加定义外,此命令通常还会在发布者上创建一个复制槽。

除非订阅最初被禁用,否则将在运行此命令的事务提交时启动一个逻辑复制工作进程来复制新订阅的数据。

要能够创建订阅,您必须拥有 pg_create_subscription 角色的权限,以及对当前数据库的 CREATE 权限。

有关订阅和整个逻辑复制的更多信息,请参阅第 29.2 节第 29 章

参数

subscription_name #

新订阅的名称。

CONNECTION 'conninfo' #

libpq 连接字符串,定义如何连接到发布者数据库。有关详细信息,请参阅第 32.1.1 节

PUBLICATION publication_name [, ...] #

要订阅的发布者上的发布名称。

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

此子句指定订阅的可选参数。

以下参数控制订阅创建期间发生的情况

connect (boolean) #

指定 CREATE SUBSCRIPTION 命令是否应连接到发布者。默认值为 true。将此值设置为 false 将强制 create_slotenabledcopy_data 的值为 false。(您不能将 connect 设置为 false 与将 create_slotenabledcopy_data 设置为 true 结合使用。)

由于当此选项为 false 时不会建立连接,因此不会订阅任何表。要启动复制,您必须手动创建复制槽,启用故障转移(如果需要),启用订阅,并刷新订阅。有关示例,请参阅第 29.2.3 节

create_slot (boolean) #

指定该命令是否应在发布者上创建复制槽。默认值为 true

如果设置为 false,您将负责以其他方式创建发布者的槽。有关示例,请参阅第 29.2.3 节

enabled (boolean) #

指定订阅是否应主动复制,或者是否应仅设置而不启动。默认值为 true

slot_name (string) #

要使用的发布者的复制槽的名称。默认情况下,使用订阅的名称作为槽名称。

slot_name 设置为 NONE 表示没有与订阅关联的复制槽。此类订阅还必须将 enabledcreate_slot 都设置为 false。当您稍后手动创建复制槽时,可以使用此选项。有关示例,请参阅第 29.2.3 节

当将 slot_name 设置为有效名称且将 create_slot 设置为 false 时,命名槽的 failover 属性值可能与订阅中指定的 failover 参数不同。请始终确保槽属性 failover 与订阅的对应参数匹配,反之亦然。否则,发布者上的槽的行为可能与这些订阅选项所说的不同:例如,即使订阅的 failover 选项被禁用,发布者上的槽也可以同步到备用节点,或者即使订阅的 failover 选项已启用,也可以禁用同步。

以下参数控制订阅创建后的复制行为

binary (boolean) #

指定订阅是否将请求发布者以二进制格式(而不是文本格式)发送数据。默认值为 false。任何初始表同步复制(请参阅 copy_data)也使用相同的格式。二进制格式可能比文本格式快,但在机器架构和 PostgreSQL 版本之间的可移植性较差。二进制格式非常特定于数据类型;例如,它不允许从 smallint 列复制到 integer 列,即使这在文本格式下可以正常工作。即使启用了此选项,也只有具有二进制发送和接收函数的数据类型才以二进制格式传输。请注意,初始同步要求所有数据类型都具有二进制发送和接收函数,否则同步将失败(有关发送/接收函数的更多信息,请参阅CREATE TYPE)。

进行跨版本复制时,发布者可能具有某些数据类型的二进制发送函数,但订阅者缺少该类型的二进制接收函数。在这种情况下,数据传输将失败,并且无法使用 binary 选项。

如果发布者是 16 之前的 PostgreSQL 版本,那么即使 binary = true,任何初始表同步也将使用文本格式。

copy_data (boolean) #

指定在复制开始时是否复制正在订阅的发布中预先存在的数据。默认值为 true

如果发布包含 WHERE 子句,它将影响复制哪些数据。有关详细信息,请参阅注释

有关 copy_data = true 如何与 origin 参数交互的详细信息,请参阅注释

streaming (enum) #

指定是否为此订阅启用正在进行的事务的流式传输。默认值为 off,表示所有事务都在发布者上完全解码,然后作为一个整体发送给订阅者。

如果设置为 on,则传入的更改将写入临时文件,然后在事务在发布者上提交并由订阅者接收后才应用。

如果设置为 parallel,则传入的更改将通过可用的并行应用工作进程之一直接应用。如果没有可用的并行应用工作进程来处理流式事务,则将更改写入临时文件,并在事务提交后应用。请注意,如果并行应用工作进程中发生错误,则可能不会在服务器日志中报告远程事务的完成 LSN。

synchronous_commit (enum) #

此参数的值将覆盖此订阅的应用工作进程中的 synchronous_commit 设置。默认值为 off

off 用于逻辑复制是安全的:如果订阅者由于缺少同步而丢失事务,则数据将从发布者再次发送。

在进行同步逻辑复制时,不同的设置可能更合适。逻辑复制工作进程会将写入和刷新的位置报告给发布者,并且在使用同步复制时,发布者将等待实际刷新。这意味着,当将订阅用于同步复制时,将订阅者的 synchronous_commit 设置为 off 可能会增加发布者上 COMMIT 的延迟。在这种情况下,将 synchronous_commit 设置为 local 或更高可能会更有利。

two_phase (boolean) #

指定是否为此订阅启用两阶段提交。默认值为 false

启用两阶段提交后,准备好的事务会在 PREPARE TRANSACTION 时发送到订阅者,并在订阅者上作为两阶段事务进行处理。否则,准备好的事务仅在提交时发送到订阅者,然后由订阅者立即处理。

两阶段提交的实现要求复制已成功完成初始表同步阶段。因此,即使为订阅启用了 two_phase,内部两阶段状态仍会暂时保持 pending,直到初始化阶段完成。请查看 pg_subscriptionsubtwophasestate 列,以了解实际的两阶段状态。

disable_on_error (boolean) #

指定如果在从发布者复制数据期间,订阅工作进程检测到任何错误,是否应自动禁用订阅。默认值为 false

password_required (boolean) #

如果设置为 true,则由于此订阅而建立的与发布者的连接必须使用密码身份验证,并且密码必须作为连接字符串的一部分指定。当订阅的所有者是超级用户时,将忽略此设置。默认值为 true。只有超级用户才能将此值设置为 false

run_as_owner (boolean) #

如果为 true,则所有复制操作都以订阅所有者的身份执行。如果为 false,则复制工作进程将以每个表的所有者的身份对表执行操作。后一种配置通常更安全;有关详细信息,请参阅 第 29.10 节。默认值为 false

origin (string) #

指定订阅是否将请求发布者仅发送没有来源的更改,或者发送无论来源如何的更改。将 origin 设置为 none 表示订阅将请求发布者仅发送没有来源的更改。将 origin 设置为 any 表示发布者发送无论其来源如何的更改。默认值为 any

有关 copy_data = true 如何与 origin 参数交互的详细信息,请参阅注释

failover (boolean) #

指定是否启用与订阅关联的复制槽以同步到备用机,以便在故障转移后可以从新的主服务器恢复逻辑复制。默认值为 false

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

注意

有关如何在订阅和发布实例之间配置访问控制的详细信息,请参阅 第 29.10 节

当创建复制槽(默认行为)时,不能在事务块内执行 CREATE SUBSCRIPTION

创建连接到同一数据库集群的订阅(例如,在同一集群中的数据库之间进行复制或在同一数据库中进行复制)只有在复制槽不是作为同一命令的一部分创建时才会成功。否则,CREATE SUBSCRIPTION 调用将挂起。为了使其工作,请单独创建复制槽(使用插件名称为 pgoutputpg_create_logical_replication_slot 函数),并使用参数 create_slot = false 创建订阅。有关示例,请参阅 第 29.2.3 节。这是一个实现限制,可能会在将来的版本中解除。

如果发布中的任何表具有 WHERE 子句,则 expression 计算结果为 false 或 null 的行将不会发布。如果订阅中有多个发布,其中同一个表已使用不同的 WHERE 子句发布,则如果满足任何表达式(指该发布操作),则将发布该行。在不同的 WHERE 子句的情况下,如果其中一个发布没有 WHERE 子句(指该发布操作),或者该发布声明为 FOR ALL TABLESFOR TABLES IN SCHEMA,则无论其他表达式的定义如何,始终都会发布行。如果订阅者是 15 之前的 PostgreSQL 版本,则在初始数据同步阶段将忽略任何行筛选。在这种情况下,用户可能需要考虑删除任何与后续筛选不兼容的初始复制数据。因为初始数据同步在复制现有表数据时不会考虑发布的 publish 参数,所以可能会复制一些不会使用 DML 复制的行。有关示例,请参阅 第 29.2.2 节

不支持在多个发布中,同一个表已使用不同列列表发布的订阅。

我们允许指定不存在的发布,以便用户以后可以添加这些发布。这意味着 pg_subscription 可以具有不存在的发布。

当使用 copy_data = trueorigin = NONE 的订阅参数组合时,初始同步表数据直接从发布者复制,这意味着不可能知道该数据的真实来源。如果发布者也有订阅,则复制的表数据可能源自更上游的位置。此场景会被检测到,并向用户记录一个 WARNING,但该警告仅表示可能存在问题;用户有责任进行必要的检查,以确保复制的数据来源确实如预期。

要查找哪些表可能包含非本地来源(由于在发布者上创建的其他订阅),请尝试以下 SQL 查询

# substitute <pub-names> below with your publication name(s) to be queried
SELECT DISTINCT PT.schemaname, PT.tablename
FROM pg_publication_tables PT,
     pg_subscription_rel PS
     JOIN pg_class C ON (C.oid = PS.srrelid)
     JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE N.nspname = PT.schemaname AND
      C.relname = PT.tablename AND
      PT.pubname IN (<pub-names>);

示例

创建一个到远程服务器的订阅,该订阅复制 mypublicationinsert_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 扩展。

提交更正

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