Merge branch '2.3' into develop

This commit is contained in:
Esa Korhonen
2019-04-30 12:06:06 +03:00
11 changed files with 212 additions and 92 deletions

View File

@ -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;
}

View File

@ -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());

View File

@ -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,