diff --git a/doc/src/sgml/failover.sgml b/doc/src/sgml/failover.sgml index 91dca31..98e01c2 100644 --- a/doc/src/sgml/failover.sgml +++ b/doc/src/sgml/failover.sgml @@ -706,11 +706,19 @@ if (we need to executed follow primary 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_primary 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_primary_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 7f8e9d9..bac5f84 100644 --- a/src/include/pcp/libpcp_ext.h +++ b/src/include/pcp/libpcp_ext.h @@ -99,6 +99,7 @@ typedef struct char pg_role[NAMEDATALEN]; /* backend role examined by show pool_nodes and pcp_node_info*/ 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 fc84da6..d11ee9e 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -625,6 +625,7 @@ extern int write_status_file(void); 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_main_node(void); diff --git a/src/main/health_check.c b/src/main/health_check.c index d7ed427..f10a7bb 100644 --- a/src/main/health_check.c +++ b/src/main/health_check.c @@ -310,7 +310,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; @@ -329,7 +328,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, @@ -441,7 +440,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 cf5e0c3..5d3b00f 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -1564,6 +1564,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; @@ -1856,6 +1857,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++; @@ -3518,6 +3520,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))); @@ -3583,6 +3586,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))); } @@ -3909,6 +3913,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_master_node_id = true; node_status_was_changed_to_down = true; @@ -4214,3 +4219,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; +}