Remove unnecessary SConfig from readwritesplit
The configuration doesn't need to be contained in shared pointer as each session holds its own version of it. This removes most of the overhead in configuration reloading. The only thing that's left is any overhead added by the use of thread-local storage.
This commit is contained in:
@ -58,7 +58,7 @@ using namespace maxscale;
|
||||
* @param options Router options
|
||||
* @return True on success, false if a configuration error was found
|
||||
*/
|
||||
static bool rwsplit_process_router_options(SConfig config, char **options)
|
||||
static bool rwsplit_process_router_options(Config& config, char **options)
|
||||
{
|
||||
if (options == NULL)
|
||||
{
|
||||
@ -94,51 +94,51 @@ static bool rwsplit_process_router_options(SConfig config, char **options)
|
||||
"Allowed values are LEAST_GLOBAL_CONNECTIONS, "
|
||||
"LEAST_ROUTER_CONNECTIONS, LEAST_BEHIND_MASTER,"
|
||||
"and LEAST_CURRENT_OPERATIONS.",
|
||||
STRCRITERIA(config->slave_selection_criteria));
|
||||
STRCRITERIA(config.slave_selection_criteria));
|
||||
success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
config->slave_selection_criteria = c;
|
||||
config.slave_selection_criteria = c;
|
||||
}
|
||||
}
|
||||
else if (strcmp(options[i], "max_sescmd_history") == 0)
|
||||
{
|
||||
config->max_sescmd_history = atoi(value);
|
||||
config.max_sescmd_history = atoi(value);
|
||||
}
|
||||
else if (strcmp(options[i], "disable_sescmd_history") == 0)
|
||||
{
|
||||
config->disable_sescmd_history = config_truth_value(value);
|
||||
config.disable_sescmd_history = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "master_accept_reads") == 0)
|
||||
{
|
||||
config->master_accept_reads = config_truth_value(value);
|
||||
config.master_accept_reads = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "strict_multi_stmt") == 0)
|
||||
{
|
||||
config->strict_multi_stmt = config_truth_value(value);
|
||||
config.strict_multi_stmt = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "strict_sp_calls") == 0)
|
||||
{
|
||||
config->strict_sp_calls = config_truth_value(value);
|
||||
config.strict_sp_calls = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "retry_failed_reads") == 0)
|
||||
{
|
||||
config->retry_failed_reads = config_truth_value(value);
|
||||
config.retry_failed_reads = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "master_failure_mode") == 0)
|
||||
{
|
||||
if (strcasecmp(value, "fail_instantly") == 0)
|
||||
{
|
||||
config->master_failure_mode = RW_FAIL_INSTANTLY;
|
||||
config.master_failure_mode = RW_FAIL_INSTANTLY;
|
||||
}
|
||||
else if (strcasecmp(value, "fail_on_write") == 0)
|
||||
{
|
||||
config->master_failure_mode = RW_FAIL_ON_WRITE;
|
||||
config.master_failure_mode = RW_FAIL_ON_WRITE;
|
||||
}
|
||||
else if (strcasecmp(value, "error_on_write") == 0)
|
||||
{
|
||||
config->master_failure_mode = RW_ERROR_ON_WRITE;
|
||||
config.master_failure_mode = RW_ERROR_ON_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -159,7 +159,7 @@ static bool rwsplit_process_router_options(SConfig config, char **options)
|
||||
}
|
||||
|
||||
// TODO: Don't process parameters in readwritesplit
|
||||
static bool handle_max_slaves(SConfig config, const char *str)
|
||||
static bool handle_max_slaves(Config& config, const char *str)
|
||||
{
|
||||
bool rval = true;
|
||||
char *endptr;
|
||||
@ -167,13 +167,13 @@ static bool handle_max_slaves(SConfig config, const char *str)
|
||||
|
||||
if (*endptr == '%' && *(endptr + 1) == '\0')
|
||||
{
|
||||
config->rw_max_slave_conn_percent = val;
|
||||
config->max_slave_connections = 0;
|
||||
config.rw_max_slave_conn_percent = val;
|
||||
config.max_slave_connections = 0;
|
||||
}
|
||||
else if (*endptr == '\0')
|
||||
{
|
||||
config->max_slave_connections = val;
|
||||
config->rw_max_slave_conn_percent = 0;
|
||||
config.max_slave_connections = val;
|
||||
config.rw_max_slave_conn_percent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -184,7 +184,7 @@ static bool handle_max_slaves(SConfig config, const char *str)
|
||||
return rval;
|
||||
}
|
||||
|
||||
RWSplit::RWSplit(SERVICE* service, SConfig config):
|
||||
RWSplit::RWSplit(SERVICE* service, const Config& config):
|
||||
mxs::Router<RWSplit, RWSplitSession>(service),
|
||||
m_service(service),
|
||||
m_config(config),
|
||||
@ -194,7 +194,7 @@ RWSplit::RWSplit(SERVICE* service, SConfig config):
|
||||
|
||||
static void data_destroy_callback(void* data)
|
||||
{
|
||||
SConfig* my_config = static_cast<SConfig*>(data);
|
||||
Config* my_config = static_cast<Config*>(data);
|
||||
delete my_config;
|
||||
}
|
||||
|
||||
@ -208,16 +208,17 @@ SERVICE* RWSplit::service() const
|
||||
return m_service;
|
||||
}
|
||||
|
||||
SConfig* RWSplit::get_local_config() const
|
||||
Config* RWSplit::get_local_config() const
|
||||
{
|
||||
SConfig* my_config = static_cast<SConfig*>(mxs_rworker_get_data(m_wkey));
|
||||
Config* my_config = static_cast<Config*>(mxs_rworker_get_data(m_wkey));
|
||||
|
||||
if (my_config == nullptr)
|
||||
{
|
||||
// First time we get the configuration, create and update it
|
||||
my_config = new SConfig;
|
||||
m_lock.lock();
|
||||
my_config = new Config(m_config);
|
||||
m_lock.unlock();
|
||||
mxs_rworker_set_data(m_wkey, my_config, data_destroy_callback);
|
||||
update_local_config();
|
||||
}
|
||||
|
||||
ss_dassert(my_config);
|
||||
@ -226,7 +227,7 @@ SConfig* RWSplit::get_local_config() const
|
||||
|
||||
void RWSplit::update_local_config() const
|
||||
{
|
||||
SConfig* my_config = get_local_config();
|
||||
Config* my_config = get_local_config();
|
||||
|
||||
m_lock.lock();
|
||||
*my_config = m_config;
|
||||
@ -239,7 +240,7 @@ void RWSplit::update_config(void* data)
|
||||
inst->update_local_config();
|
||||
}
|
||||
|
||||
void RWSplit::store_config(SConfig config)
|
||||
void RWSplit::store_config(const Config& config)
|
||||
{
|
||||
m_lock.lock();
|
||||
m_config = config;
|
||||
@ -249,7 +250,7 @@ void RWSplit::store_config(SConfig config)
|
||||
mxs_rworker_broadcast(update_config, this);
|
||||
}
|
||||
|
||||
SConfig RWSplit::config() const
|
||||
const Config& RWSplit::config() const
|
||||
{
|
||||
return *get_local_config();
|
||||
}
|
||||
@ -266,9 +267,9 @@ const Stats& RWSplit::stats() const
|
||||
int RWSplit::max_slave_count() const
|
||||
{
|
||||
int router_nservers = m_service->n_dbref;
|
||||
int conf_max_nslaves = m_config->max_slave_connections > 0 ?
|
||||
m_config->max_slave_connections :
|
||||
(router_nservers * m_config->rw_max_slave_conn_percent) / 100;
|
||||
int conf_max_nslaves = m_config.max_slave_connections > 0 ?
|
||||
m_config.max_slave_connections :
|
||||
(router_nservers * m_config.rw_max_slave_conn_percent) / 100;
|
||||
return MXS_MIN(router_nservers - 1, MXS_MAX(1, conf_max_nslaves));
|
||||
}
|
||||
|
||||
@ -278,8 +279,8 @@ bool RWSplit::have_enough_servers() const
|
||||
const int min_nsrv = 1;
|
||||
const int router_nsrv = m_service->n_dbref;
|
||||
|
||||
int n_serv = MXS_MAX(m_config->max_slave_connections,
|
||||
(router_nsrv * m_config->rw_max_slave_conn_percent) / 100);
|
||||
int n_serv = MXS_MAX(m_config.max_slave_connections,
|
||||
(router_nsrv * m_config.rw_max_slave_conn_percent) / 100);
|
||||
|
||||
/** With too few servers session is not created */
|
||||
if (router_nsrv < min_nsrv || n_serv < min_nsrv)
|
||||
@ -292,15 +293,15 @@ bool RWSplit::have_enough_servers() const
|
||||
}
|
||||
else
|
||||
{
|
||||
int pct = m_config->rw_max_slave_conn_percent / 100;
|
||||
int pct = m_config.rw_max_slave_conn_percent / 100;
|
||||
int nservers = router_nsrv * pct;
|
||||
|
||||
if (m_config->max_slave_connections < min_nsrv)
|
||||
if (m_config.max_slave_connections < min_nsrv)
|
||||
{
|
||||
MXS_ERROR("Unable to start %s service. There are "
|
||||
"too few backend servers configured in "
|
||||
"MaxScale.cnf. Found %d when %d is required.",
|
||||
m_service->name, m_config->max_slave_connections, min_nsrv);
|
||||
m_service->name, m_config.max_slave_connections, min_nsrv);
|
||||
}
|
||||
if (nservers < min_nsrv)
|
||||
{
|
||||
@ -309,7 +310,7 @@ bool RWSplit::have_enough_servers() const
|
||||
"too few backend servers configured in "
|
||||
"MaxScale.cnf. Found %d%% when at least %.0f%% "
|
||||
"would be required.", m_service->name,
|
||||
m_config->rw_max_slave_conn_percent, dbgpct);
|
||||
m_config.rw_max_slave_conn_percent, dbgpct);
|
||||
}
|
||||
}
|
||||
succp = false;
|
||||
@ -345,7 +346,7 @@ RWSplit* RWSplit::create(SERVICE *service, MXS_CONFIG_PARAMETER* params)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SConfig config(new Config(params));
|
||||
Config config(params);
|
||||
|
||||
if (!handle_max_slaves(config, config_get_string(params, "max_slave_connections")))
|
||||
{
|
||||
@ -353,25 +354,25 @@ RWSplit* RWSplit::create(SERVICE *service, MXS_CONFIG_PARAMETER* params)
|
||||
}
|
||||
|
||||
/** These options cancel each other out */
|
||||
if (config->disable_sescmd_history && config->max_sescmd_history > 0)
|
||||
if (config.disable_sescmd_history && config.max_sescmd_history > 0)
|
||||
{
|
||||
config->max_sescmd_history = 0;
|
||||
config.max_sescmd_history = 0;
|
||||
}
|
||||
|
||||
if (config->optimistic_trx)
|
||||
if (config.optimistic_trx)
|
||||
{
|
||||
// Optimistic transaction routing requires transaction replay
|
||||
config->transaction_replay = true;
|
||||
config.transaction_replay = true;
|
||||
}
|
||||
|
||||
if (config->transaction_replay)
|
||||
if (config.transaction_replay)
|
||||
{
|
||||
/**
|
||||
* Replaying transactions requires that we are able to do delayed query
|
||||
* retries and reconnect to a master.
|
||||
*/
|
||||
config->delayed_retry = true;
|
||||
config->master_reconnection = true;
|
||||
config.delayed_retry = true;
|
||||
config.master_reconnection = true;
|
||||
}
|
||||
|
||||
return new (std::nothrow) RWSplit(service, config);
|
||||
@ -388,41 +389,41 @@ void RWSplit::diagnostics(DCB *dcb)
|
||||
{
|
||||
const char *weightby = serviceGetWeightingParameter(service());
|
||||
double master_pct = 0.0, slave_pct = 0.0, all_pct = 0.0;
|
||||
SConfig cnf = config();
|
||||
Config cnf = config();
|
||||
|
||||
dcb_printf(dcb, "\n");
|
||||
dcb_printf(dcb, "\tuse_sql_variables_in: %s\n",
|
||||
mxs_target_to_str(cnf->use_sql_variables_in));
|
||||
mxs_target_to_str(cnf.use_sql_variables_in));
|
||||
dcb_printf(dcb, "\tslave_selection_criteria: %s\n",
|
||||
select_criteria_to_str(cnf->slave_selection_criteria));
|
||||
select_criteria_to_str(cnf.slave_selection_criteria));
|
||||
dcb_printf(dcb, "\tmaster_failure_mode: %s\n",
|
||||
failure_mode_to_str(cnf->master_failure_mode));
|
||||
failure_mode_to_str(cnf.master_failure_mode));
|
||||
dcb_printf(dcb, "\tmax_slave_replication_lag: %d\n",
|
||||
cnf->max_slave_replication_lag);
|
||||
cnf.max_slave_replication_lag);
|
||||
dcb_printf(dcb, "\tretry_failed_reads: %s\n",
|
||||
cnf->retry_failed_reads ? "true" : "false");
|
||||
cnf.retry_failed_reads ? "true" : "false");
|
||||
dcb_printf(dcb, "\tstrict_multi_stmt: %s\n",
|
||||
cnf->strict_multi_stmt ? "true" : "false");
|
||||
cnf.strict_multi_stmt ? "true" : "false");
|
||||
dcb_printf(dcb, "\tstrict_sp_calls: %s\n",
|
||||
cnf->strict_sp_calls ? "true" : "false");
|
||||
cnf.strict_sp_calls ? "true" : "false");
|
||||
dcb_printf(dcb, "\tdisable_sescmd_history: %s\n",
|
||||
cnf->disable_sescmd_history ? "true" : "false");
|
||||
cnf.disable_sescmd_history ? "true" : "false");
|
||||
dcb_printf(dcb, "\tmax_sescmd_history: %lu\n",
|
||||
cnf->max_sescmd_history);
|
||||
cnf.max_sescmd_history);
|
||||
dcb_printf(dcb, "\tmaster_accept_reads: %s\n",
|
||||
cnf->master_accept_reads ? "true" : "false");
|
||||
cnf.master_accept_reads ? "true" : "false");
|
||||
dcb_printf(dcb, "\tconnection_keepalive: %d\n",
|
||||
cnf->connection_keepalive);
|
||||
cnf.connection_keepalive);
|
||||
dcb_printf(dcb, "\tcausal_reads: %s\n",
|
||||
cnf->causal_reads ? "true" : "false");
|
||||
cnf.causal_reads ? "true" : "false");
|
||||
dcb_printf(dcb, "\tcausal_reads_timeout: %s\n",
|
||||
cnf->causal_reads_timeout.c_str());
|
||||
cnf.causal_reads_timeout.c_str());
|
||||
dcb_printf(dcb, "\tmaster_reconnection: %s\n",
|
||||
cnf->master_reconnection ? "true" : "false");
|
||||
cnf.master_reconnection ? "true" : "false");
|
||||
dcb_printf(dcb, "\tdelayed_retry: %s\n",
|
||||
cnf->delayed_retry ? "true" : "false");
|
||||
cnf.delayed_retry ? "true" : "false");
|
||||
dcb_printf(dcb, "\tdelayed_retry_timeout: %lu\n",
|
||||
cnf->delayed_retry_timeout);
|
||||
cnf.delayed_retry_timeout);
|
||||
|
||||
dcb_printf(dcb, "\n");
|
||||
|
||||
@ -504,11 +505,11 @@ uint64_t RWSplit::getCapabilities()
|
||||
bool RWSplit::configure(MXS_CONFIG_PARAMETER* params)
|
||||
{
|
||||
bool rval = false;
|
||||
SConfig cnf(new Config(params));
|
||||
Config cnf(params);
|
||||
|
||||
if (handle_max_slaves(cnf, config_get_string(params, "max_slave_connections")))
|
||||
{
|
||||
store_config(std::move(cnf));
|
||||
store_config(cnf);
|
||||
rval = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user