PostgreSQL中的逻辑复制

编程/技术 2019-03-17 @ 20:52:11 浏览数: 312 净访问: 242 By: skyrover

本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议


逻辑复制是一种复制数据对象和它们变化的方法,基于它们的复制ID(通常是主键)。我们用术语逻辑来和物理复制来做对比,物理复制会使用特定的块地址和byte-by-byte的复制。PostgreSQL同时支持两种方法。逻辑复制允许在数据复制和安全上有更细粒度的控制。

逻辑复制使用发布订阅模型来描述,一个或者多个订阅者在一个发布节点上订阅一个或者多个发布。订阅者从它们订阅的发布拉取数据,并且可能重新发布数据来允许级联复制或者更复杂的配置。

对于一个表的逻辑复制通常开始于在发布者数据库上做一个数据快照,并将数据复制到订阅者。一旦完成之后,发布者中的数据变动将会实时发送到订阅者上。订阅者以和发布者相同的顺序来应用数据,以确保在单次订阅中事务一致性可以得到保证。数据复制方法有时也被成为事务复制。

逻辑复制的典型应用是:

  • 发送单数据库或者数据库子集的增量变化到订阅者
  • 当单个变化到达订阅者时候触发触发器
  • 联合多个数据库为一个
  • 在不同版本的PostgreSQL中复制数据
  • 在不同平台中的PostgreSQL中复制数据
  • 对不同组的用户提供复制数据的权限
  • 在多个数据库中共享一个数据库的子集

订阅者数据库和其他任何PostgreSQL实例行为一样,并且在定义自己的发布功能时候可以成为一个发布者。当订阅者被应用作为只读时,那么在一次单次订阅将不会产生冲突。另一方面,如果有应用或者其他订阅者有在同一个表中有写入操作,冲突就会产生。

快速配置

首先在postgresql.conf中配置: wal_level = logical

其他需要的配置已经有足够支持基本配置的默认配置

pg_hba.conf需要被调整为支持复制(值依赖于你自己真实的网络配置和你想用来链接的用户)

host     all     repuser     0.0.0.0/0     md5

然后在发布者数据库中:

CREATE PUBLICATION mypub FOR TABLE users, departments;

然后在订阅者数据库

CREATE SUBSCRIPTION mysub CONNECTION 'dbname=foo host=bar user=repuser' PUBLICATION mypub;

上面的步骤之后就会开始复制进程,会将users表和departments表的原始表数据同步到订阅者,然后在这些表有增量数据的时候开始复制。

配置

逻辑复制需要一些配置项被设置。

在发布者这边,wal_level必须被设置为logicalmax_replication_slots必须被设置至少为链接的订阅者数量,加上一些为表同步的预留数量。max_wal_senders应该被至少和max_replication_slots加上在同一时间链接的物理复制数量。

订阅者也需要设置max_replication_slots

监控

逻辑复制基于和物理流式复制类似的架构,在一个发布节点上的监控和物理复制主节点上的监控类似。

订阅的监控信息可以在pg_stat_subscription中查看。该视图对每个订阅者都有一行记录。一次订阅可以有0个或者多个活动的订阅者。

发布

发布可以定义在任何物理复制主节点上。定义了发布的节点被称为发布者。一个发布是产生于一个表或者一系列表的变化,也被成为变化集或者复制集。每个发布只在一个数据库存在。

发布和schema不同,并且不会影响表是如何访问的。每个表可以被添加到多个发布上。发布可能只包含表。必须显式的添加对象,除非在ALL TABLES上创建了发布。

发布可以选择在INSERT, UPDATE, DELETE的任何组合上,类似于通过特定的事件类型来触发触发器。默认所有操作类型都被复制。

一个发布表必须含有一个replica identity,这样在UPDATEDELETE操作上才可以被复制,这样在订阅者一侧才可以进行合适的更新和删除。默认是主键。唯一索引也可以被设置为replica identity。如果表没有任何合适的键,那么它可以被设置为full,表示一行的所有列组成replica identity。但是这样很低效,只应该被作为plan b,如果没有其他的办法。

发布可以用CREATE PUBLICATION来创建,同样可以被改变或者删除。

例子:使用唯一索引作为replica identity:

alter table word_mapping REPLICA IDENTITY using index idx_word_mapping;

详细参考: Chapter 31. Logical Replication


点赞走一波😏


评论

提交评论