订阅是逻辑复制的下游端。定义订阅的节点称为订阅者。订阅定义了与另一个数据库的连接以及它想订阅的一组发布(一个或多个)。
订阅端数据库的行为与任何其他 PostgreSQL 实例相同,并且可以通过定义自己的发布,作为其他数据库的发布者。
如果需要,一个订阅者节点可以有多个订阅。可以在单个发布者-订阅者对之间定义多个订阅,但此时必须确保被订阅的发布对象不重叠。
每个订阅将通过一个复制槽(见Section 26.2.6)接收变更。对于已有表数据的初始数据同步,可能需要额外的复制槽;这些复制槽将在数据同步结束后被删除。
逻辑复制订阅可以作为同步复制中的备库(见Section 26.2.8)。备库名称默认为订阅名称。可以在订阅的连接信息中通过application_name指定一个替代名称。
如果当前用户是超级用户,pg_dump会转储订阅。否则会写一条警告并跳过订阅,因为非超级用户无法从pg_subscription目录读取所有订阅信息。
订阅使用CREATE SUBSCRIPTION添加,可随时使用ALTER SUBSCRIPTION命令停止/恢复,并使用DROP SUBSCRIPTION移除。
当订阅被删除并重建时,同步信息会丢失。这意味着之后必须重新同步数据。
模式定义不会被复制,已发布的表必须存在于订阅端。只有常规表可以作为复制的目标。例如,不能复制到视图。
发布端和订阅端的表通过完全限定的表名进行匹配。不支持复制到订阅端名称不同的表。
表的列也按名称匹配。订阅端表中列的顺序无需与发布端匹配。列的数据类型也无需匹配,只要数据的文本表示可以转换为目标类型即可。例如,可以从integer类型的列复制到bigint类型的列。目标表也可以有已发布表未提供的额外列。这些额外列将用目标表定义中指定的默认值填充。
如前所述,每个(活动的)订阅都从远程(发布端)的一个复制槽接收变更。
额外的表同步槽通常是瞬态的,由系统内部创建以执行初始表同步,并在不再需要时自动删除。这些表同步槽的名称是自动生成的:“pg_%u_sync_%u_%llu”(参数分别为:订阅oid、表relid、系统标识sysid)。
通常,使用CREATE SUBSCRIPTION创建订阅时会自动创建远程复制槽,使用DROP SUBSCRIPTION删除订阅时会自动删除复制槽。但在某些情况下,分别操控订阅和底层复制槽会很有用,甚至是必要的。以下是一些场景:
创建订阅时复制槽已经存在。此时可使用create_slot = false选项创建订阅,以关联到现有的槽。
创建订阅时远程主机不可达或状态不明确。此时可使用connect = false选项创建订阅。这样就完全不会联系远程主机。pg_dump就是这样使用的。在订阅激活前,必须手动创建远程复制槽。
删除订阅时需要保留复制槽。这在将订阅端数据库迁移到另一台主机并从那里激活时很有用。此时应在尝试删除订阅之前,使用ALTER SUBSCRIPTION解除槽与订阅的关联。
删除订阅时远程主机不可达。此时应在尝试删除订阅之前,使用ALTER SUBSCRIPTION解除槽与订阅的关联。如果远程数据库实例已经不存在了,则无需其他操作。但如果远程数据库实例只是暂时不可达,则应手动删除复制槽(以及任何仍存在的表同步槽),否则它/它们将继续保留WAL,并可能最终导致磁盘空间耗尽。此类情况应仔细调查。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。