双向复制设计:按顺序或同时将源数据库上不匹配的行编写脚本并执行到多个订阅者数据库的最佳方式?
Bidirectional Replication Design: best way to script and execute unmatched row on Source DB to multiple subscriber DBs, sequentially or concurrently?
感谢您提供的帮助或建议。
我正在尝试在 Windows 中的 Postgresql 10 上构建自己的多主复制,以应对无法使用任何当前第 3 方工具进行 PG 多主复制的情况,这也可能涉及另一个数据库订户组 (Sybase ADS) 中的平台。我有以下逻辑来创建双向复制,部分灵感来自 Bucardo 的逻辑,在 1 个发布者和 2 个订阅者之间:
当在 Source table 上进行 INSERT、UPDATE 或 DELETE 时,Source table 触发器将行添加到在 Source DB 上创建的元 table作为要在订阅它的 2 个订阅者数据库上执行的复制事务。
一个 NOTIFY 信号将被发送到服务,或者用 Python 编写的脚本或一些脚本语言将监视元 table 中的变化或触发执行并被能够对每个订阅者数据库进行 table 比较或将语句编写为 运行。
***我认为需要暂停订阅者的触发器以防止他们将收到的语句推送给订阅者,即如果节点 A 和节点 B 都订阅了彼此的 table A ,那么对节点 A 的 table A 的更新应该复制到节点 B 的 table A,而不是在双向 "ping-pong storm" 中复制回 table A。
- 将在 table 之间进行最终比较,交易将被关闭。如果从第 2 步附录推送交易时 paused/disabled,则重新启用订阅者的触发器。
这将有希望能够双向完成,按时间戳顺序,按 FIFO 顺序,除非我能想出一个方法来创建子进程以 运行 并发同步。
为此,我正在尝试找出设置服务逻辑的最佳方法——本质上是上面的第 2 步,这显然是在 Linux 中使用守护进程完成的,但我必须工作在 Windows 中,使它 运行 成为或类似于 service/agent---or 提出了一个相当简单和有效的设计来将源 DB 语句发送到订阅者 DB。
有没有人看出这个计划有问题或可能行不通?
免责声明:我对 Postgresql 一无所知,但已经完成了大量自定义复制。
双向复制的主要问题是合并问题。
如果在具有不同属性的两个系统中使用相同的密钥,那么哪个系统可以推送他们的更改?如果你提名一个大师,那就更容易了。然后奴隶每次都会被覆盖。
你能处理多少延迟?将 'notify' 部分取出并只需要一个五分钟的 windows 任务调度程序作业来检查日志 tables 并推送数据要容易得多。
也就是说,这种模式:
变化发生在table。 table 上的数据库触发器记录更改并将 table 的 PK 写入更改日志 table。日志 table 中的一个 ReplicationBatch
列默认设置为 NULL
A windows 计划任务检查所有更改日志 table 以查找自上次 运行 和 'reserves' 这些记录以来发生的所有更改通过将它们的复制状态设置为复制批号
即你运行一个UPDATE LogTable Set ReplicationBatch=BatchNumber WHERE ReplicationState IS NULL
- 复制所有已标记的记录
你运行一个SELECT * FROM LogTable WHERE ReplicationState=RepID
获取要处理的记录
- 完成后,保留的记录被标记为完成,因此下一次仅复制后续更改。此完成标志可能在日志 table 中,也可能在 ReplicaionBatch 编号 table
中
要点是您需要为复制保留记录,以便在复制它们时,可以从源添加额外的日志记录而不会弄乱批处理
然后定期清除日志 tables。
感谢您提供的帮助或建议。
我正在尝试在 Windows 中的 Postgresql 10 上构建自己的多主复制,以应对无法使用任何当前第 3 方工具进行 PG 多主复制的情况,这也可能涉及另一个数据库订户组 (Sybase ADS) 中的平台。我有以下逻辑来创建双向复制,部分灵感来自 Bucardo 的逻辑,在 1 个发布者和 2 个订阅者之间:
当在 Source table 上进行 INSERT、UPDATE 或 DELETE 时,Source table 触发器将行添加到在 Source DB 上创建的元 table作为要在订阅它的 2 个订阅者数据库上执行的复制事务。
一个 NOTIFY 信号将被发送到服务,或者用 Python 编写的脚本或一些脚本语言将监视元 table 中的变化或触发执行并被能够对每个订阅者数据库进行 table 比较或将语句编写为 运行。
***我认为需要暂停订阅者的触发器以防止他们将收到的语句推送给订阅者,即如果节点 A 和节点 B 都订阅了彼此的 table A ,那么对节点 A 的 table A 的更新应该复制到节点 B 的 table A,而不是在双向 "ping-pong storm" 中复制回 table A。
- 将在 table 之间进行最终比较,交易将被关闭。如果从第 2 步附录推送交易时 paused/disabled,则重新启用订阅者的触发器。
这将有希望能够双向完成,按时间戳顺序,按 FIFO 顺序,除非我能想出一个方法来创建子进程以 运行 并发同步。
为此,我正在尝试找出设置服务逻辑的最佳方法——本质上是上面的第 2 步,这显然是在 Linux 中使用守护进程完成的,但我必须工作在 Windows 中,使它 运行 成为或类似于 service/agent---or 提出了一个相当简单和有效的设计来将源 DB 语句发送到订阅者 DB。
有没有人看出这个计划有问题或可能行不通?
免责声明:我对 Postgresql 一无所知,但已经完成了大量自定义复制。
双向复制的主要问题是合并问题。
如果在具有不同属性的两个系统中使用相同的密钥,那么哪个系统可以推送他们的更改?如果你提名一个大师,那就更容易了。然后奴隶每次都会被覆盖。
你能处理多少延迟?将 'notify' 部分取出并只需要一个五分钟的 windows 任务调度程序作业来检查日志 tables 并推送数据要容易得多。
也就是说,这种模式:
变化发生在table。 table 上的数据库触发器记录更改并将 table 的 PK 写入更改日志 table。日志 table 中的一个
ReplicationBatch
列默认设置为 NULLA windows 计划任务检查所有更改日志 table 以查找自上次 运行 和 'reserves' 这些记录以来发生的所有更改通过将它们的复制状态设置为复制批号
即你运行一个UPDATE LogTable Set ReplicationBatch=BatchNumber WHERE ReplicationState IS NULL
- 复制所有已标记的记录
你运行一个SELECT * FROM LogTable WHERE ReplicationState=RepID
获取要处理的记录
- 完成后,保留的记录被标记为完成,因此下一次仅复制后续更改。此完成标志可能在日志 table 中,也可能在 ReplicaionBatch 编号 table 中
要点是您需要为复制保留记录,以便在复制它们时,可以从源添加额外的日志记录而不会弄乱批处理
然后定期清除日志 tables。