复制源是为了更容易地在逻辑解码 上实现逻辑复制解决方案而设计。它们提供了对两种常见问题的解决方案:
如何安全地跟踪复制进度?
如何基于一行的来源更改复制行为?例如,阻止双向复制 设置中的循环
复制源只有两个属性,名称和 OID。名称应该可以被用来在系统间引用该源,
它是一种自由形式的文本
。为了避免复制源之间的冲突,可以
在复制源的名称前加上复制解决方案的名称。在空间效率很重要的情况下,OID
被用来避免不得不存储长版本。OID 不能在系统间被共享。
可以使用函数
pg_replication_origin_create()
创建复制源,使用函数
pg_replication_origin_drop()
删除复制源,并且在系统目录
pg_replication_origin
中查看复制源。
构建一套复制解决方案的一个重要部分是以一种安全的方式跟踪重放进度。当应用 过程或者整个集簇死掉时,需要能够找出数据被成功地复制到了什么地方。对此的 简单解决方案(例如为每一个被重放的事务更新一个表行)有运行时负荷和数据库 膨胀的问题。
通过使用复制源,一个会话可以被标记为从一个远程节点重放(使用
pg_replication_origin_session_setup()
函数)。此外,
可以使用
pg_replication_origin_xact_setup()
以每一个事务为基础配置每一个源事务的
LSN和提交时间戳。如果完成这样的配置,
复制过程将保持在一种对崩溃安全的方式中。所有复制源的重放进度可以在
pg_replication_origin_status
视图中看到。一个源的进度(例如在继续复制时)可以使用
pg_replication_origin_progress()
(用于任何源)或者
pg_replication_origin_session_progress()
(用于在当前会话中配置的源)获得。
在比从一个系统复制到另一个系统更复杂的复制拓扑中,另一个问题是很难避免再次
复制已经被重放的行。这可能导致复制中的循环和低效。复制源提供了一种可选的机制
来识别和阻止这种问题。在使用前一段提到的函数配置时,每一个被传递
给输出插件回调(见第 48.6 节)的由该会话
生成的改变和事务会被标记上该会话的复制源。这使得可以在输出插件中以不同的方式
对待它们,例如忽略除本地生成的行之外的所有行。此外,
filter_by_origin_cb
回调可以被用来基于来源过滤逻辑
解码改变流。虽然灵活性较低,通过这种回调进行过滤比用输出插件过滤效率更高。