Use shared configurations in readwritesplit

By using a shared pointer instead of a plain object, we can replace the
router configuration without it affecting existing sessions. This is a
change that is required to enable runtime reconfiguration of
readwritesplit.
This commit is contained in:
Markus Mäkelä
2018-07-05 15:08:37 +03:00
parent 13763ace32
commit bd4be3a97b
7 changed files with 107 additions and 103 deletions

View File

@ -56,7 +56,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(Config& config, char **options)
static bool rwsplit_process_router_options(SConfig config, char **options)
{
if (options == NULL)
{
@ -92,51 +92,51 @@ static bool rwsplit_process_router_options(Config& 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
{
@ -157,7 +157,7 @@ static bool rwsplit_process_router_options(Config& config, char **options)
}
// TODO: Don't process parameters in readwritesplit
static bool handle_max_slaves(Config& config, const char *str)
static bool handle_max_slaves(SConfig config, const char *str)
{
bool rval = true;
char *endptr;
@ -165,13 +165,13 @@ static bool handle_max_slaves(Config& 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
{
@ -182,7 +182,7 @@ static bool handle_max_slaves(Config& config, const char *str)
return rval;
}
RWSplit::RWSplit(SERVICE* service, const Config& config):
RWSplit::RWSplit(SERVICE* service, SConfig config):
mxs::Router<RWSplit, RWSplitSession>(service),
m_service(service),
m_config(config)
@ -198,8 +198,9 @@ SERVICE* RWSplit::service() const
return m_service;
}
const Config& RWSplit::config() const
SConfig RWSplit::config() const
{
ss_dassert(m_config);
return m_config;
}
@ -215,9 +216,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));
}
@ -227,8 +228,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)
@ -241,15 +242,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)
{
@ -258,7 +259,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;
@ -274,9 +275,8 @@ bool RWSplit::have_enough_servers() const
RWSplit* RWSplit::create(SERVICE *service, char **options)
{
MXS_CONFIG_PARAMETER* params = service->svc_config_param;
Config config(params);
SConfig config(new Config(params));
if (!handle_max_slaves(config, config_get_string(params, "max_slave_connections")) ||
(options && !rwsplit_process_router_options(config, options)))
@ -285,25 +285,25 @@ RWSplit* RWSplit::create(SERVICE *service, char **options)
}
/** 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);
@ -320,40 +320,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();
dcb_printf(dcb, "\n");
dcb_printf(dcb, "\tuse_sql_variables_in: %s\n",
mxs_target_to_str(config().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(config().slave_selection_criteria));
select_criteria_to_str(cnf->slave_selection_criteria));
dcb_printf(dcb, "\tmaster_failure_mode: %s\n",
failure_mode_to_str(config().master_failure_mode));
failure_mode_to_str(cnf->master_failure_mode));
dcb_printf(dcb, "\tmax_slave_replication_lag: %d\n",
config().max_slave_replication_lag);
cnf->max_slave_replication_lag);
dcb_printf(dcb, "\tretry_failed_reads: %s\n",
config().retry_failed_reads ? "true" : "false");
cnf->retry_failed_reads ? "true" : "false");
dcb_printf(dcb, "\tstrict_multi_stmt: %s\n",
config().strict_multi_stmt ? "true" : "false");
cnf->strict_multi_stmt ? "true" : "false");
dcb_printf(dcb, "\tstrict_sp_calls: %s\n",
config().strict_sp_calls ? "true" : "false");
cnf->strict_sp_calls ? "true" : "false");
dcb_printf(dcb, "\tdisable_sescmd_history: %s\n",
config().disable_sescmd_history ? "true" : "false");
cnf->disable_sescmd_history ? "true" : "false");
dcb_printf(dcb, "\tmax_sescmd_history: %lu\n",
config().max_sescmd_history);
cnf->max_sescmd_history);
dcb_printf(dcb, "\tmaster_accept_reads: %s\n",
config().master_accept_reads ? "true" : "false");
cnf->master_accept_reads ? "true" : "false");
dcb_printf(dcb, "\tconnection_keepalive: %d\n",
config().connection_keepalive);
cnf->connection_keepalive);
dcb_printf(dcb, "\tcausal_reads: %s\n",
config().causal_reads ? "true" : "false");
cnf->causal_reads ? "true" : "false");
dcb_printf(dcb, "\tcausal_reads_timeout: %s\n",
config().causal_reads_timeout.c_str());
cnf->causal_reads_timeout.c_str());
dcb_printf(dcb, "\tmaster_reconnection: %s\n",
config().master_reconnection ? "true" : "false");
cnf->master_reconnection ? "true" : "false");
dcb_printf(dcb, "\tdelayed_retry: %s\n",
config().delayed_retry ? "true" : "false");
cnf->delayed_retry ? "true" : "false");
dcb_printf(dcb, "\tdelayed_retry_timeout: %lu\n",
config().delayed_retry_timeout);
cnf->delayed_retry_timeout);
dcb_printf(dcb, "\n");

View File

@ -200,6 +200,8 @@ struct Config
bool optimistic_trx; /**< Enable optimistic transactions */
};
typedef std::tr1::shared_ptr<Config> SConfig;
/**
* The statistics for this router instance
*/
@ -226,11 +228,11 @@ class RWSplit: public mxs::Router<RWSplit, RWSplitSession>
RWSplit& operator=(const RWSplit&);
public:
RWSplit(SERVICE* service, const Config& config);
RWSplit(SERVICE* service, SConfig config);
~RWSplit();
SERVICE* service() const;
const Config& config() const;
SConfig config() const;
Stats& stats();
const Stats& stats() const;
int max_slave_count() const;
@ -298,7 +300,7 @@ public:
private:
SERVICE* m_service; /**< Service where the router belongs*/
Config m_config;
SConfig m_config;
Stats m_stats;
};

