pgpool2.git / summary / log / commit / refs
commit 259cdf99fc195713abdb5eb86a6a85bc81947c77
Author: Tatsuo Ishii <ishii@postgresql.org>
Date: Sun Apr 17 08:46:45 2016 +0000
Do not restart child process if certain conditions met
- Streaming replication mode
- request option is REQ_DETAIL_SWITCHOVER
- does not use the load balance node (that means the process does not
issue queries to the load balance node)
- the node is not primary node
src/main/pgpool_main.c | 112 +++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 100 insertions(+), 12 deletions(-)
diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c
index a8208a128..c320993ad 100644
--- a/src/main/pgpool_main.c
+++ b/src/main/pgpool_main.c
@@ -5,7 +5,7 @@
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2015 PgPool Global Development Group
+ * Copyright (c) 2003-2016 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
@@ -1443,12 +1443,13 @@ static RETSIGTYPE failover_handler(int sig)
*/
static void failover(void)
{
- int i;
+ int i, j, k;
int node_id;
int new_master;
int new_primary;
int nodes[MAX_NUM_BACKENDS];
bool need_to_restart_children;
+ bool partial_restart;
int status;
int sts;
bool need_to_restart_pcp = false;
@@ -1607,7 +1608,7 @@ static void failover(void)
failoverLockRes = wd_failover_command_start(NODE_PROMOTE_CMD);
}
- else
+ else /* NODE_DOWN_REQUEST */
{
int cnt = 0;
@@ -1699,15 +1700,17 @@ static void failover(void)
}
#endif
+ ereport(DEBUG1, (errmsg("failover/failback request details: STREAM: %d reqkind: %d detail: %x node_id: %d",
+ STREAM, reqkind, request_details & REQ_DETAIL_SWITCHOVER,
+ node_id)));
/* On 2011/5/2 Tatsuo Ishii says: if mode is streaming replication
- * and request is NODE_UP_REQUEST(failback case) we don't need to
+ * and request is NODE_UP_REQUEST (failback case) we don't need to
* restart all children. Existing session will not use newly
* attached node, but load balanced node is not changed until this
* session ends, so it's harmless anyway.
*/
- if (MASTER_SLAVE && !strcmp(pool_config->master_slave_sub_mode, MODE_STREAMREP) &&
- reqkind == NODE_UP_REQUEST)
+ if (STREAM && reqkind == NODE_UP_REQUEST)
{
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,
@@ -1715,6 +1718,58 @@ static void failover(void)
BACKEND_INFO(node_id).backend_port)));
need_to_restart_children = false;
+ partial_restart = false;
+ }
+
+ /*
+ * If the mode is streaming replication and the request is
+ * NODE_DOWN_REQUEST and it's actually a switch over request, we don't
+ * need to restart all children, except the node is primary.
+ */
+ else if (STREAM && reqkind == NODE_DOWN_REQUEST &&
+ request_details & REQ_DETAIL_SWITCHOVER && node_id != PRIMARY_NODE_ID)
+ {
+ ereport(LOG,
+ (errmsg("Do not restart children because we are switching over node id %d host%s port:%d and we are in streaming replication mode", node_id,
+ BACKEND_INFO(node_id).backend_hostname,
+ BACKEND_INFO(node_id).backend_port)));
+
+ need_to_restart_children = true;
+ partial_restart = true;
+
+ for (i = 0; i < pool_config->num_init_children; i++)
+ {
+ bool restart = false;
+
+ for (j=0;j<pool_config->max_pool;j++)
+ {
+ for (k=0;k<NUM_BACKENDS;k++)
+ {
+ ConnectionInfo *con = pool_coninfo(i, j, k);
+
+ if (con->connected && con->load_balancing_node == node_id)
+ {
+ ereport(LOG,
+ (errmsg("child pid %d needs to restart because pool %d uses backend %d",
+ process_info[i].pid, j, node_id)));
+ restart = true;
+ break;
+ }
+ }
+ }
+
+ if (restart)
+ {
+ pid_t pid = process_info[i].pid;
+ if (pid)
+ {
+ kill(pid, SIGQUIT);
+ ereport(DEBUG1,
+ (errmsg("failover handler"),
+ errdetail("kill process with PID:%d", pid)));
+ }
+ }
+ }
}
else
{
@@ -1735,6 +1790,7 @@ static void failover(void)
}
need_to_restart_children = true;
+ partial_restart = false;
}
failoverLockRes = wd_failover_command_start(NODE_FAILED_CMD);
@@ -1872,12 +1928,11 @@ static void failover(void)
}
- /* Fork the children if needed */
+ /* Kill children and restart them if needed */
if (need_to_restart_children)
{
for (i=0;i<pool_config->num_init_children;i++)
{
-
/*
* Try to kill pgpool child because previous kill signal
* may not be received by pgpool child. This could happen
@@ -1888,16 +1943,49 @@ static void failover(void)
* signal mask is set as well, thus signals are never
* received.
*/
- kill(process_info[i].pid, SIGQUIT);
- process_info[i].pid = fork_a_child(fds, i);
- process_info[i].start_time = time(NULL);
+ bool restart = false;
+
+ if (partial_restart)
+ {
+ for (j=0;j<pool_config->max_pool;j++)
+ {
+ for (k=0;k<NUM_BACKENDS;k++)
+ {
+ ConnectionInfo *con = pool_coninfo(i, j, k);
+
+ if (con->connected && con->load_balancing_node == node_id)
+ {
+
+ ereport(LOG,
+ (errmsg("child pid %d needs to restart because pool %d uses backend %d",
+ process_info[i].pid, j, node_id)));
+ restart = true;
+ break;
+ }
+ }
+ }
+ }
+ else
+ restart = true;
+
+ if (restart)
+ {
+ if (process_info[i].pid)
+ {
+ kill(process_info[i].pid, SIGQUIT);
+
+ process_info[i].pid = fork_a_child(fds, i);
+ process_info[i].start_time = time(NULL);
+ }
+ }
}
}
+
else
{
/* Set restart request to each child. Children will exit(1)
- * whenever they are idle to restart.
+ * whenever they are convenient.
*/
for (i=0;i<pool_config->num_init_children;i++)
{
[parent: 9b62eca4042a]