diff --git a/doc/src/sgml/failover.sgml b/doc/src/sgml/failover.sgml index fdd05ae..90f3056 100644 --- a/doc/src/sgml/failover.sgml +++ b/doc/src/sgml/failover.sgml @@ -706,11 +706,19 @@ if (we need to executed follow master command) Specifies the minimum amount of time in seconds for execution interval of auto failback. Next auto failback won't execute until that specified time have passed - after previous auto failback. When Pgpool-II frequently detect - backend down because of network error for example, you may avoid repeating + after previous auto failback or node transitioning to "down" status (including temporary + "down" status during a follow_master event). When Pgpool-II + frequently detect backend down because of network error for example, you may avoid repeating failover and failback by setting this parameter to large enough value. The default is 60. Setting this parameter to 0 means that auto failback don't wait. + + + This should be set to longer than the time it takes for follow_master_command to execute + for all your backends, otherwise auto_failover may detect a backend as "up" even though + it has not yet been configured to follow the new primary backend. + + diff --git a/src/include/pcp/libpcp_ext.h b/src/include/pcp/libpcp_ext.h index 430a752..c47c8f5 100644 --- a/src/include/pcp/libpcp_ext.h +++ b/src/include/pcp/libpcp_ext.h @@ -97,6 +97,7 @@ typedef struct * primary node */ char replication_state [NAMEDATALEN]; /* "state" from pg_stat_replication */ char replication_sync_state [NAMEDATALEN]; /* "sync_state" from pg_stat_replication */ + time_t auto_failback_time; /* resume time of auto_failback */ } BackendInfo; typedef struct diff --git a/src/include/pool.h b/src/include/pool.h index 6a4118d..47c21c2 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -866,6 +866,7 @@ extern void do_health_check_child(int *node_id); extern POOL_NODE_STATUS * verify_backend_node_status(POOL_CONNECTION_POOL_SLOT * *slots); extern POOL_NODE_STATUS * pool_get_node_status(void); extern void pool_set_backend_status_changed_time(int backend_id); +extern void pool_set_backend_auto_failback_time(int backend_id); extern int get_next_master_node(void); #endif /* POOL_H */ diff --git a/src/main/health_check.c b/src/main/health_check.c index 6a1603d..3e8d049 100644 --- a/src/main/health_check.c +++ b/src/main/health_check.c @@ -235,7 +235,6 @@ establish_persistent_connection(int node) { BackendInfo *bkinfo; int retry_cnt; - static time_t auto_failback_interval = 0; /* resume time of auto_failback */ bool check_failback = false; time_t now; char *dbname; @@ -254,7 +253,7 @@ establish_persistent_connection(int node) /* get current time to use auto_faliback_interval */ now = time(NULL); - if (pool_config->auto_failback && auto_failback_interval < now && + if (pool_config->auto_failback && bkinfo->auto_failback_time < now && STREAM && !strcmp(bkinfo->replication_state, "streaming") && !Req_info->switching) { ereport(DEBUG1, @@ -351,7 +350,7 @@ establish_persistent_connection(int node) (errmsg("request auto failback, node id:%d", node))); /* get current time to use auto_faliback_interval */ now = time(NULL); - auto_failback_interval = now + pool_config->auto_failback_interval; + bkinfo->auto_failback_time = now + pool_config->auto_failback_interval; send_failback_request(node, true, REQ_DETAIL_CONFIRMED); } diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index f3053dc..42d3428 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -1900,6 +1900,7 @@ failover(void) BACKEND_INFO(node_id_set[i]).backend_status = CON_DOWN; /* set down status */ pool_set_backend_status_changed_time(node_id_set[i]); + pool_set_backend_auto_failback_time(node_id_set[i]); if (reqkind == NODE_QUARANTINE_REQUEST) { BACKEND_INFO(node_id_set[i]).quarantine = true; @@ -2192,6 +2193,7 @@ failover(void) bkinfo->backend_port))); bkinfo->backend_status = CON_DOWN; /* set down status */ pool_set_backend_status_changed_time(i); + pool_set_backend_auto_failback_time(i); (void) write_status_file(); follow_cnt++; @@ -3816,6 +3818,7 @@ read_status_file(bool discard_status) { BACKEND_INFO(i).backend_status = CON_DOWN; pool_set_backend_status_changed_time(i); + pool_set_backend_auto_failback_time(i); (void) write_status_file(); ereport(LOG, (errmsg("read_status_file: %d th backend is set to down status", i))); @@ -3881,6 +3884,7 @@ read_status_file(bool discard_status) { BACKEND_INFO(i).backend_status = CON_DOWN; pool_set_backend_status_changed_time(i); + pool_set_backend_auto_failback_time(i); ereport(LOG, (errmsg("reading status file: %d th backend is set to down status", i))); } @@ -4217,6 +4221,7 @@ sync_backend_from_watchdog(void) { BACKEND_INFO(i).backend_status = CON_DOWN; pool_set_backend_status_changed_time(i); + pool_set_backend_auto_failback_time(i); my_backend_status[i] = &(BACKEND_INFO(i).backend_status); reload_maste_node_id = true; node_status_was_changed_to_down = true; @@ -4522,3 +4527,15 @@ pool_set_backend_status_changed_time(int backend_id) tval = time(NULL); BACKEND_INFO(backend_id).status_changed_time = tval; } + +/* + * Set backend auto failback time for specified backend id. + */ +void +pool_set_backend_auto_failback_time(int backend_id) +{ + time_t tval; + + tval = time(NULL); + BACKEND_INFO(backend_id).auto_failback_time = tval + pool_config->auto_failback_interval; +}