View File

@ -116,7 +116,7 @@ bool RWSplitSession::handle_target_is_all(route_target_t route_target, GWBUF *qu
{
// TODO: Append to the already stored session command instead of disabling history
MXS_INFO("Large session write, have to disable session command history");
m_config.disable_sescmd_history = true;
m_config->disable_sescmd_history = true;
continue_large_session_write(querybuf, qtype);
result = true;

View File

@ -84,7 +84,7 @@ void RWSplitSession::handle_connection_keepalive(SRWBackend& target)
ss_dassert(target);
ss_debug(int nserv = 0);
/** Each heartbeat is 1/10th of a second */
int keepalive = m_config.connection_keepalive * 10;
int keepalive = m_config->connection_keepalive * 10;
for (auto it = m_backends.begin(); it != m_backends.end(); it++)
{
@ -115,7 +115,7 @@ bool RWSplitSession::prepare_target(SRWBackend& target, route_target_t route_tar
if (!target->in_use())
{
ss_dassert(target->can_connect() && can_recover_servers());
ss_dassert(!TARGET_IS_MASTER(route_target) || m_config.master_reconnection);
ss_dassert(!TARGET_IS_MASTER(route_target) || m_config->master_reconnection);
rval = target->connect(m_client->session, &m_sescmd_list);
MXS_INFO("Connected to '%s'", target->name());
@ -166,7 +166,7 @@ bool RWSplitSession::have_connected_slaves() const
bool RWSplitSession::should_try_trx_on_slave(route_target_t route_target) const
{
return m_config.optimistic_trx && // Optimistic transactions are enabled
return m_config->optimistic_trx && // Optimistic transactions are enabled
!is_locked_to_master() && // Not locked to master
!m_is_replay_active && // Not replaying a transaction
m_otrx_state == OTRX_INACTIVE && // Not yet in optimistic mode
@ -260,7 +260,7 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf)
}
// If delayed query retry is enabled, we need to store the current statement
bool store_stmt = m_config.delayed_retry;
bool store_stmt = m_config->delayed_retry;
if (m_qc.large_query())
{
@ -297,7 +297,7 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf)
{
succp = true;
if (m_config.retry_failed_reads &&
if (m_config->retry_failed_reads &&
(command == MXS_COM_QUERY || command == MXS_COM_STMT_EXECUTE))
{
// Only commands that can contain an SQL statement should be stored
@ -309,8 +309,8 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf)
{
succp = handle_master_is_target(&target);
if (!m_config.strict_multi_stmt &&
!m_config.strict_sp_calls &&
if (!m_config->strict_multi_stmt &&
!m_config->strict_sp_calls &&
m_target_node == m_current_master)
{
/** Reset the forced node as we're in relaxed multi-statement mode */
@ -363,7 +363,7 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf)
}
}
if (succp && m_router->config().connection_keepalive &&
if (succp && m_config->connection_keepalive &&
(TARGET_IS_SLAVE(route_target) || TARGET_IS_MASTER(route_target)))
{
handle_connection_keepalive(target);
@ -488,7 +488,7 @@ bool RWSplitSession::route_session_write(GWBUF *querybuf, uint8_t command, uint3
}
}
if (m_config.max_sescmd_history > 0 && m_sescmd_list.size() >= m_config.max_sescmd_history)
if (m_config->max_sescmd_history > 0 && m_sescmd_list.size() >= m_config->max_sescmd_history)
{
static bool warn_history_exceeded = true;
if (warn_history_exceeded)
@ -500,16 +500,16 @@ bool RWSplitSession::route_session_write(GWBUF *querybuf, uint8_t command, uint3
"command history, add `disable_sescmd_history=true` to "
"service '%s'. To increase the limit (currently %lu), add "
"`max_sescmd_history` to the same service and increase the value.",
m_router->service()->name, m_config.max_sescmd_history);
m_router->service()->name, m_config->max_sescmd_history);
warn_history_exceeded = false;
}
m_config.disable_sescmd_history = true;
m_config.max_sescmd_history = 0;
m_config->disable_sescmd_history = true;
m_config->max_sescmd_history = 0;
m_sescmd_list.clear();
}
if (m_config.disable_sescmd_history)
if (m_config->disable_sescmd_history)
{
/** Prune stored responses */
ResponseMap::iterator it = m_sescmd_responses.lower_bound(lowest_pos);
@ -596,7 +596,7 @@ SRWBackend RWSplitSession::get_slave_backend(int max_rlag)
}
else if (backend->in_use() || counts.second < m_router->max_slave_count())
{
if (!m_config.master_accept_reads && rval->is_master())
if (!m_config->master_accept_reads && rval->is_master())
{
// Pick slaves over masters with master_accept_reads=false
rval = backend;
@ -604,7 +604,7 @@ SRWBackend RWSplitSession::get_slave_backend(int max_rlag)
else
{
// Compare the two servers and pick the best one
rval = compare_backends(rval, backend, m_config.slave_selection_criteria);
rval = compare_backends(rval, backend, m_config->slave_selection_criteria);
}
}
}
@ -622,7 +622,7 @@ SRWBackend RWSplitSession::get_master_backend()
if (master)
{
if (master->in_use() || (m_config.master_reconnection && master->can_connect()))
if (master->in_use() || (m_config->master_reconnection && master->can_connect()))
{
if (master->is_master())
{
@ -696,9 +696,9 @@ int RWSplitSession::get_max_replication_lag()
int conf_max_rlag;
/** if there is no configured value, then longest possible int is used */
if (m_config.max_slave_replication_lag > 0)
if (m_config->max_slave_replication_lag > 0)
{
conf_max_rlag = m_config.max_slave_replication_lag;
conf_max_rlag = m_config->max_slave_replication_lag;
}
else
{
@ -878,7 +878,7 @@ void RWSplitSession::log_master_routing_failure(bool found,
else
{
/** We never had a master connection, the session must be in read-only mode */
if (m_config.master_failure_mode != RW_FAIL_INSTANTLY)
if (m_config->master_failure_mode != RW_FAIL_INSTANTLY)
{
sprintf(errmsg, "Session is in read-only mode because it was created "
"when no master was available");
@ -899,7 +899,7 @@ void RWSplitSession::log_master_routing_failure(bool found,
bool RWSplitSession::should_replace_master(SRWBackend& target)
{
return m_config.master_reconnection &&
return m_config->master_reconnection &&
// We have a target server and it's not the current master
target && target != m_current_master &&
// We are not inside a transaction (also checks for autocommit=1)
@ -946,7 +946,7 @@ bool RWSplitSession::handle_master_is_target(SRWBackend* dest)
{
succp = false;
/** The original master is not available, we can't route the write */
if (m_config.master_failure_mode == RW_ERROR_ON_WRITE)
if (m_config->master_failure_mode == RW_ERROR_ON_WRITE)
{
succp = send_readonly_error(m_client);
@ -955,8 +955,8 @@ bool RWSplitSession::handle_master_is_target(SRWBackend* dest)
m_current_master->close();
}
}
else if (!m_config.delayed_retry ||
m_retry_duration >= m_config.delayed_retry_timeout)
else if (!m_config->delayed_retry ||
m_retry_duration >= m_config->delayed_retry_timeout)
{
// Cannot retry the query, log a message that routing has failed
log_master_routing_failure(succp, m_current_master, target);
@ -993,7 +993,7 @@ GWBUF* RWSplitSession::add_prefix_wait_gtid(SERVER *server, GWBUF *origin)
GWBUF* rval = origin;
const char* wait_func = (server->server_type == SERVER_TYPE_MARIADB) ?
MARIADB_WAIT_GTID_FUNC : MYSQL_WAIT_GTID_FUNC;
const char *gtid_wait_timeout = m_router->config().causal_reads_timeout.c_str();
const char *gtid_wait_timeout = m_config->causal_reads_timeout.c_str();
const char *gtid_position = m_gtid_pos.c_str();
/* Create a new buffer to store prefix sql */
@ -1051,7 +1051,7 @@ bool RWSplitSession::handle_got_target(GWBUF* querybuf, SRWBackend& target, bool
uint8_t cmd = mxs_mysql_get_command(querybuf);
GWBUF *send_buf = gwbuf_clone(querybuf);
if (cmd == COM_QUERY && m_router->config().causal_reads && !m_gtid_pos .empty())
if (cmd == COM_QUERY && m_config->causal_reads && !m_gtid_pos .empty())
{
send_buf = add_prefix_wait_gtid(target->server(), send_buf);
m_wait_gtid = WAITING_FOR_HEADER;

View File

@ -301,15 +301,16 @@ bool RWSplit::select_connect_backend_servers(MXS_SESSION *session,
connection_type type)
{
SRWBackend master = get_root_master(backends);
SConfig cnf(config());
if (!master && config().master_failure_mode == RW_FAIL_INSTANTLY)
if (!master && cnf->master_failure_mode == RW_FAIL_INSTANTLY)
{
MXS_ERROR("Couldn't find suitable Master from %lu candidates.", backends.size());
return false;
}
/** Check slave selection criteria and set compare function */
select_criteria_t select_criteria = config().slave_selection_criteria;
select_criteria_t select_criteria = cnf->slave_selection_criteria;
auto cmpfun = criteria_cmpfun[select_criteria];
ss_dassert(cmpfun);

View File

@ -38,17 +38,17 @@ RWSplitSession::RWSplitSession(RWSplit* instance, MXS_SESSION* session,
m_gtid_pos(""),
m_wait_gtid(NONE),
m_next_seq(0),
m_qc(this, session, instance->config().use_sql_variables_in),
m_qc(this, session, m_config->use_sql_variables_in),
m_retry_duration(0),
m_is_replay_active(false),
m_can_replay_trx(true)
{
if (m_config.rw_max_slave_conn_percent)
if (m_config->rw_max_slave_conn_percent)
{
int n_conn = 0;
double pct = (double)m_config.rw_max_slave_conn_percent / 100.0;
double pct = (double)m_config->rw_max_slave_conn_percent / 100.0;
n_conn = MXS_MAX(floor((double)m_nbackends * pct), 1);
m_config.max_slave_connections = n_conn;
m_config->max_slave_connections = n_conn;
}
}
@ -350,7 +350,7 @@ static void log_unexpected_response(SRWBackend& backend, GWBUF* buffer, GWBUF* c
GWBUF* RWSplitSession::handle_causal_read_reply(GWBUF *writebuf, SRWBackend& backend)
{
if (m_config.causal_reads)
if (m_config->causal_reads)
{
if (GWBUF_IS_REPLY_OK(writebuf) && backend == m_current_master)
{
@ -473,7 +473,7 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb)
poll_fake_hangup_event(backend_dcb);
}
}
else if (m_config.transaction_replay && m_can_replay_trx &&
else if (m_config->transaction_replay && m_can_replay_trx &&
session_trx_is_active(m_client->session))
{
if (!backend->has_session_commands())
@ -491,7 +491,7 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb)
size_t size{m_trx.size() + m_current_query.length()};
// A transaction is open and it is eligible for replaying
if (size < m_config.trx_max_size)
if (size < m_config->trx_max_size)
{
/** Transaction size is OK, store the statement for replaying and
* update the checksum of the result */
@ -524,7 +524,7 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb)
ss_dassert(backend->get_reply_state() == REPLY_STATE_DONE);
MXS_INFO("Reply complete, last reply from %s", backend->name());
if (m_config.causal_reads)
if (m_config->causal_reads)
{
// The reply should never be complete while we are still waiting for the header.
ss_dassert(m_wait_gtid != WAITING_FOR_HEADER);
@ -560,7 +560,7 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb)
}
else if (m_is_replay_active)
{
ss_dassert(m_config.transaction_replay);
ss_dassert(m_config->transaction_replay);
handle_trx_replay();
/**
@ -582,7 +582,7 @@ void RWSplitSession::clientReply(GWBUF *writebuf, DCB *backend_dcb)
return;
}
}
else if (m_config.transaction_replay && session_trx_is_ending(m_client->session))
else if (m_config->transaction_replay && session_trx_is_ending(m_client->session))
{
m_trx.close();
m_can_replay_trx = true;
@ -638,7 +638,7 @@ bool RWSplitSession::start_trx_replay()
{
bool rval = false;
if (!m_is_replay_active && m_config.transaction_replay && m_can_replay_trx)
if (!m_is_replay_active && m_config->transaction_replay && m_can_replay_trx)
{
if (m_trx.have_stmts() || m_current_query.get())
{
@ -736,7 +736,7 @@ void RWSplitSession::handleError(GWBUF *errmsgbuf, DCB *problem_dcb,
* can't be sure whether it was executed or not. In this
* case the safest thing to do is to close the client
* connection. */
if (m_config.master_failure_mode != RW_FAIL_INSTANTLY)
if (m_config->master_failure_mode != RW_FAIL_INSTANTLY)
{
can_continue = true;
}
@ -752,7 +752,7 @@ void RWSplitSession::handleError(GWBUF *errmsgbuf, DCB *problem_dcb,
can_continue = true;
retry_query(m_current_query.release());
}
else if (m_config.master_failure_mode == RW_ERROR_ON_WRITE)
else if (m_config->master_failure_mode == RW_ERROR_ON_WRITE)
{
/** In error_on_write mode, the session can continue even
* if the master is lost. Send a read-only error to
@ -865,7 +865,7 @@ bool RWSplitSession::handle_error_new_connection(DCB *backend_dcb, GWBUF *errmsg
*/
GWBUF *stored = m_current_query.release();
if (stored && m_config.retry_failed_reads)
if (stored && m_config->retry_failed_reads)
{
MXS_INFO("Re-routing failed read after server '%s' failed", backend->name());
retry_query(stored, 0);
@ -905,7 +905,7 @@ bool RWSplitSession::handle_error_new_connection(DCB *backend_dcb, GWBUF *errmsg
* Try to get replacement slave or at least the minimum
* number of slave connections for router session.
*/
if (m_recv_sescmd > 0 && m_config.disable_sescmd_history)
if (m_recv_sescmd > 0 && m_config->disable_sescmd_history)
{
succp = m_router->have_enough_servers();
}

View File

@ -132,7 +132,7 @@ public:
mxs::SRWBackend m_current_master; /**< Current master server */
mxs::SRWBackend m_target_node; /**< The currently locked target node */
mxs::SRWBackend m_prev_target; /**< The previous target where a query was sent */
Config m_config; /**< copied config info from router instance */
SConfig m_config; /**< Configuration for this session */
int m_nbackends; /**< Number of backend servers (obsolete) */
DCB* m_client; /**< The client DCB */
uint64_t m_sescmd_count; /**< Number of executed session commands */
@ -249,14 +249,14 @@ private:
*
* @see handle_trx_replay
*/
return m_config.delayed_retry &&
m_retry_duration < m_config.delayed_retry_timeout &&
return m_config->delayed_retry &&
m_retry_duration < m_config->delayed_retry_timeout &&
!session_trx_is_active(m_client->session);
}
inline bool can_recover_servers() const
{
return !m_config.disable_sescmd_history || m_recv_sescmd == 0;
return !m_config->disable_sescmd_history || m_recv_sescmd == 0;
}
inline bool is_large_query(GWBUF* buf)