Fix failover() to deal with the case when no former primary node exists.
authorTatsuo Ishii <ishii@sraoss.co.jp>
Sun, 6 Feb 2022 08:11:52 +0000 (17:11 +0900)
committerTatsuo Ishii <ishii@sraoss.co.jp>
Sun, 6 Feb 2022 08:25:50 +0000 (17:25 +0900)
Consider a case when no primary node exists when Pgpool-II starts
up. In this case Req_info->primary_node_id is -1. failover() did not
consider this and skipped to call find_primary_node_repeatedly().
Also follow_master_command was not executed if
Req_info->primary_node_id is -1.

This commit fixes the bug above.

Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2022-February/004114.html

src/main/pgpool_main.c

index c92b93ea67d8657c9a160ac291db37c8d7a82ec6..a612a5bd7bf7c39f60b277f821121aca6b0ae0be 100644 (file)
@@ -2018,15 +2018,18 @@ static void failover(void)
                        }
                }
                /*
-                * If the down node was a standby node in streaming replication
-                * mode, we can avoid calling find_primary_node_repeatedly() and
-                * recognize the former primary as the new primary node, which
-                * will reduce the time to process standby down.
+                * If the down node was a standby node in streaming replication mode,
+                * we can avoid calling find_primary_node_repeatedly() and recognize
+                * the former primary as the new primary node, which will reduce the
+                * time to process standby down.
+                * This does not apply to the case when no primary node existed
+                * (Req_info->primary_node_id < 0). In this case
+                * find_primary_node_repeatedly() should be called.
                 */
                else if (SL_MODE &&
                                 reqkind == NODE_DOWN_REQUEST)
                {
-                       if (Req_info->primary_node_id != node_id)
+                       if (Req_info->primary_node_id >= 0 && Req_info->primary_node_id != node_id)
                        {
                                new_primary = Req_info->primary_node_id;
                        }
@@ -2058,10 +2061,16 @@ static void failover(void)
                        if (*pool_config->follow_master_command != '\0' ||
                                reqkind == PROMOTE_NODE_REQUEST)
                        {
-                               /* only if the failover is against the current primary */
+                               /*
+                                * follow primary command is executed in following cases:
+                                * - failover against the current primary
+                                * - no primary exists and new primary is created by failover
+                                * - promote node request
+                                */
                                if (((reqkind == NODE_DOWN_REQUEST) &&
                                         Req_info->primary_node_id >= 0 &&
                                         (nodes[Req_info->primary_node_id])) ||
+                                       (reqkind == NODE_DOWN_REQUEST && Req_info->primary_node_id < 0 && new_primary >= 0) ||
                                        (node_id >= 0 && (reqkind == PROMOTE_NODE_REQUEST) &&
                                         (VALID_BACKEND(node_id))))
                                {