目前我们有以下设置:Postgresql DB“Master”和全局分布式 Postgresql Slaves,使用逻辑复制进行数据复制。主设备是读/写的,从设备是只读的。主服务器通过虚拟化功能具有高可用性。但如果整个数据中心发生故障,我们就会遇到问题。
Data Center 1 Global Slaves
+-----------+ +-----------+
| DB1 | | |
| Master DB |--------------------| Slave 1 |
| |-----\ | |
+-----------+ \ +-----------+
\
\
\
\ +-----------+
\ | |
--------| Slave 50 |
| |
+-----------+
因此,我想在第二个数据中心使用另一个 Postgresql Slave 来扩展设置。当数据中心 1 发生故障时,数据中心 2 中的 Postgresql Slave 将提升为新的 Master(读写),并且全局 Slave 将重新配置为新的 Master。
Data Center 1 Global Slaves
+-----------+ +-----------+
| DB1 | | |
| Master DB | /-------| Slave 1 |
| DOWN | / | |
+-----------+ / +-----------+
| /
| /
V /
+-----------+ / +-----------+
| New |-----/ | |
| Master DB |--------------------| Slave 50 |
| DB2 | | |
+-----------+ +-----------+
Data Center 2
如果我理解正确的话,无论我在数据中心1和数据中心2之间使用流式复制还是逻辑复制,全局从站都需要从新的主站重新同步。它是否正确?如果没有,如何实现数据中心迁移而不需要重新同步所有全局从站?
如果通过 Postgresql 方式无法做到这一点,那么使用 pgedge 或 pglogic 之类的插件会帮助我吗?我认为我可以通过在数据中心 1 和 2 之间使用 Veeam Replication 来解决这个问题,但这在迁移时可能会导致更多数据丢失。
阅读手册页后,我得出以下结论:
数据中心(DC)1和2之间的流式复制:复制槽不会复制到从站。从 PG16 开始,我可以在 DB2 上订阅全局从站。如果 DC1 发生故障,通过数据中心 2 将复制中继到全局从属设备将防止出现问题,但如果 DC2 发生故障,则会导致类似的问题。将全局从站重新订阅到 DB2 将导致重新同步,或者如果禁用初始同步,从站将不再同步。
数据中心 (DC) 1 和 2 之间的逻辑复制:此处复制槽未复制到从属服务器。此外,DB2 将具有完全不同的 LSN 和时间线,因此 DB1 的 LSN 不能与 DB2 的 LSN 相关。
当在 DB1 和 DB2 之间使用流复制时,DB2 会得到提升。如果我使用 pg_create_logic_replication_slot() 在 DB2 上创建新的复制槽,然后在全局从属服务器上更改订阅连接字符串的
host
参数,全局从属服务器会在正确的位置继续复制吗?
经过大量研究,答案是:这是可能的,而且实际上已经进行了大量讨论。在 postgresql 世界中,他们称之为“逻辑复制和物理备用故障转移”或“故障转移槽”。
基本上,必须有一个流复制“副本”,如果原始主数据库将被提升为新的主数据库。此外,在提升副本之前,逻辑复制的复制槽必须存在于副本上。这很困难,就像 Postgresql <16 it is not possible to create replication slots on a replica.
因此,存在将replication_slot 文件从主副本复制到副本的“黑客”(即Patroni 使用此技术)。然而,可能存在多种竞争条件,可能导致逻辑复制订阅者上的数据不一致,特别是当物理副本落后于逻辑复制订阅者时,并且订阅者将切换到升级的副本(即,请参阅“相关提供者/订阅者不同步问题”,位于 https://github.com/zalando/patroni/issues/1749)。
详细讨论可以在Postgresql Wiki中找到: https://wiki.postgresql.org/wiki/Logical_replication_and_physical_standby_failover https://wiki.postgresql.org/wiki/Failover_slots