Merge branch '2.3' into develop
This commit is contained in:
@ -277,6 +277,11 @@ bool RWSplitSession::route_single_stmt(GWBUF* querybuf)
|
||||
}
|
||||
else if (TARGET_IS_MASTER(route_target))
|
||||
{
|
||||
if (m_config.causal_reads)
|
||||
{
|
||||
gwbuf_set_type(querybuf, GWBUF_TYPE_TRACK_STATE);
|
||||
}
|
||||
|
||||
succp = handle_master_is_target(&target);
|
||||
|
||||
if (!succp && should_migrate_trx(target))
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <functional>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
|
||||
#include <maxbase/stopwatch.hh>
|
||||
#include <maxscale/router.hh>
|
||||
@ -193,6 +194,11 @@ BackendSelectFunction get_backend_select_function(select_criteria_t sc)
|
||||
return backend_cmp_current_load;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// Buffers for sorting the servers, thread_local to avoid repeated memory allocations
|
||||
thread_local std::array<PRWBackends, 3> priority_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the best slave candidate for routing reads.
|
||||
@ -208,7 +214,6 @@ PRWBackends::iterator find_best_backend(PRWBackends& backends,
|
||||
bool masters_accepts_reads)
|
||||
{
|
||||
// Group backends by priority. The set of highest priority backends will then compete.
|
||||
std::map<int, PRWBackends> priority_map;
|
||||
int best_priority {INT_MAX}; // low numbers are high priority
|
||||
|
||||
for (auto& psBackend : backends)
|
||||
@ -222,16 +227,16 @@ PRWBackends::iterator find_best_backend(PRWBackends& backends,
|
||||
{
|
||||
if (!is_busy)
|
||||
{
|
||||
priority = 1; // highest priority, idle servers
|
||||
priority = 0; // highest priority, idle servers
|
||||
}
|
||||
else
|
||||
{
|
||||
priority = 13; // lowest priority, busy servers
|
||||
priority = 2; // lowest priority, busy servers
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
priority = 2; // idle masters with masters_accept_reads==false
|
||||
priority = 1; // idle masters with masters_accept_reads==false
|
||||
}
|
||||
|
||||
priority_map[priority].push_back(psBackend);
|
||||
@ -239,8 +244,14 @@ PRWBackends::iterator find_best_backend(PRWBackends& backends,
|
||||
}
|
||||
|
||||
auto best = select(priority_map[best_priority]);
|
||||
auto rval = std::find(backends.begin(), backends.end(), *best);
|
||||
|
||||
return std::find(backends.begin(), backends.end(), *best);
|
||||
for (auto& a : priority_map)
|
||||
{
|
||||
a.clear();
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -563,6 +563,17 @@ static bool server_is_shutting_down(GWBUF* writebuf)
|
||||
return err == ER_SERVER_SHUTDOWN || err == ER_NORMAL_SHUTDOWN || err == ER_SHUTDOWN_COMPLETE;
|
||||
}
|
||||
|
||||
void RWSplitSession::close_stale_connections()
|
||||
{
|
||||
for (auto& backend : m_backends)
|
||||
{
|
||||
if (backend->in_use() && !backend->can_connect())
|
||||
{
|
||||
backend->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RWSplitSession::clientReply(GWBUF* writebuf, DCB* backend_dcb)
|
||||
{
|
||||
DCB* client_dcb = backend_dcb->session->client_dcb;
|
||||
@ -719,6 +730,15 @@ void RWSplitSession::clientReply(GWBUF* writebuf, DCB* backend_dcb)
|
||||
m_can_replay_trx = true;
|
||||
}
|
||||
|
||||
if (m_expected_responses == 0)
|
||||
{
|
||||
/**
|
||||
* Close stale connections to servers in maintenance. Done here to avoid closing the connections
|
||||
* before all responses have been received.
|
||||
*/
|
||||
close_stale_connections();
|
||||
}
|
||||
|
||||
if (backend->in_use() && backend->has_session_commands())
|
||||
{
|
||||
// Backend is still in use and has more session commands to execute
|
||||
|
@ -144,6 +144,7 @@ private:
|
||||
void continue_large_session_write(GWBUF* querybuf, uint32_t type);
|
||||
bool route_single_stmt(GWBUF* querybuf);
|
||||
bool route_stored_query();
|
||||
void close_stale_connections();
|
||||
|
||||
mxs::RWBackend* get_hinted_backend(char* name);
|
||||
mxs::RWBackend* get_slave_backend(int max_rlag);
|
||||
|
@ -1592,8 +1592,17 @@ bool SchemaRouterSession::send_tables(GWBUF* pPacket)
|
||||
|
||||
if (database.empty())
|
||||
{
|
||||
MXS_FREE(query);
|
||||
return false;
|
||||
// Was not a "show tables from x". If a current database is selected, use that as target.
|
||||
if (!m_current_db.empty())
|
||||
{
|
||||
database = m_current_db;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No current db, route the query to a server, likely getting "No database selected"
|
||||
MXS_FREE(query);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ServerMap tablelist;
|
||||
|
Reference in New Issue
Block a user