pgpool2.git / summary / log / commit / refs
commit b5c4ed11ffb1fdf2c416f9b9b2a8184a992d9523
Author: Tatsuo Ishii <ishii@postgresql.org>
Date: Thu Apr 07 01:21:39 2016 +0000
First cut of Proposal: minimize process restart when fail over occurs
This commit creates necessary infrastructure toward the goal:
- Add a flag to the Request info area on the shared memory, which is
used to distinguish if the request is originated by a fail over or a
switch over. The flag is called "request_details", a 8 bit unsigned
char variable. Currently only the least significant bit is used. Use
of the bit must be through REQ_DETAIL_SWITCHOVER define (if the bit
is set, the request is originated by a switch over).
- Add a boolean parameter "switch_over" to indicate the request is
originated by a switch over to:
register_node_operation_request
degenerate_backend_set
degenerate_backend_set_ex
- Modify register_node_operation_request to set the switch over flag.
- Modify failover and to retrieve the switch over flag. Currently it
just prints a debug message.
More work will need to accomplish the goal...
2016-04-07 09:52:39: pid 15692: DEBUG: failover handler
2016-04-07 09:52:39: pid 15692: DETAIL: kind: 1 flags: 1 node_count: 1 index:0
src/include/pool.h | 9 +++++---
src/main/pgpool_main.c | 43 +++++++++++++++++++++++++++------------
src/pcp_con/pcp_worker.c | 6 +++---
src/protocol/pool_process_query.c | 2 +-
src/protocol/pool_proto_modules.c | 4 ++--
src/watchdog/watchdog.c | 4 ++--
6 files changed, 44 insertions(+), 24 deletions(-)
diff --git a/src/include/pool.h b/src/include/pool.h
index ee8b1109f..864b5250a 100644
--- a/src/include/pool.h
+++ b/src/include/pool.h
@@ -395,8 +395,11 @@ typedef enum {
PROMOTE_NODE_REQUEST
} POOL_REQUEST_KIND;
+#define REQ_DETAIL_SWITCHOVER 0x00000001 /* failover due to switch over */
+
typedef struct {
POOL_REQUEST_KIND kind; /* request kind */
+ unsigned char request_details; /* option flags kind */
int node_id[MAX_NUM_BACKENDS]; /* request node id */
int count; /* request node ids count */
}POOL_REQUEST_NODE;
@@ -503,7 +506,7 @@ extern char remote_port[]; /* client port */
/*
* public functions
*/
-extern bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, int count);
+extern bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, int count, bool switch_over);
extern char *get_config_file_name(void);
extern char *get_hba_file_name(void);
extern void do_child(int *fds);
@@ -534,8 +537,8 @@ extern void NoticeResponse(POOL_CONNECTION *frontend,
POOL_CONNECTION_POOL *backend);
extern void notice_backend_error(int node_id);
-extern void degenerate_backend_set(int *node_id_set, int count);
-extern bool degenerate_backend_set_ex(int *node_id_set, int count, bool error, bool test_only);
+extern void degenerate_backend_set(int *node_id_set, int count, bool switch_over);
+extern bool degenerate_backend_set_ex(int *node_id_set, int count, bool error, bool test_only, bool switch_over);
extern void promote_backend(int node_id);
extern void send_failback_request(int node_id, bool throw_error);
diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c
index 2e9351806..a8208a128 100644
--- a/src/main/pgpool_main.c
+++ b/src/main/pgpool_main.c
@@ -542,7 +542,7 @@ process_backend_health_check_failure(int health_check_node_id, int retrycnt)
ereport(LOG,
(errmsg("setting backend node %d status to NODE DOWN", health_check_node_id)));
health_check_timer_expired = 0;
- degenerate_backend_set(&health_check_node_id,1);
+ degenerate_backend_set(&health_check_node_id, 1, false);
return 2;
/* need to distribute this info to children ??*/
}
@@ -556,10 +556,12 @@ process_backend_health_check_failure(int health_check_node_id, int retrycnt)
* This function enqueues the failover/failback requests, and fires the failover() if the function
* is not already executing
*/
-bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, int count)
+bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, int count, bool switch_over)
{
bool failover_in_progress;
pool_sigset_t oldmask;
+ int index;
+ unsigned char request_details = 0;
/*
* if the queue is already full
@@ -578,10 +580,17 @@ bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, i
return false;
}
Req_info->request_queue_tail++;
- Req_info->request[Req_info->request_queue_tail % MAX_REQUEST_QUEUE_SIZE].kind = kind;
+ index = Req_info->request_queue_tail % MAX_REQUEST_QUEUE_SIZE;
+ Req_info->request[index].kind = kind;
+
+ /* Set switch over flag if requested */
+ if (switch_over)
+ request_details |= REQ_DETAIL_SWITCHOVER;
+ Req_info->request[index].request_details = request_details;
+
if(count > 0)
- memcpy(Req_info->request[Req_info->request_queue_tail % MAX_REQUEST_QUEUE_SIZE].node_id, node_id_set, (sizeof(int) * count));
- Req_info->request[Req_info->request_queue_tail % MAX_REQUEST_QUEUE_SIZE].count = count;
+ memcpy(Req_info->request[index].node_id, node_id_set, (sizeof(int) * count));
+ Req_info->request[index].count = count;
failover_in_progress = Req_info->switching;
pool_semaphore_unlock(REQUEST_INFO_SEM);
@@ -1045,7 +1054,7 @@ void notice_backend_error(int node_id)
}
else
{
- degenerate_backend_set(&n, 1);
+ degenerate_backend_set(&n, 1, false);
}
}
@@ -1058,14 +1067,16 @@ void notice_backend_error(int node_id)
* node_id_set: array of node ids to be registered for NODE DOWN operation
* count: number of elements in node_id_set array
* error: if set error is thrown as soon as any node id is found in
- * in node_id_set on which operation could not be performed.
+ * node_id_set on which operation could not be performed.
* test_only: When set, function only checks if NODE DOWN operation can be
* executed on provided node ids and never registers the operation
* request.
* For test_only case function returs false or throws an error as
* soon as first non complient node in node_id_set is found
+ * switch_over: if set, the request is originated by switch over, not errors.
*/
-bool degenerate_backend_set_ex(int *node_id_set, int count, bool error, bool test_only)
+bool degenerate_backend_set_ex(int *node_id_set, int count, bool error, bool test_only,
+ bool switch_over)
{
int i;
int node_id[MAX_NUM_BACKENDS];
@@ -1144,7 +1155,7 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, bool error, bool tes
if (res != COMMAND_FAILED)
{
- register_node_operation_request(NODE_DOWN_REQUEST, node_id, node_count);
+ register_node_operation_request(NODE_DOWN_REQUEST, node_id, node_count, switch_over);
}
else
{
@@ -1161,9 +1172,9 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, bool error, bool tes
* wrapper over degenerate_backend_set_ex function to register
* NODE down operation request
*/
-void degenerate_backend_set(int *node_id_set, int count)
+void degenerate_backend_set(int *node_id_set, int count, bool switch_over)
{
- degenerate_backend_set_ex(node_id_set, count, false, false);
+ degenerate_backend_set_ex(node_id_set, count, false, false, switch_over);
}
/* send promote node request using SIGUSR1 */
@@ -1217,7 +1228,7 @@ void promote_backend(int node_id)
if (res != COMMAND_FAILED)
{
- register_node_operation_request(PROMOTE_NODE_REQUEST, &node_id, 1);
+ register_node_operation_request(PROMOTE_NODE_REQUEST, &node_id, 1, false);
}
else
{
@@ -1275,7 +1286,7 @@ void send_failback_request(int node_id,bool throw_error)
if (res != COMMAND_FAILED)
{
- register_node_operation_request(NODE_UP_REQUEST, &node_id, 1);
+ register_node_operation_request(NODE_UP_REQUEST, &node_id, 1, false);
}
else
{
@@ -1488,6 +1499,7 @@ static void failover(void)
int queue_index;
int node_id_set[MAX_NUM_BACKENDS];
int node_count;
+ unsigned char request_details;
WDFailoverCMDResults failoverLockRes;
pool_semaphore_lock(REQUEST_INFO_SEM);
@@ -1505,10 +1517,15 @@ static void failover(void)
queue_index = Req_info->request_queue_head % MAX_REQUEST_QUEUE_SIZE;
memcpy(node_id_set, Req_info->request[queue_index].node_id , (sizeof(int) * Req_info->request[queue_index].count));
reqkind = Req_info->request[queue_index].kind;
+ request_details = Req_info->request[queue_index].request_details;
node_count = Req_info->request[queue_index].count;
pool_semaphore_unlock(REQUEST_INFO_SEM);
+ ereport(DEBUG1,
+ (errmsg("failover handler"),
+ errdetail("kind: %d flags: %x node_count: %d index:%d", reqkind, request_details, node_count, queue_index)));
+
if (reqkind == CLOSE_IDLE_REQUEST)
{
kill_all_children(SIGUSR1);
diff --git a/src/pcp_con/pcp_worker.c b/src/pcp_con/pcp_worker.c
index 04d0a419a..fda3882e0 100644
--- a/src/pcp_con/pcp_worker.c
+++ b/src/pcp_con/pcp_worker.c
@@ -502,14 +502,14 @@ static int pool_detach_node(int node_id, bool gracefully)
{
if (!gracefully)
{
- degenerate_backend_set_ex(&node_id, 1, true, false);
+ degenerate_backend_set_ex(&node_id, 1, true, false, true);
return 0;
}
/* Check if the NODE DOWN can be executed on
* the given node id.
*/
- degenerate_backend_set_ex(&node_id, 1, true, true);
+ degenerate_backend_set_ex(&node_id, 1, true, true, true);
/*
* Wait until all frontends exit
@@ -529,7 +529,7 @@ static int pool_detach_node(int node_id, bool gracefully)
/*
* Now all frontends have gone. Let's do failover.
*/
- degenerate_backend_set_ex(&node_id, 1, true, false);
+ degenerate_backend_set_ex(&node_id, 1, true, false, true);
/*
* Wait for failover completed.
diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c
index b39f70d47..934cc3379 100644
--- a/src/protocol/pool_process_query.c
+++ b/src/protocol/pool_process_query.c
@@ -3631,7 +3631,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
if (pool_config->replication_stop_on_mismatch)
{
- degenerate_backend_set(degenerate_node, degenerate_node_num);
+ degenerate_backend_set(degenerate_node, degenerate_node_num, false);
retcode = 1;
}
ereport(FATAL,
diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c
index 15aa00bcc..242799ef8 100644
--- a/src/protocol/pool_proto_modules.c
+++ b/src/protocol/pool_proto_modules.c
@@ -387,7 +387,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
ereport(DEBUG1,
(errmsg("Query: sending SIGUSR1 signal to parent")));
- register_node_operation_request(CLOSE_IDLE_REQUEST, NULL, 0);
+ register_node_operation_request(CLOSE_IDLE_REQUEST, NULL, 0, false);
/* we need to loop over here since we will get USR1 signal while sleeping */
while (stime > 0)
@@ -1515,7 +1515,7 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
free_string(msg);
- degenerate_backend_set(victim_nodes, number_of_nodes);
+ degenerate_backend_set(victim_nodes, number_of_nodes, true);
child_exit(POOL_EXIT_AND_RESTART);
}
else
diff --git a/src/watchdog/watchdog.c b/src/watchdog/watchdog.c
index 40186d11e..69cc956e0 100644
--- a/src/watchdog/watchdog.c
+++ b/src/watchdog/watchdog.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
@@ -4980,7 +4980,7 @@ static bool process_wd_command_function(WatchdogNode* wdNode, WDPacketData* pkt,
{
reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt);
wd_set_node_mask_for_degenerate_req(node_id_list, node_count);
- degenerate_backend_set(node_id_list,node_count);
+ degenerate_backend_set(node_id_list, node_count, false);
}
}
[parent: 64696fd839da]