Merge branch '2.3' into develop
This commit is contained in:
@ -608,7 +608,7 @@ bool RWSplitSession::route_session_write(GWBUF* querybuf, uint8_t command, uint3
|
||||
return nsucc;
|
||||
}
|
||||
|
||||
RWBackend* RWSplitSession::get_hinted_backend(char* name)
|
||||
RWBackend* RWSplitSession::get_hinted_backend(const char* name)
|
||||
{
|
||||
RWBackend* rval = nullptr;
|
||||
|
||||
@ -669,15 +669,15 @@ RWBackend* RWSplitSession::get_last_used_backend()
|
||||
*
|
||||
* @param rses Pointer to router client session
|
||||
* @param btype Backend type
|
||||
* @param name Name of the backend which is primarily searched. May be NULL.
|
||||
* @param name Name of the requested backend. May be NULL if any name is accepted.
|
||||
* @param max_rlag Maximum replication lag
|
||||
* @param target The target backend
|
||||
*
|
||||
* @return True if a backend was found
|
||||
*/
|
||||
RWBackend* RWSplitSession::get_target_backend(backend_type_t btype,
|
||||
char* name,
|
||||
int max_rlag)
|
||||
const char* name,
|
||||
int max_rlag)
|
||||
{
|
||||
/** Check whether using target_node as target SLAVE */
|
||||
if (m_target_node && session_trx_is_read_only(m_client->session))
|
||||
@ -686,13 +686,11 @@ RWBackend* RWSplitSession::get_target_backend(backend_type_t btype,
|
||||
}
|
||||
|
||||
RWBackend* rval = nullptr;
|
||||
|
||||
if (name) /*< Choose backend by name from a hint */
|
||||
if (name)
|
||||
{
|
||||
btype = BE_SLAVE;
|
||||
// Choose backend by name from a hint
|
||||
rval = get_hinted_backend(name);
|
||||
}
|
||||
|
||||
else if (btype == BE_SLAVE)
|
||||
{
|
||||
rval = get_slave_backend(max_rlag);
|
||||
@ -701,7 +699,6 @@ RWBackend* RWSplitSession::get_target_backend(backend_type_t btype,
|
||||
{
|
||||
rval = get_master_backend();
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -738,80 +735,72 @@ int RWSplitSession::get_max_replication_lag()
|
||||
*/
|
||||
RWBackend* RWSplitSession::handle_hinted_target(GWBUF* querybuf, route_target_t route_target)
|
||||
{
|
||||
char* named_server = NULL;
|
||||
int rlag_max = SERVER::RLAG_UNDEFINED;
|
||||
const char rlag_hint_tag[] = "max_slave_replication_lag";
|
||||
const int comparelen = sizeof(rlag_hint_tag);
|
||||
int config_max_rlag = get_max_replication_lag(); // From router configuration.
|
||||
RWBackend* target = nullptr;
|
||||
|
||||
HINT* hint = querybuf->hint;
|
||||
|
||||
while (hint != NULL)
|
||||
for (HINT* hint = querybuf->hint; !target && hint; hint = hint->next)
|
||||
{
|
||||
if (hint->type == HINT_ROUTE_TO_NAMED_SERVER)
|
||||
{
|
||||
/**
|
||||
* Set the name of searched
|
||||
* backend server.
|
||||
*/
|
||||
named_server = (char*)hint->data;
|
||||
MXS_INFO("Hint: route to server '%s'", named_server);
|
||||
}
|
||||
else if (hint->type == HINT_PARAMETER
|
||||
&& (strncasecmp((char*)hint->data,
|
||||
"max_slave_replication_lag",
|
||||
strlen("max_slave_replication_lag")) == 0))
|
||||
{
|
||||
int val = (int)strtol((char*)hint->value, (char**)NULL, 10);
|
||||
|
||||
if (val != 0 || errno == 0)
|
||||
// Set the name of searched backend server.
|
||||
const char* named_server = (char*)hint->data;
|
||||
MXS_INFO("Hint: route to server '%s'.", named_server);
|
||||
target = get_target_backend(BE_UNDEFINED, named_server, config_max_rlag);
|
||||
if (!target)
|
||||
{
|
||||
/** Set max. acceptable replication lag value for backend srv */
|
||||
rlag_max = val;
|
||||
MXS_INFO("Hint: max_slave_replication_lag=%d", rlag_max);
|
||||
// Target may differ from the requested name if the routing target is locked, e.g. by a trx.
|
||||
// Target is null only if not locked and named server was not found or was invalid.
|
||||
if (mxb_log_is_priority_enabled(LOG_INFO))
|
||||
{
|
||||
std::string status;
|
||||
for (const auto& a : m_backends)
|
||||
{
|
||||
if (strcmp(a->server()->name(), named_server) == 0)
|
||||
{
|
||||
status = a->server()->status_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
MXS_INFO("Was supposed to route to named server %s but couldn't find the server in a "
|
||||
"suitable state. Server state: %s",
|
||||
named_server, !status.empty() ? status.c_str() : "Could not find server");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hint->type == HINT_PARAMETER
|
||||
&& (strncasecmp((char*)hint->data, rlag_hint_tag, comparelen) == 0))
|
||||
{
|
||||
const char* str_val = (char*)hint->value;
|
||||
int hint_max_rlag = (int)strtol(str_val, (char**)NULL, 10);
|
||||
if (hint_max_rlag != 0 || errno == 0)
|
||||
{
|
||||
MXS_INFO("Hint: %s=%d", rlag_hint_tag, hint_max_rlag);
|
||||
target = get_target_backend(BE_SLAVE, nullptr, hint_max_rlag);
|
||||
if (!target)
|
||||
{
|
||||
MXS_INFO("Was supposed to route to server with replication lag "
|
||||
"at most %d but couldn't find such a slave.", hint_max_rlag);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Hint: Could not parse value of %s: '%s' is not a valid number.",
|
||||
rlag_hint_tag, str_val);
|
||||
}
|
||||
}
|
||||
hint = hint->next;
|
||||
} /*< while */
|
||||
|
||||
if (rlag_max == SERVER::RLAG_UNDEFINED) /*< no rlag max hint, use config */
|
||||
{
|
||||
rlag_max = get_max_replication_lag();
|
||||
}
|
||||
|
||||
/** target may be master or slave */
|
||||
backend_type_t btype = route_target & TARGET_SLAVE ? BE_SLAVE : BE_MASTER;
|
||||
|
||||
/**
|
||||
* Search backend server by name or replication lag.
|
||||
* If it fails, then try to find valid slave or master.
|
||||
*/
|
||||
RWBackend* target = get_target_backend(btype, named_server, rlag_max);
|
||||
|
||||
if (!target)
|
||||
{
|
||||
if (TARGET_IS_NAMED_SERVER(route_target))
|
||||
{
|
||||
std::string status = "Could not find server";
|
||||
// If no target so far, pick any available. TODO: should this be error instead?
|
||||
// Erroring here is more appropriate when namedserverfilter allows setting multiple target types
|
||||
// e.g. target=server1,->slave
|
||||
|
||||
for (const auto& a : m_backends)
|
||||
{
|
||||
if (strcmp(a->server()->name(), named_server) == 0)
|
||||
{
|
||||
status = a->server()->status_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MXS_INFO("Was supposed to route to named server %s but couldn't find the server in a "
|
||||
"suitable state. Server state: %s", named_server, status.c_str());
|
||||
}
|
||||
else if (TARGET_IS_RLAG_MAX(route_target))
|
||||
{
|
||||
MXS_INFO("Was supposed to route to server with "
|
||||
"replication lag at most %d but couldn't "
|
||||
"find such a slave.",
|
||||
rlag_max);
|
||||
}
|
||||
backend_type_t btype = route_target & TARGET_SLAVE ? BE_SLAVE : BE_MASTER;
|
||||
target = get_target_backend(btype, NULL, config_max_rlag);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
@ -164,9 +164,10 @@ void RWSplitSession::process_sescmd_response(RWBackend* backend, GWBUF** ppPacke
|
||||
*ppPacket = NULL;
|
||||
}
|
||||
|
||||
if (m_expected_responses == 0
|
||||
if (m_expected_responses == 0 && !m_config.disable_sescmd_history
|
||||
&& (command == MXS_COM_CHANGE_USER || command == MXS_COM_RESET_CONNECTION))
|
||||
{
|
||||
mxb_assert_message(!m_sescmd_list.empty(), "Must have stored session commands");
|
||||
mxb_assert_message(m_slave_responses.empty(), "All responses should've been processed");
|
||||
// This is the last session command to finish that resets the session state, reset the history
|
||||
MXS_INFO("Resetting session command history (length: %lu)", m_sescmd_list.size());
|
||||
|
@ -146,11 +146,11 @@ private:
|
||||
void close_stale_connections();
|
||||
|
||||
int64_t get_current_rank();
|
||||
mxs::RWBackend* get_hinted_backend(char* name);
|
||||
mxs::RWBackend* get_hinted_backend(const char* name);
|
||||
mxs::RWBackend* get_slave_backend(int max_rlag);
|
||||
mxs::RWBackend* get_master_backend();
|
||||
mxs::RWBackend* get_last_used_backend();
|
||||
mxs::RWBackend* get_target_backend(backend_type_t btype, char* name, int max_rlag);
|
||||
mxs::RWBackend* get_target_backend(backend_type_t btype, const char* name, int max_rlag);
|
||||
|
||||
bool handle_target_is_all(route_target_t route_target,
|
||||
GWBUF* querybuf,
|
||||
|
Reference in New Issue
Block a user