受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

Chapter 29. 逻辑复制

逻辑复制是一种基于数据对象及其复制标识(通常是主键)来复制数据对象及其变更的方法。这里使用“逻辑”一词,是为了与物理复制相区别;物理复制使用精确的块地址,并按字节逐一复制。PostgreSQL 可以同时支持这两种机制,见 Chapter 26。逻辑复制允许对数据复制和安全性进行细粒度控制。

逻辑复制采用发布订阅模型,一个或多个订阅者订阅某个发布者节点上的一个或多个发布。订阅者从其订阅的发布中拉取数据,随后还可以重新发布这些数据,以实现级联复制或更复杂的配置。

表的逻辑复制通常开始于 PostgreSQL 在发布端数据库中为该表数据建立快照,并将其复制到订阅端。完成后,发布端自初始复制以来发生的变更会持续发送给订阅端。订阅端会按与发布端相同的顺序应用这些数据,因此对于单个订阅中的发布,可以保证事务一致性。这种数据复制方法有时也称为事务性复制。

逻辑复制的典型用法是:

  • 当单个数据库或数据库的某个子集发生变更时,将增量变更发送给订阅者。

  • 当单个变更到达订阅端时触发触发器。

  • 将多个数据库汇总到单个数据库中(例如用于分析)。

  • 在PostgreSQL的不同主版本之间进行复制。

  • 在不同平台上(例如Linux到Windows)的PostgreSQL实例之间进行复制。

  • 向不同用户组开放对复制数据的访问。

  • 在多个数据库间共享数据库的一个子集。

订阅端数据库的行为与任何其他 PostgreSQL 实例相同,并且可以通过定义自己的发布,作为其他数据库的发布者。当应用把订阅端视为只读时,单个订阅不会产生冲突。另一方面,如果应用或其他订阅者对同一组表执行了其他写操作,就可能发生冲突。

29.1. 发布 #

发布可以定义在任何物理复制主库上。定义发布的节点称为 发布者。发布是一组由某个表或一组表产生的变更,也可称为 变更集或复制集。每个发布只存在于一个数据库中。

发布与模式不同,不影响表的访问方式。每个表在需要时都可以加入多个发布。 发布目前只能包含表以及模式中的所有表。除非创建发布时使用 ALL TABLES,否则对象必须显式添加。

发布可以选择将要产生的变更限制为 INSERTUPDATEDELETETRUNCATE 的任意组合,类似于触发器按特定事件类型触发。默认会复制所有操作类型。 这些发布规范只适用于 DML 操作;不影响初始数据同步复制。 (行过滤器对 TRUNCATE 无效。见 Section 29.4)。

每个发布都可以有多个订阅者。

使用 CREATE PUBLICATION 命令创建发布,之后可使用对应命令修改或删除。

单个表可以使用 ALTER PUBLICATION 动态添加和移除。ADD TABLEDROP TABLE 都是事务性的,因此事务提交后,表会在正确的快照点开始或停止复制。

29.1.1. 复制标识 #

已发布的表若要复制 UPDATEDELETE 操作,必须配置 复制标识,以便在订阅端识别应更新或删除的行。

默认情况下,如果存在主键,则主键就是复制标识。也可以将另一个唯一索引 (满足某些附加要求)设置为复制标识。如果表没有合适的键,可将复制标识设为 FULL,表示整行作为键。指定复制标识 FULL 时,订阅端在查找行时可以使用索引。 候选索引必须是 btree 或 hash、非部分索引,且最左索引字段必须是引用已发布表 列的列(而非表达式)。这些非唯一索引属性的限制,遵循了主键的一部分限制规则。 如果没有合适索引,订阅端查找会非常低效,因此复制标识 FULL 仅应在没有其他方案时作为后备选项。

如果发布端设置的是非 FULL 的复制标识,则订阅端也必须设置 由相同或更少列组成的复制标识。

对于复制标识定义为 NOTHING、无主键时的 DEFAULT,或使用已删除索引的 USING INDEX 的表,如果将其包含在复制 UPDATEDELETE 的发布中,则不支持这些操作。尝试执行时会在发布端报错。

无论复制标识如何,INSERT 操作都可以继续执行。

关于如何设置复制标识,见 ALTER TABLE...REPLICA IDENTITY

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。