diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c index 0e21d37d..cf6a04d7 100644 --- a/src/config/pool_config_variables.c +++ b/src/config/pool_config_variables.c @@ -115,6 +115,7 @@ static const char *BackendDataDirShowFunc(int index); static const char *BackendHostShowFunc(int index); static const char *BackendPortShowFunc(int index); static const char *BackendWeightShowFunc(int index); +static const char *PrimaryBackendWeightShowFunc(int index); static const char *BackendAppNameShowFunc(int index); static const char *HealthCheckPeriodShowFunc(int index); @@ -139,6 +140,7 @@ static bool BackendHostAssignFunc(ConfigContext context, char *newval, int index static bool BackendDataDirAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool BackendFlagsAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool BackendWeightAssignFunc(ConfigContext context, double newval, int index, int elevel); +static bool PrimaryBackendWeightAssignFunc(ConfigContext context, double newval, int index, int elevel); static bool BackendAppNameAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool HBDestinationPortAssignFunc(ConfigContext context, int newval, int index, int elevel); static bool HBDeviceAssignFunc(ConfigContext context, char *newval, int index, int elevel); @@ -1607,6 +1609,18 @@ static struct config_double_array ConfigureNamesDoubleArray[] = EMPTY_CONFIG_DOUBLE, BackendWeightAssignFunc, NULL, BackendWeightShowFunc, BackendSlotEmptyCheckFunc }, + { + + {"backend_weight_primary", CFGCXT_RELOAD, CONNECTION_CONFIG, + "load balance weight of backend in primary role.", + CONFIG_VAR_TYPE_DOUBLE_ARRAY, true, 0, MAX_NUM_BACKENDS + }, + NULL, + -1, + 0.0, 100000000.0, + EMPTY_CONFIG_DOUBLE, + PrimaryBackendWeightAssignFunc, NULL, PrimaryBackendWeightShowFunc, BackendSlotEmptyCheckFunc + }, /* End-of-list marker */ EMPTY_CONFIG_DOUBLE_ARRAY @@ -2488,7 +2502,7 @@ build_variable_groups(void) { /* we build these by hand */ /* group 1. Backend config vars */ - ConfigureVarGroups[0].var_count = 6; + ConfigureVarGroups[0].var_count = 7; ConfigureVarGroups[0].var_list = palloc0(sizeof(struct config_generic *) * ConfigureVarGroups[0].var_count); ConfigureVarGroups[0].var_list[0] = find_option("backend_hostname", FATAL); ConfigureVarGroups[0].var_list[0]->flags |= VAR_PART_OF_GROUP; @@ -2496,12 +2510,14 @@ build_variable_groups(void) ConfigureVarGroups[0].var_list[1]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[0].var_list[2] = find_option("backend_weight", FATAL); ConfigureVarGroups[0].var_list[2]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[0].var_list[3] = find_option("backend_data_directory", FATAL); + ConfigureVarGroups[0].var_list[3] = find_option("backend_weight_primary", FATAL); ConfigureVarGroups[0].var_list[3]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[0].var_list[4] = find_option("backend_application_name", FATAL); + ConfigureVarGroups[0].var_list[4] = find_option("backend_data_directory", FATAL); ConfigureVarGroups[0].var_list[4]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[0].var_list[5] = find_option("backend_flag", FATAL); + ConfigureVarGroups[0].var_list[5] = find_option("backend_application_name", FATAL); ConfigureVarGroups[0].var_list[5]->flags |= VAR_PART_OF_GROUP; + ConfigureVarGroups[0].var_list[6] = find_option("backend_flag", FATAL); + ConfigureVarGroups[0].var_list[6]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[0].gen.max_elements = ConfigureVarGroups[0].var_list[0]->max_elements; /* group 2. other_pgpool config vars */ @@ -3997,6 +4013,26 @@ BackendWeightAssignFunc(ConfigContext context, double newval, int index, int ele return true; } +static bool +PrimaryBackendWeightAssignFunc(ConfigContext context, double newval, int index, int elevel) +{ + double old_v = g_pool_config.backend_desc->backend_info[index].unnormalized_weight_primary; + + g_pool_config.backend_desc->backend_info[index].unnormalized_weight_primary = newval; + + /* + * Log weight change event only when context is reloading of pgpool.conf + * and weight is actually changed + */ + if (context == CFGCXT_RELOAD && old_v != newval) + { + ereport(LOG, + (errmsg("initializing pool configuration: primary mode backend weight for backend:%d changed from %f to %f", index, old_v, newval), + errdetail("This change will be effective from next client session"))); + } + return true; +} + static bool BackendPortAssignFunc(ConfigContext context, int newval, int index, int elevel) @@ -4248,6 +4284,12 @@ BackendWeightShowFunc(int index) return IntValueShowFunc(g_pool_config.backend_desc->backend_info[index].unnormalized_weight); } +static const char * +PrimaryBackendWeightShowFunc(int index) +{ + return IntValueShowFunc(g_pool_config.backend_desc->backend_info[index].unnormalized_weight_primary); +} + static const char * BackendPortShowFunc(int index) { @@ -4622,6 +4664,12 @@ config_post_processor(ConfigContext context, int elevel) { total_weight += backend_info->unnormalized_weight; local_num_backends = i + 1; + /* + * Use backend_weight for the primary backend weight when + * explicit primary backend weight is not provided + */ + if (backend_info->unnormalized_weight_primary < 0) + backend_info->unnormalized_weight_primary = backend_info->unnormalized_weight; /* initialize backend_hostname with a default socket path if empty */ if (*(backend_info->backend_hostname) == '\0') @@ -4658,9 +4706,14 @@ config_post_processor(ConfigContext context, int elevel) backend_info->backend_weight = (RAND_MAX) * backend_info->unnormalized_weight / total_weight; + backend_info->backend_weight_primary = + (RAND_MAX) * backend_info->unnormalized_weight_primary / total_weight; + + backend_info->backend_weight_standby = backend_info->backend_weight; + ereport(DEBUG1, (errmsg("initializing pool configuration"), - errdetail("backend %d weight: %f flag: %04x", i, backend_info->backend_weight, backend_info->flag))); + errdetail("backend %d weight: %f primary backend weight: %f flag: %04x", i, backend_info->backend_weight,backend_info->backend_weight_primary, backend_info->flag))); } } diff --git a/src/include/pcp/libpcp_ext.h b/src/include/pcp/libpcp_ext.h index b62c3b28..65869f0e 100644 --- a/src/include/pcp/libpcp_ext.h +++ b/src/include/pcp/libpcp_ext.h @@ -92,8 +92,11 @@ typedef struct BACKEND_STATUS backend_status; /* backend status */ char pg_backend_status[NAMEDATALEN]; /* backend status examined by show pool_nodes and pcp_node_info*/ time_t status_changed_time; /* backend status changed time */ - double backend_weight; /* normalized backend load balance ratio */ + double backend_weight; /* current normalized backend load balance ratio */ + double backend_weight_standby; /* normalized backend load balance ratio when node in in standby role */ + double backend_weight_primary; /* normalized backend load balance ratio when node is in primary role */ double unnormalized_weight; /* described parameter */ + double unnormalized_weight_primary; /* described parameter */ char backend_data_directory[MAX_PATH_LENGTH]; char backend_application_name[NAMEDATALEN]; /* application_name for walreceiver */ unsigned short flag; /* various flags */ diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index c4453a76..0d16edce 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -429,6 +429,13 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) Req_info->primary_node_id = find_primary_node_repeatedly(); } + /* Use the primary backend weights for primary node */ + if (Req_info->primary_node_id >= 0) + { + /* Save primary node id */ + BACKEND_INFO(Req_info->primary_node_id).backend_weight = BACKEND_INFO(Req_info->primary_node_id).backend_weight_primary; + } + /* fork a child for PCP handling */ pcp_unix_fd = create_unix_domain_socket(pcp_un_addr); /* Add onproc exit to clean up the unix domain socket at exit */ @@ -1870,7 +1877,10 @@ failover(void) else { if (Req_info->primary_node_id >= 0) + { BACKEND_INFO(Req_info->primary_node_id).role = ROLE_STANDBY; + BACKEND_INFO(Req_info->primary_node_id).backend_weight = BACKEND_INFO(Req_info->primary_node_id).backend_weight_standby; + } new_primary = find_primary_node_repeatedly(); } } @@ -1953,11 +1963,17 @@ failover(void) if (Req_info->primary_node_id >= 0) { pool_set_backend_status_changed_time(Req_info->primary_node_id); + /* restore the backend_weight to standby backend weight, for old primary + * This ensures that reattaching the node will use the correct weight + */ + BACKEND_INFO(Req_info->primary_node_id).backend_weight = BACKEND_INFO(Req_info->primary_node_id).backend_weight_standby; } if (new_primary >= 0) { BACKEND_INFO(new_primary).role = ROLE_PRIMARY; pool_set_backend_status_changed_time(new_primary); + BACKEND_INFO(new_primary).backend_weight = BACKEND_INFO(new_primary).backend_weight_primary; + } } Req_info->primary_node_id = new_primary; diff --git a/src/sample/pgpool.conf.sample-logical b/src/sample/pgpool.conf.sample-logical index 14d5f55b..2a13819e 100644 --- a/src/sample/pgpool.conf.sample-logical +++ b/src/sample/pgpool.conf.sample-logical @@ -79,6 +79,10 @@ backend_port0 = 5432 # Port number for backend 0 backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) +backend_weight_primary0 = 1 + # Weight for backend 0 when it is in primary mode + # (only in load balancing mode) + backend_data_directory0 = '/data' # Data directory for backend 0 backend_flag0 = 'ALLOW_TO_FAILOVER' @@ -90,6 +94,7 @@ backend_application_name0 = 'server0' #backend_hostname1 = 'host2' #backend_port1 = 5433 #backend_weight1 = 1 +#backend_weight_primary1 = 0 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' #backend_application_name1 = 'server1' diff --git a/src/sample/pgpool.conf.sample-raw b/src/sample/pgpool.conf.sample-raw index 080a0329..c7a8e572 100644 --- a/src/sample/pgpool.conf.sample-raw +++ b/src/sample/pgpool.conf.sample-raw @@ -80,6 +80,9 @@ backend_port0 = 5432 # Port number for backend 0 backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) +backend_weight_primary0 = 1 + # Weight for backend 0 when it is in primary mode + # (only in load balancing mode) backend_data_directory0 = '/data' # Data directory for backend 0 backend_flag0 = 'ALLOW_TO_FAILOVER' @@ -90,6 +93,7 @@ backend_application_name0 = 'server0' # walsender's application_name, used for "show pool_nodes" command #backend_hostname1 = 'host2' #backend_port1 = 5433 +#backend_weight_primary1 = 0 #backend_weight1 = 1 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' diff --git a/src/sample/pgpool.conf.sample-replication b/src/sample/pgpool.conf.sample-replication index 40e28870..ca15b29b 100644 --- a/src/sample/pgpool.conf.sample-replication +++ b/src/sample/pgpool.conf.sample-replication @@ -79,6 +79,10 @@ backend_port0 = 5432 # Port number for backend 0 backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) +backend_weight_primary0 = 1 + # Weight for backend 0 when it is in primary mode + # (only in load balancing mode) + backend_data_directory0 = '/data' # Data directory for backend 0 backend_flag0 = 'ALLOW_TO_FAILOVER' @@ -87,6 +91,7 @@ backend_flag0 = 'ALLOW_TO_FAILOVER' #backend_hostname1 = 'host2' #backend_port1 = 5433 #backend_weight1 = 1 +#backend_weight_primary1 = 0 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' diff --git a/src/sample/pgpool.conf.sample-slony b/src/sample/pgpool.conf.sample-slony index 884cae7b..8d5096a2 100644 --- a/src/sample/pgpool.conf.sample-slony +++ b/src/sample/pgpool.conf.sample-slony @@ -79,6 +79,10 @@ backend_port0 = 5432 # Port number for backend 0 backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) +backend_weight_primary0 = 1 + # Weight for backend 0 when it is in primary mode + # (only in load balancing mode) + backend_data_directory0 = '/data' # Data directory for backend 0 backend_flag0 = 'ALLOW_TO_FAILOVER' @@ -88,6 +92,7 @@ backend_flag0 = 'ALLOW_TO_FAILOVER' #backend_hostname1 = 'host2' #backend_port1 = 5433 #backend_weight1 = 1 +#backend_weight_primary1 = 0 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' diff --git a/src/sample/pgpool.conf.sample-snapshot b/src/sample/pgpool.conf.sample-snapshot index db505d01..b36e5f51 100644 --- a/src/sample/pgpool.conf.sample-snapshot +++ b/src/sample/pgpool.conf.sample-snapshot @@ -79,6 +79,10 @@ backend_port0 = 5432 # Port number for backend 0 backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) +backend_weight_primary0 = 1 + # Weight for backend 0 when it is in primary mode + # (only in load balancing mode) + backend_data_directory0 = '/data' # Data directory for backend 0 backend_flag0 = 'ALLOW_TO_FAILOVER' @@ -87,6 +91,7 @@ backend_flag0 = 'ALLOW_TO_FAILOVER' #backend_hostname1 = 'host2' #backend_port1 = 5433 #backend_weight1 = 1 +#backend_weight_primary1 = 0 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' diff --git a/src/sample/pgpool.conf.sample-stream b/src/sample/pgpool.conf.sample-stream index bb643121..387826ec 100644 --- a/src/sample/pgpool.conf.sample-stream +++ b/src/sample/pgpool.conf.sample-stream @@ -80,6 +80,10 @@ backend_port0 = 5432 # Port number for backend 0 backend_weight0 = 1 # Weight for backend 0 (only in load balancing mode) +backend_weight_primary0 = 1 + # Weight for backend 0 when it is in primary mode + # (only in load balancing mode) + backend_data_directory0 = '/data' # Data directory for backend 0 backend_flag0 = 'ALLOW_TO_FAILOVER' @@ -91,6 +95,7 @@ backend_application_name0 = 'server0' #backend_hostname1 = 'host2' #backend_port1 = 5433 #backend_weight1 = 1 +#backend_weight_primary1 = 0 #backend_data_directory1 = '/data1' #backend_flag1 = 'ALLOW_TO_FAILOVER' #backend_application_name1 = 'server1' diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c index 78a29276..27d13b7a 100644 --- a/src/utils/pool_process_reporting.c +++ b/src/utils/pool_process_reporting.c @@ -1073,6 +1073,11 @@ get_config(int *nrows) snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "weight of backend #%d", j); i++; + snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend_weight_primary%d", j); + snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%f", BACKEND_INFO(j).backend_weight_primary / RAND_MAX); + snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "weight of backend in primary mode#%d", j); + i++; + snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend_data_directory%d", j); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", BACKEND_INFO(j).backend_data_directory); snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "data directory for backend #%d", j);