pgpool2.git / summary / log / commit / refs

commit    a7e459fa31204323df83e4a3df3135bf7d4634cd
Author:   Tatsuo Ishii <ishii@postgresql.org>
Date:     Wed Sep 21 00:26:46 2016 +0000

    Fix the case when all backends are down then 1 node attached.
    
    When all backends are down, no connection is accepted. Then 1
    PostgreSQL becomes up, and attach the node using pcp_attach_node. It
    successfully finishes. However, when a new connection arrives, still
    the connection is refused because pgpool child process looks into the
    cached status, in which the recovered node is still in down status if
    mode is streaming replication mode (native replication and other modes
    are fine). Solution is, if all nodes are down, force to restart all
    pgpool child.
    
    Per bug 248.


src/main/pgpool_main.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index 04156f702..cd490be74 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -1510,6 +1510,7 @@ static void failover(void) int status; int sts; bool need_to_restart_pcp = false; + bool all_backend_down = true; ereport(DEBUG1, (errmsg("failover handler called"))); @@ -1629,6 +1630,20 @@ static void failover(void) BACKEND_INFO(node_id).backend_hostname, BACKEND_INFO(node_id).backend_port))); + /* Check to see if all backends are down */ + for (i=0;i<NUM_BACKENDS;i++) + { + if (BACKEND_INFO(i).backend_status != CON_DOWN && + BACKEND_INFO(i).backend_status != CON_UNUSED) + { + ereport(LOG, + (errmsg("Node %d is not down (status: %d)", + i, BACKEND_INFO(i).backend_status))); + all_backend_down = false; + break; + } + } + BACKEND_INFO(node_id).backend_status = CON_CONNECT_WAIT; /* unset down status */ (void)write_status_file(); @@ -1721,10 +1736,21 @@ static void failover(void) * attached node, but load balanced node is not changed until this * session ends, so it's harmless anyway. */ - if (STREAM && reqkind == NODE_UP_REQUEST) + /* + * On 2015/9/21 Tatsuo Ishii says: this judgment is not sufficient if + * all backends were down. Child process has local status in which all + * backends are down. In this case even if new connection arrives from + * frontend, the child will not accept it because the local status + * shows all backends are down. For this purpose we refer to + * "all_backend_down" variable, which was set before updating backend status. + * + * See bug 248 for more details. + */ + + if (STREAM && reqkind == NODE_UP_REQUEST && all_backend_down == false) { ereport(LOG, - (errmsg("Do not restart children because we are failbacking node id %d host%s port:%d and we are in streaming replication mode", node_id, + (errmsg("Do not restart children because we are failbacking node id %d host: %s port: %d and we are in streaming replication mode and not all backends were down", node_id, BACKEND_INFO(node_id).backend_hostname, BACKEND_INFO(node_id).backend_port))); [parent: e89e365aca82]