Postgresql 中文操作指南
Synopsis
CREATE SUBSCRIPTION subscription_name
CONNECTION 'conninfo'
PUBLICATION publication_name [, ...]
[ WITH ( subscription_parameter [= value] [, ... ] ) ]
Description
CREATE SUBSCRIPTION 添加新的逻辑复制订阅。创建订阅的用户将成为订阅的所有者。订阅名称必须不同于当前数据库中任何现有订阅的名称。
订阅表示与发布者的复制连接。因此,除了在本地目录中添加定义外,此命令通常还会在发布者上创建一个复制槽。
逻辑复制工作程序将在运行此命令的事务提交时开始复制新订阅的数据,除非订阅最初已禁用。
要能够创建订阅,您必须拥有 pg_create_subscription 角色的权限,以及对当前数据库的 CREATE 权限。
有关订阅和逻辑复制整体的更多信息,请访问 Section 31.2 和 Chapter 31 。
Parameters
-
subscription_name #
-
新订阅的名称。
-
-
CONNECTION '_conninfo'_ #
-
libpq 连接字符串,用来定义如何连接到发布者数据库。详情请参阅 Section 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 结合起来。)
-
由于在启用此选项时不会进行任何连接,因此不会订阅任何表。若要启动复制,您必须手动创建复制槽、启用订阅并刷新订阅。有关示例,请参阅 Section 31.2.3 。
-
-
create_slot (boolean) #
-
指定命令是否应该在发布者上创建复制槽。默认值为 true 。
-
如果设置为 false ,您负责以其他方式创建发布者的槽。有关示例,请参阅 Section 31.2.3 。
-
-
enabled (boolean) #
-
指定订阅是否应主动复制或仅应设置而不启动。默认值为 true 。
-
-
slot_name (string) #
-
要使用的发布者复制槽的名称。默认情况下,对发布者的槽使用订阅的名称。
-
将 slot_name 设置 NONE 意味着不会将复制槽与订阅相关联。此类订阅还必须将 enabled 和 create_slot 均设置为 false 。稍后手动创建复制槽时使用此项。有关示例,请参阅 Section 31.2.3 。
-
-
binary (boolean) #
-
指定订阅是否将请求发布者以二进制格式(而不是文本)发送数据。默认值为 false 。任何初始表同步副本(请参见 copy_data )也使用相同的格式。二进制格式可能比文本格式更快,但跨机器架构和 PostgreSQL 版本的可移植性更差。二进制格式具有很高的数据类型特异性;例如,它不允许从 smallint 列复制到 integer 列,即使在文本格式中这样可以正常进行。即使启用了此选项,也只有具有二进制发送和接收函数的数据类型才会以二进制方式传输。请注意,初始同步要求所有数据类型都具有二进制发送和接收函数,否则同步将失败(有关发送/接收函数的更多信息,请参阅 CREATE TYPE )。
-
在进行跨版本复制时,发布者可能对某些数据类型具有二进制发送函数,但订阅者没有针对该类型二进制接收函数。在这种情况下,数据传输将失败,且 binary 选项无法使用。
-
如果发布者的 PostgreSQL 版本低于 16,则任何初始表同步都会使用文本格式,即使 binary = true 。
-
-
copy_data (boolean) #
-
streaming (enum) #
-
指定是否为此订阅启用正在进行的事务的流传输。默认值是 off ,表示所有事务都在发布者上完全解码,然后才作为整体发送给订阅者。
-
如果设置为 on ,传入的更改将写入临时文件,然后仅在事务在发布者上提交并由订阅者接收后才应用。
-
如果设置为 parallel ,将直接通过空闲的并行应用工作进程之一应用传入的更改(如果可用)。如果没有空闲的并行应用工作进程来处理流式传输事务,则更改将写入临时文件并在事务提交后应用。请注意,如果在并行应用工作进程中发生错误,则远程事务的完成 LSN 可能不会在服务器日志中报告。
-
-
synchronous_commit (enum) #
-
此参数的值会覆盖该订阅的应用工作进程中的 synchronous_commit 设置。默认值是 off 。
-
将其用于逻辑复制是安全的:如果订阅者因丢失同步而丢失事务,则发布者将再次发送数据。
-
执行同步逻辑复制时,可能需要不同的设置。逻辑复制工作进程会将写入和刷新位置报告给发布者,并且在使用同步复制时,发布者将等待实际刷新。这意味着当订阅用于同步复制时,为订阅者将 synchronous_commit 设置为 off 可能会增加发布者上的 COMMIT 的延迟。在这种情况下,将 synchronous_commit 设置为 local 或更高可能是有利的。
-
-
two_phase (boolean) #
-
指定是否为此订阅启用两阶段提交。默认值为 false 。
-
启用两阶段提交后,准备好的事务会在 PREPARE TRANSACTION 时发送给订阅者,并在订阅者上作为两阶段事务进行处理。否则,准备好的事务仅在提交时发送给订阅者,然后由订阅者立即处理。
-
两阶段提交的实现要求复制已成功完成初始表同步阶段。因此,即使为订阅启用了 two_phase ,内部两阶段状态在初始化阶段完成之前也会暂时保持“挂起”。请参阅 pg_subscription 的 subtwophasestate 列来了解实际的两阶段状态。
-
-
disable_on_error (boolean) #
-
指定如果订阅工作进程在从发布者复制数据过程中检测到任何错误,是否应该自动禁用订阅。默认值为 false 。
-
-
password_required (boolean) #
-
如果设置为 true ,则由于此订阅而与发布者建立的连接必须使用密码验证,并且密码必须指定为连接字符串的一部分。订阅归超级用户所有时,此设置将被忽略。默认值为 true 。只有超级用户才能将此值设置为 false 。
-
-
run_as_owner (boolean) #
-
如果为 true,则所有复制操作都将作为订阅者所有者执行。如果为 false,则复制工作进程将以该表所有者的身份对每张表执行操作。后一种配置通常更加安全;有关详细信息,请参阅 Section 31.9 。默认值为 false 。
-
-
origin (string) #
-
指定订阅是否将请求发布者仅发送没有原点或无论原点如何都发送更改。将 origin 设置为 none 意味着订阅将请求发布者仅发送没有原点的更改。将 origin 设置为 any 意味着发布者无论其原点如何都发送更改。默认值为 any 。
-
请参阅 Notes 以详细了解 copy_data = true 如何与 origin 参数交互。
-
在指定类型为 boolean 的参数时,可以省略 = value 部分,这等同于指定 TRUE 。
Notes
有关如何配置订阅和发布实例之间的访问控制的详细信息,请参阅 Section 31.9 。
创建复制槽(默认行为)时,无法在事务块中执行 CREATE SUBSCRIPTION 。
仅当复制槽没有创建为同一命令的一部分时,创建连接到同一数据库集群的订阅(例如,在同一集群中的数据库之间复制或在同一数据库中复制)才会成功。否则, CREATE SUBSCRIPTION 调用将挂起。要使其正常工作,请分别创建复制槽(使用带有插件名称 pgoutput 的函数 pg_create_logical_replication_slot )并使用参数 create_slot = false 创建订阅。具体示例,请参阅 Section 31.2.3 。这是一项实现限制,可能会在未来的版本中取消。
如果发布中的任何表都有 WHERE 子句,则 expression 求值为 false 或 null 的行将不会发布。如果订阅有多个发布,并且在其中同一张表已使用不同的 WHERE 子句发布,则只要任何表达式(引用该发布操作)满足,该行都将发布。在使用不同的 WHERE 子句的情况下,如果某个发布没有 WHERE 子句(引用该发布操作)或发布被声明为 FOR ALL TABLES 或 FOR TABLES IN SCHEMA ,则无论其他表达式的定义如何,总是发布行。如果订阅者是版本低于 15 的 PostgreSQL,则在初始数据同步阶段将忽略任何行筛选。对于这种情况,用户可能希望考虑删除任何与后续筛选不兼容的最初复制的数据。由于初始数据同步在复制现有表数据时不考虑发布 publish 参数,因此可能会复制一些不会使用 DML 复制的行。有关示例,请参阅 Section 31.2.2 。
不支持在同一表已使用不同的列列表发布的多个发布中订阅。
我们允许指定不存在的发布,以便用户稍后添加这些发布。这意味着 pg_subscription 可能有不存在的发布。
当使用 copy_data = true 和 origin = 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>);
Examples
创建一个对远程服务器的订阅,该服务器复制 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);