MXS-2555 Beta Smart Router.

1. Remove persistence of performance data
2. Move global CanonicalPerformance into SmartRouter object
3. Implement another kill_all_others_v2. Left kill_all_others_v1
    in case it should be fixed and used instead.
This commit is contained in:
Niclas Antti
2019-06-13 13:43:30 +03:00
parent 1241300494
commit 6a7b6d4b89
6 changed files with 138 additions and 144 deletions

View File

@ -74,10 +74,11 @@ std::string extract_error(GWBUF* buffer)
return rval;
}
SmartRouterSession::SmartRouterSession(SmartRouter*,
SmartRouterSession::SmartRouterSession(SmartRouter* pRouter,
MXS_SESSION* pSession,
Clusters clusters)
: mxs::RouterSession(pSession)
, m_router(*pRouter)
, m_pClient_dcb(pSession->client_dcb)
, m_clusters(std::move(clusters))
, m_qc(this, pSession, TYPE_ALL)
@ -192,7 +193,7 @@ int SmartRouterSession::routeQuery(GWBUF* pBuf)
else
{
std::string canonical = maxscale::get_canonical(pBuf);
auto perf = perf_find(canonical);
auto perf = m_router.perf_find(canonical);
if (perf.is_valid())
{
@ -287,8 +288,10 @@ void SmartRouterSession::clientReply(GWBUF* pPacket, DCB* pDcb)
if (m_mode == Mode::MeasureQuery)
{
perf_update(m_measurement.canonical, {cluster.host, query_dur});
// kill_all_others(cluster.host);
m_router.perf_update(m_measurement.canonical, {cluster.host, query_dur});
// If the query is still going on, an error packet is received, else the
// whole query might play out (and be discarded).
kill_all_others_v2(cluster.host);
}
m_mode = Mode::CollectResults;
@ -435,7 +438,11 @@ bool SmartRouterSession::write_split_packets(GWBUF* pBuf)
return true; // TODO. What could possibly go wrong?
}
void SmartRouterSession::kill_all_others(const maxbase::Host& host)
/* TODO This should work much the way that kill_all_others_v2 works, but it does
* not. Something funky happens to the dcb/pipeline when this is used.
* Leaving it here, since it should be fixed.
*/
void SmartRouterSession::kill_all_others_v1(const maxbase::Host& host)
{
MySQLProtocol* pProt = static_cast<MySQLProtocol*>(m_pClient_dcb->protocol);
uint64_t mysql_thread_id = pProt->thread_id;
@ -452,6 +459,70 @@ void SmartRouterSession::kill_all_others(const maxbase::Host& host)
}
}
struct KillStruct
{
std::string user;
std::string password;
maxbase::Host host;
int mysql_thread_id;
};
using KillStructs = std::vector<KillStruct>;
void kill_thread(const KillStructs& kill_structs)
{
for (auto& ks : kill_structs)
{
auto conn = mysql_init(nullptr);
if (mysql_real_connect(conn, ks.host.address().c_str(),
ks.user.c_str(), ks.password.c_str(),
"", ks.host.port(), nullptr, 0) == nullptr)
{
MXS_SERROR("Trying to kill query on " << ks.host << " but failed to connect");
continue;
}
std::ostringstream os;
os << "kill query " << ks.mysql_thread_id;
auto sql = os.str();
MXS_SINFO("Sending '" << sql << "' to " << ks.host);
mysql_real_query(conn, sql.c_str(), sql.size());
auto err_code = mysql_errno(conn);
if (err_code)
{
MXS_SERROR("Failed to send kill err code=" << err_code);
}
}
}
void SmartRouterSession::kill_all_others_v2(const maxbase::Host& host)
{
MySQLProtocol* pProt = static_cast<MySQLProtocol*>(m_pClient_dcb->protocol);
int mysql_thread_id = pProt->thread_id;
KillStructs kill_structs;
for (Cluster& cluster : m_clusters)
{
if (cluster.host == host || !cluster.tracker.expecting_response_packets())
{
continue;
}
// TODO TODO: Where do the user and password come from? And also, open
// a permanent connection to each Cluster for killing.
std::string TODO_user = "maxscale";
std::string TODO_password = "pass";
kill_structs.push_back(KillStruct {TODO_user, TODO_password,
cluster.host, mysql_thread_id});
MXS_SDEBUG("Queue " << cluster.host << " mysql_thread_id=" << mysql_thread_id << " for kill");
}
if (!kill_structs.empty())
{
std::thread murderer {kill_thread, kill_structs};
murderer.detach();
}
}
void SmartRouterSession::handleError(GWBUF* pPacket,
DCB* pProblem,