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]