PG pool failover 导致两个独立的master出现网络故障

use*_*142 7 postgresql failover

我已经使用 PG Pool 设置了两台服务器来为 web 应用程序创建 HA 设置。

PGPool 和 postgres 在两台服务器上运行,使用从服务器 1 到服务器 2 的流式复制。每台机器上的 webapp 连接到 PgPool,然后将请求发送到当前主服务器。如果数据库连接中断,它被设置为自动故障转移,它运行自定义故障转移脚本将服务器 1 降级为从服务器并将服务器 2 提升为主服务器。

今天早上发生的事情是,网络中断了 2 分钟,这意味着两个 PGPool 实例都无法相互通信 - 因此每个 PGPool 都认为另一台机器出现故障。

服务器 1 - 继续作为主服务器,断开服务器 2
服务器 2 - 启动故障转移,断开服务器 1 并使其自己成为主服务器

由于网络关闭,故障转移命令无法通过服务器 1 使其成为从服务器,反之亦然。因此,当网络在 2 分钟后恢复正常时,我所拥有的是两台服务器,它们都认为自己是主服务器。

PgPool 似乎没有自动故障回复命令,可以用来在网络重新连接时强制服务器 1 再次成为主服务器,这是我能想到的唯一真正的解决方案。

我的问题是我应该如何处理这种情况?这甚至是此设置的正确架构吗?当然,这是一个常见的情况,我无法理解如何解决这种问题。

编辑:是否建议 pgpool 在 linux-ha 下的虚拟 ip 下运行?这可以解决问题,而且我已经为公共 IP 启动并运行了它——这样,任何一台机器都只能访问一个 pgpool 实例。

Ant*_*des 5

首先,我认为 pgpool2 确实有一个故障回复命令,但在这种情况下这对您没有多大帮助。问题是,如果两台机器都认为自己是主人,就会导致混乱。更重要的是,这里有一个简单的案例:网络出现故障。如果网络分区了怎么办?即,两台机器都已连接,但它们以某种方式失去了彼此的连接。在这种情况下,两台机器都将成为 master,它们将为不同的客户端提供服务,并且您将拥有一个分叉的数据库。这是一种罕见的情况,但你确定你准备好冒由此产生的混乱的风险吗?

另一种选择是这样的:

                                    +- master db
                                    |
                ------ pgpool ------+
                                    |
                                    +- hot standby
Run Code Online (Sandbox Code Playgroud)

但是,在这种情况下,您可能不希望出现单点故障 pgpool。我知道只有两种方法可以解决这个问题。最简单的方法是仅手动将备用提升为 master,这适用于您的架构。在人工干预之前,您的应用程序将需要进入只读模式。

第二种方法是有法定人数。一种可行的架构是这样的:

                +--- pgpool standing by -+    +- master db
                |                        |    |
   failover ip -+--- active pgpool      -+----+- hot standby 1
                |                        |    |
                +--- pgpool standing by -+    +- hot standby 2
                                              |
                                              +- hot standby 3

                                              (as many standby servers as
                                              you want, so that you have
                                              read-only load balancing)
Run Code Online (Sandbox Code Playgroud)

三个 pgpool 运行在三台不同的机器上,每台机器都有自己的 IP 地址,但它们还提供了一个额外的故障转移 IP 地址,仅由活动机器使用,并且是客户端使用的地址。如果活动 pgpool 出现故障,备用 pgpool 会接管它。这可以通过heartbeat.

为了将热备份提升为 master,pgpool 的法定人数(即三个中的至少两个)必须如此决定;并且他们只会在做出决定后的延迟(例如 10 秒)后才会执行该决定。此外,活动 pgpool 可能不会在没有得到至少另一个 pgpool 确认的情况下继续使用现有的主数据库超过 10 秒(这是为了防止两个备用 pgpool 失去与活动 pgpool 的连接的情况,并master 的同时,将热备提升为 master,但活动 pgpool 继续使用旧的 master)。

实际上第三个 pgpool 不需要参与故障转移 IP,只是为了帮助仲裁。另外,我不知道 pgpool 是否有足够的功能来做到这一点。也许你需要另一个守护进程。一个更通用的架构是这样的:

              +--- active pgpool      -+          +- master db
              |                        |          | 
 failover ip -+                       -+----------+- hot standby 1
              |                        |          | 
              +--- pgpool standing by -+      +---+- hot standby 2
                                              |   | 
                                              |   +- hot standby 3
                monitoring daemon 1 ---+      |
                                       |      |
                monitoring daemon 2 ---+------+
                                       |
                monitoring daemon 3 ---+
Run Code Online (Sandbox Code Playgroud)

在这种情况下,由 pgpool 完成的负载平衡与备用数据库的监控和升级是分开的。注意你可以把pgpools、数据库服务器和监控守护进程放在同一台机器上,但是两个pgpool必须在两台不同的机器上,三个监控守护进程必须在三台不同的机器上。请注意,我不知道是否存在具有所有必要功能的现成监控守护程序。

细节可以改,但是我觉得如果不使用quorum就做自动待机提升到master的话,就是自找麻烦了。


Kha*_*led 0

如果您的服务器位于同一个 LAN 中(相互访问的网络延迟较低),您可以考虑以复制多主模式运行 pgpool。由于需要同时更新两个数据库,您将承受一些开销。

如果一个系统发生故障,pgpool 可以继续通过活动节点提供访问。系统恢复后,您可以在 pgpool 中运行在线恢复来启动另一个节点。