diff --git a/doc.ja/src/sgml/stream-check.sgml b/doc.ja/src/sgml/stream-check.sgml index caaae13..4a0e9bf 100644 --- a/doc.ja/src/sgml/stream-check.sgml +++ b/doc.ja/src/sgml/stream-check.sgml @@ -251,6 +251,38 @@ + + prefer_lower_delay_standby (boolean) + + + prefer_lower_delay_standby 設定パラメータ + + + + + + このパラメータはを使用しているときに有効です。 + onに設定すると、負荷分散先のスタンバイサーバがdelay_thresholdを超えて遅延したときに、プライマリサーバでなく、 + が0より大きくて1番遅延の少ないスタンバイサーバを負荷分散ノードにします。 + 全てのスタンバイサーバがdelay_thresholdを超えて遅延している場合はプライマリサーバに送ります。 + デフォルトはoffです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + log_standby_delay (string) diff --git a/doc/src/sgml/stream-check.sgml b/doc/src/sgml/stream-check.sgml index d4cef8a..d89e347 100644 --- a/doc/src/sgml/stream-check.sgml +++ b/doc/src/sgml/stream-check.sgml @@ -199,6 +199,25 @@ + + prefer_lower_delay_standby (boolean) + + prefer_lower_delay_standby configuration parameter + + + + + This parameter is only valid when delay_threshold is set to larger than 0. + When set to on, if load balancing node is delayed over delay_threshold + Pgpool-II send the query to not the primary node but the least delay standby which is set backend_weight to larger than 0. + If all standby nodes are delayed over delay_threshold, Pgpool-II send to the primary. Default is off. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + log_standby_delay (string) diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c index cd42b1f..2e67e2a 100644 --- a/src/config/pool_config_variables.c +++ b/src/config/pool_config_variables.c @@ -503,6 +503,16 @@ static struct config_bool ConfigureNamesBool[] = }, { + {"prefer_lower_delay_standby", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, + "If the load balance node is delayed over delay_threshold on SR, pgpool find another standby node which is lower delayed.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.prefer_lower_delay_standby, + false, + NULL, NULL, NULL + }, + + { {"connection_cache", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "Caches connections to backends.", CONFIG_VAR_TYPE_BOOL, false, 0 diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c index 6635369..f60dc5a 100644 --- a/src/context/pool_query_context.c +++ b/src/context/pool_query_context.c @@ -547,8 +547,10 @@ pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node) */ /* - * If replication delay is too much, we prefer to send to - * the primary. + * As streaming replication delay is too much, if + * prefer_lower_delay_standby is true then elect new + * load balance node which is lower delayed, + * false then send to the primary. */ if (STREAM && pool_config->delay_threshold && @@ -558,7 +560,20 @@ pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node) (errmsg("could not load balance because of too much replication delay"), errdetail("destination = %d for query= \"%s\"", dest, query))); - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + if (pool_config->prefer_lower_delay_standby) + { + int new_load_balancing_node = select_load_balancing_node(); + ereport(DEBUG1, + (errmsg("select new load balancing node which is the most lower delay standby"), + errdetail("new load balancing node is node %d", new_load_balancing_node))); + session_context->load_balance_node_id = new_load_balancing_node; + session_context->query_context->load_balance_node_id = session_context->load_balance_node_id; + pool_set_node_to_be_sent(query_context, session_context->query_context->load_balance_node_id); + } + else + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } } /* diff --git a/src/include/pool_config.h b/src/include/pool_config.h index d473dc1..a5698d5 100644 --- a/src/include/pool_config.h +++ b/src/include/pool_config.h @@ -304,6 +304,9 @@ typedef struct * that health_check_period required to be * greater than 0 to enable the * functionality. */ + + bool prefer_lower_delay_standby; + LogStandbyDelayModes log_standby_delay; /* how to log standby lag */ bool connection_cache; /* cache connection pool? */ int health_check_timeout; /* health check timeout */ diff --git a/src/protocol/pool_pg_utils.c b/src/protocol/pool_pg_utils.c index 59ba540..201f345 100644 --- a/src/protocol/pool_pg_utils.c +++ b/src/protocol/pool_pg_utils.c @@ -313,6 +313,7 @@ select_load_balancing_node(void) POOL_SESSION_CONTEXT *ses = pool_get_session_context(false); int tmp; int no_load_balance_node_id = -2; + BackendInfo *bkinfo; /* * -2 indicates there's no database_redirect_preference_list. -1 indicates @@ -399,6 +400,42 @@ select_load_balancing_node(void) if (suggested_node_id >= 0) { /* + * If Streaming Replication mode and delay_threshold and + * prefer_lower_delay_standby is true, we choose the least delayed + * node if suggested_node is standby and delayed over delay_threshold. + */ + bkinfo = pool_get_node_info(suggested_node_id); + if (STREAM && + pool_config->delay_threshold && + pool_config->prefer_lower_delay_standby && + !IS_PRIMARY_NODE_ID(suggested_node_id) && + (bkinfo->standby_delay > pool_config->delay_threshold)) + { + selected_slot = PRIMARY_NODE_ID; + uint64 temp_delay = pool_config->delay_threshold; + + for (i = 0; i < NUM_BACKENDS; i++) + { + bkinfo = pool_get_node_info(i); + if (VALID_BACKEND_RAW(i) && + !IS_PRIMARY_NODE_ID(i) && + (bkinfo->standby_delay < temp_delay) && + (bkinfo->backend_weight > 0)) + { + selected_slot = i; + temp_delay = bkinfo->standby_delay; + } + } + ereport(DEBUG1, + (errmsg("selecting load balance node"), + errdetail("suggested backend id %d is streaming delayed over delay_threshold", suggested_node_id))); + ereport(DEBUG1, + (errmsg("selecting load balance node"), + errdetail("selected backend id is %d", selected_slot))); + return selected_slot; + } + + /* * If the weight is bigger than random rate then send to * suggested_node_id. If the weight is less than random rate then * choose load balance node from other nodes. @@ -470,6 +507,39 @@ select_load_balancing_node(void) total_weight += BACKEND_INFO(i).backend_weight; } } + + /* + * If Streaming Replication mode and delay_threshold and + * prefer_lower_delay_standby is true, we elect the most lower delayed + * node if suggested_node is standby and delayed over delay_threshold. + */ + bkinfo = pool_get_node_info(selected_slot); + if (STREAM && + pool_config->delay_threshold && + pool_config->prefer_lower_delay_standby && + (bkinfo->standby_delay > pool_config->delay_threshold)) + { + ereport(DEBUG1, + (errmsg("selecting load balance node"), + errdetail("backend id %d is streaming delayed over delay_threshold", selected_slot))); + + selected_slot = PRIMARY_NODE_ID; + uint64 temp_delay = pool_config->delay_threshold; + + for (i = 0; i < NUM_BACKENDS; i++) + { + bkinfo = pool_get_node_info(i); + if (!IS_PRIMARY_NODE_ID(i) && + VALID_BACKEND_RAW(i) && + (bkinfo->standby_delay < temp_delay) && + (bkinfo->backend_weight > 0)) + { + selected_slot = i; + temp_delay = bkinfo->standby_delay; + } + } + } + ereport(DEBUG1, (errmsg("selecting load balance node"), errdetail("selected backend id is %d", selected_slot))); diff --git a/src/sample/pgpool.conf.sample-logical b/src/sample/pgpool.conf.sample-logical index b156250..14d5f55 100644 --- a/src/sample/pgpool.conf.sample-logical +++ b/src/sample/pgpool.conf.sample-logical @@ -426,6 +426,11 @@ delay_threshold = 10000000 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default +prefer_lower_delay_standby = off + # If delay_threshold is set larger than 0, Pgpool-II send to + # the primary when selected node is delayed over delay_threshold. + # If this is set to on, Pgpool-II send query to other standby + # delayed lower. # - Special commands - diff --git a/src/sample/pgpool.conf.sample-raw b/src/sample/pgpool.conf.sample-raw index 77cc94f..e806595 100644 --- a/src/sample/pgpool.conf.sample-raw +++ b/src/sample/pgpool.conf.sample-raw @@ -466,6 +466,11 @@ delay_threshold = 10000000 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default +prefer_lower_delay_standby = off + # If delay_threshold is set larger than 0, Pgpool-II send to + # the primary when selected node is delayed over delay_threshold. + # If this is set to on, Pgpool-II send query to other standby + # delayed lower. # - Special commands - diff --git a/src/sample/pgpool.conf.sample-replication b/src/sample/pgpool.conf.sample-replication index b72dc90..8544535 100644 --- a/src/sample/pgpool.conf.sample-replication +++ b/src/sample/pgpool.conf.sample-replication @@ -462,6 +462,11 @@ delay_threshold = 0 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default +prefer_lower_delay_standby = off + # If delay_threshold is set larger than 0, Pgpool-II send to + # the primary when selected node is delayed over delay_threshold. + # If this is set to on, Pgpool-II send query to other standby + # delayed lower. # - Special commands - diff --git a/src/sample/pgpool.conf.sample-slony b/src/sample/pgpool.conf.sample-slony index ce802c4..a61af0e 100644 --- a/src/sample/pgpool.conf.sample-slony +++ b/src/sample/pgpool.conf.sample-slony @@ -463,6 +463,11 @@ delay_threshold = 0 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default +prefer_lower_delay_standby = off + # If delay_threshold is set larger than 0, Pgpool-II send to + # the primary when selected node is delayed over delay_threshold. + # If this is set to on, Pgpool-II send query to other standby + # delayed lower. # - Special commands - diff --git a/src/sample/pgpool.conf.sample-snapshot b/src/sample/pgpool.conf.sample-snapshot index 60499bd..cf489f7 100644 --- a/src/sample/pgpool.conf.sample-snapshot +++ b/src/sample/pgpool.conf.sample-snapshot @@ -460,6 +460,11 @@ delay_threshold = 0 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default +prefer_lower_delay_standby = off + # If delay_threshold is set larger than 0, Pgpool-II send to + # the primary when selected node is delayed over delay_threshold. + # If this is set to on, Pgpool-II send query to other standby + # delayed lower. # - Special commands - diff --git a/src/sample/pgpool.conf.sample-stream b/src/sample/pgpool.conf.sample-stream index 84fdce3..4097a58 100644 --- a/src/sample/pgpool.conf.sample-stream +++ b/src/sample/pgpool.conf.sample-stream @@ -465,6 +465,11 @@ delay_threshold = 10000000 # Threshold before not dispatching query to standby node # Unit is in bytes # Disabled (0) by default +prefer_lower_delay_standby = off + # If delay_threshold is set larger than 0, Pgpool-II send to + # the primary when selected node is delayed over delay_threshold. + # If this is set to on, Pgpool-II send query to other standby + # delayed lower. # - Special commands -