src/config/pool_config_variables.c | 10 ++++++++ src/include/pool_config.h | 3 +++ src/protocol/child.c | 4 +-- src/sample/pgpool.conf.sample | 4 +++ src/sample/pgpool.conf.sample-logical | 4 +++ src/sample/pgpool.conf.sample-master-slave | 4 +++ src/sample/pgpool.conf.sample-replication | 4 +++ src/sample/pgpool.conf.sample-stream | 3 +++ src/streaming_replication/pool_worker_child.c | 36 ++++++++------------------- src/utils/pool_process_reporting.c | 5 ++++ 10 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c index cbf426d..b55b385 100644 --- a/src/config/pool_config_variables.c +++ b/src/config/pool_config_variables.c @@ -569,6 +569,16 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"auto_failback", CFGCXT_RELOAD, FAILOVER_CONFIG, + "Enables nodes automatically reattach, when dettached node continue streaming replication.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.auto_failback, + false, + NULL, NULL, NULL + }, + /* End-of-list marker */ EMPTY_CONFIG_BOOL diff --git a/src/include/pool_config.h b/src/include/pool_config.h index 32ca641..72f620a 100644 --- a/src/include/pool_config.h +++ b/src/include/pool_config.h @@ -214,6 +214,9 @@ typedef struct * false, just abort the * transaction to keep * the consistency. */ + bool auto_failback; /* If true, backend node reattach, + * when backend node detached and + * replication_status is 'stream' */ bool replicate_select; /* replicate SELECT statement when load * balancing is disabled. */ char **reset_query_list; /* comma separated list of queries to be diff --git a/src/protocol/child.c b/src/protocol/child.c index bb9e058..fc4cc4a 100644 --- a/src/protocol/child.c +++ b/src/protocol/child.c @@ -1819,7 +1819,7 @@ check_restart_request(void) if (pool_get_my_process_info()->need_to_restart) { ereport(LOG, - (errmsg("failback event detected"), + (errmsg("failover or failback event detected"), errdetail("restarting myself"))); pool_get_my_process_info()->need_to_restart = 0; @@ -2294,7 +2294,7 @@ retry_startup: { ereport(LOG, (errmsg("selecting backend connection"), - errdetail("failback event detected, discarding existing connections"))); + errdetail("failover or failback event detected, discarding existing connections"))); pool_get_my_process_info()->need_to_restart = 0; close_idle_connection(0); diff --git a/src/sample/pgpool.conf.sample b/src/sample/pgpool.conf.sample index 148d900..5dc9306 100644 --- a/src/sample/pgpool.conf.sample +++ b/src/sample/pgpool.conf.sample @@ -501,6 +501,10 @@ search_primary_node_timeout = 300 # 0 means no timeout, keep searching # for a primary node forever. +auto_failback = off + # Dettached backend node reattach automatically + # if replication_state is 'streaming'. + #------------------------------------------------------------------------------ # ONLINE RECOVERY #------------------------------------------------------------------------------ diff --git a/src/sample/pgpool.conf.sample-logical b/src/sample/pgpool.conf.sample-logical index bdd55bf..9aaff87 100644 --- a/src/sample/pgpool.conf.sample-logical +++ b/src/sample/pgpool.conf.sample-logical @@ -485,6 +485,10 @@ search_primary_node_timeout = 300 # 0 means no timeout, keep searching # for a primary node forever. +auto_failback = off + # Dettached backend node reattach automatically + # if replication_state is 'streaming'. + #------------------------------------------------------------------------------ # ONLINE RECOVERY #------------------------------------------------------------------------------ diff --git a/src/sample/pgpool.conf.sample-master-slave b/src/sample/pgpool.conf.sample-master-slave index 5607e93..d19c284 100644 --- a/src/sample/pgpool.conf.sample-master-slave +++ b/src/sample/pgpool.conf.sample-master-slave @@ -497,6 +497,10 @@ search_primary_node_timeout = 300 # 0 means no timeout, keep searching # for a primary node forever. +auto_failback = off + # Dettached backend node reattach automatically + # if replication_state is 'streaming'. + #------------------------------------------------------------------------------ # ONLINE RECOVERY #------------------------------------------------------------------------------ diff --git a/src/sample/pgpool.conf.sample-replication b/src/sample/pgpool.conf.sample-replication index 5af975c..5a886d6 100644 --- a/src/sample/pgpool.conf.sample-replication +++ b/src/sample/pgpool.conf.sample-replication @@ -495,6 +495,10 @@ search_primary_node_timeout = 300 # 0 means no timeout, keep searching # for a primary node forever. +auto_failback = off + # Dettached backend node reattach automatically + # if replication_state is 'streaming'. + #------------------------------------------------------------------------------ # ONLINE RECOVERY #------------------------------------------------------------------------------ diff --git a/src/sample/pgpool.conf.sample-stream b/src/sample/pgpool.conf.sample-stream index ab98a98..e8bc5df 100644 --- a/src/sample/pgpool.conf.sample-stream +++ b/src/sample/pgpool.conf.sample-stream @@ -525,6 +525,9 @@ client_idle_limit_in_recovery = 0 # 0 means no disconnection # -1 means immediate disconnection +auto_failback = off + # Dettached backend node reattach automatically + # if replication_state is 'streaming'. #------------------------------------------------------------------------------ # WATCHDOG diff --git a/src/streaming_replication/pool_worker_child.c b/src/streaming_replication/pool_worker_child.c index 76cb7b3..3f93a93 100644 --- a/src/streaming_replication/pool_worker_child.c +++ b/src/streaming_replication/pool_worker_child.c @@ -3,7 +3,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2019 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -308,7 +308,7 @@ check_replication_time_lag(void) active_nodes++; } - if (active_nodes <= 1) + if (active_nodes <= 1 && !pool_config->auto_failback) { /* * If there's only one or less active node, there's no point to do @@ -403,8 +403,6 @@ check_replication_time_lag(void) if (i == PRIMARY_NODE_ID) continue; - if (!VALID_BACKEND(i)) - continue; if (*stat_rep_query == '\0') continue; @@ -418,7 +416,15 @@ check_replication_time_lag(void) { strlcpy(bkinfo->replication_state, res_rep->data[1], NAMEDATALEN); strlcpy(bkinfo->replication_sync_state, res_rep->data[2], NAMEDATALEN); - free_select_result(res_rep); + free_select_result(res_rep); + /* auto failback, if node's replication is no problem but backend_status is down */ + if (pool_config->auto_failback && !strcmp(bkinfo->replication_state, "streaming") && + !VALID_BACKEND(i) && !Req_info->switching) + { + ereport(LOG, + (errmsg("auto failback, node id:%d", i))); + send_failback_request(i, true, REQ_DETAIL_CONFIRMED); + } } pfree(query_buf); } @@ -591,26 +597,6 @@ get_query_result(POOL_CONNECTION_POOL_SLOT * *slots, int backend_id, char *query return sts; } -/* - if ((*res)->data[0] == NULL) - { - free_select_result(*res); - ereport(LOG, - (errmsg("get_query_result: no rows returned"), - errdetail("node id (%d)", backend_id))); - return sts; - } - - - if ((*res)->nullflags[0] == -1) - { - free_select_result(*res); - ereport(LOG, - (errmsg("get_query_result: NULL data returned"), - errdetail("node id (%d)", backend_id))); - return sts; - } -*/ sts = 0; return sts; } diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c index 36e273b..3ec2ee7 100644 --- a/src/utils/pool_process_reporting.c +++ b/src/utils/pool_process_reporting.c @@ -635,6 +635,11 @@ get_config(int *nrows) StrNCpy(status[i].desc, "detach false primary", POOLCONFIG_MAXDESCLEN); i++; + StrNCpy(status[i].name, "auto_failback", POOLCONFIG_MAXNAMELEN); + snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->auto_failback); + StrNCpy(status[i].desc, "auto_failback", POOLCONFIG_MAXDESCLEN); + i++; + /* ONLINE RECOVERY */ StrNCpy(status[i].name, "recovery_user", POOLCONFIG_MAXNAMELEN);