MXS-1625 Move RouteInfo to QueryClassifier

This commit is contained in:
Johan Wikman 2018-04-10 15:09:52 +03:00
parent 91b1ce39b8
commit 9be98df41c
7 changed files with 148 additions and 73 deletions

View File

@ -30,6 +30,70 @@ class QueryClassifier
QueryClassifier& operator = (const QueryClassifier&) = delete;
public:
class RouteInfo
{
public:
RouteInfo();
void reset();
uint32_t target() const
{
return m_target;
}
uint8_t command() const
{
return m_command;
}
uint32_t type_mask() const
{
return m_type_mask;
}
uint32_t stmt_id() const
{
return m_stmt_id;
}
void set_command(uint8_t c)
{
m_command = c;
}
void set_target(uint32_t t)
{
m_target = t;
}
void or_target(uint32_t t)
{
m_target |= t;
}
void set_type_mask(uint32_t t)
{
m_type_mask = t;
}
void or_type_mask(uint32_t t)
{
m_type_mask |= t;
}
void set_stmt_id(uint32_t stmt_id)
{
m_stmt_id = stmt_id;
}
private:
uint32_t m_target; /**< Route target type, TARGET_UNDEFINED for unknown */
uint8_t m_command; /**< The command byte, 0xff for unknown commands */
uint32_t m_type_mask; /**< The query type, QUERY_TYPE_UNKNOWN for unknown types*/
uint32_t m_stmt_id; /**< Prepared statement ID, 0 for unknown */
};
class Handler
{
public:
@ -97,6 +161,17 @@ public:
MXS_SESSION* pSession,
mxs_target_t use_sql_variables_in);
/**
* @brief Return the current route info. A call to update_route_info()
* will change the values.
*
* @return The current RouteInfo.
*/
const RouteInfo& current_route_info()
{
return m_route_info;
}
void master_replaced()
{
// As the master has changed, we can reset the temporary table information
@ -141,11 +216,15 @@ public:
*/
void ps_id_internal_put(uint32_t external_id, uint32_t internal_id);
uint32_t get_target_type(QueryClassifier::current_target_t current_target,
GWBUF *buffer,
uint8_t* command,
uint32_t* type,
uint32_t* stmt_id);
/**
* @brief Update the current RouteInfo.
*
* @param current_target What the current target is.
* @param pBuffer A request buffer.
*
* @return A copy of the current route info.
*/
RouteInfo update_route_info(QueryClassifier::current_target_t current_target, GWBUF* pBuffer);
private:
bool multi_statements_allowed() const
@ -251,6 +330,12 @@ private:
uint8_t packet_type,
uint32_t *qtype);
uint32_t get_target_type(QueryClassifier::current_target_t current_target,
GWBUF *buffer,
uint8_t* command,
uint32_t* type,
uint32_t* stmt_id);
private:
class PSManager;
typedef std::shared_ptr<PSManager> SPSManager;
@ -273,6 +358,7 @@ private:
bool m_multi_statements_allowed; /**< Are multi-statements allowed */
SPSManager m_sPs_manager;
HandleMap m_ps_handles; /** External ID to internal ID */
RouteInfo m_route_info;
};
}

View File

@ -177,6 +177,22 @@ bool foreach_table(QueryClassifier& qc,
namespace maxscale
{
QueryClassifier::RouteInfo::RouteInfo()
: m_target(QueryClassifier::TARGET_UNDEFINED)
, m_command(0xff)
, m_type_mask(QUERY_TYPE_UNKNOWN)
, m_stmt_id(0)
{
}
void QueryClassifier::RouteInfo::reset()
{
m_target = QueryClassifier::TARGET_UNDEFINED;
m_command = 0xff;
m_type_mask = QUERY_TYPE_UNKNOWN;
m_stmt_id = 0;
}
class QueryClassifier::PSManager
{
PSManager(const PSManager&) = delete;
@ -809,6 +825,24 @@ QueryClassifier::handle_multi_temp_and_load(QueryClassifier::current_target_t cu
return rv;
}
QueryClassifier::RouteInfo
QueryClassifier::update_route_info(QueryClassifier::current_target_t current_target, GWBUF* pBuffer)
{
uint8_t command;
uint32_t type_mask;
uint32_t stmt_id;
uint32_t target = get_target_type(current_target, pBuffer, &command, &type_mask, &stmt_id);
m_route_info.reset();
m_route_info.set_target(target);
m_route_info.set_command(command);
m_route_info.set_type_mask(type_mask);
m_route_info.set_stmt_id(stmt_id);
return m_route_info;
}
uint32_t QueryClassifier::get_target_type(QueryClassifier::current_target_t current_target,
GWBUF *buffer,
uint8_t* command,

View File

@ -1,6 +1,5 @@
add_library(readwritesplit SHARED
readwritesplit.cc
routeinfo.cc
rwsplitsession.cc
rwsplit_mysql.cc
rwsplit_route_stmt.cc

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include "routeinfo.hh"
#include <maxscale/queryclassifier.hh>
#include "rwsplitsession.hh"
using namespace maxscale;
RouteInfo::RouteInfo(RWSplitSession* rses, GWBUF* buffer)
: target(RWSplitSession::TARGET_UNDEFINED)
, command(0xff)
, type(QUERY_TYPE_UNKNOWN)
, stmt_id(0)
{
ss_dassert(rses);
ss_dassert(rses->m_client);
ss_dassert(rses->m_client->data);
ss_dassert(buffer);
QueryClassifier::current_target_t current_target;
if (rses->m_target_node == NULL)
{
current_target = QueryClassifier::CURRENT_TARGET_UNDEFINED;
}
else if (rses->m_target_node == rses->m_current_master)
{
current_target = QueryClassifier::CURRENT_TARGET_MASTER;
}
else
{
current_target = QueryClassifier::CURRENT_TARGET_SLAVE;
}
target = static_cast<route_target_t>(rses->qc().get_target_type(current_target,
buffer,
&command,
&type,
&stmt_id));
}

View File

@ -13,15 +13,6 @@
*/
#include "readwritesplit.hh"
#include <maxscale/queryclassifier.hh>
class RWSplitSession;
struct RouteInfo
{
RouteInfo(RWSplitSession* rses, GWBUF* buffer);
route_target_t target; /**< Route target type, TARGET_UNDEFINED for unknown */
uint8_t command; /**< The command byte, 0xff for unknown commands */
uint32_t type; /**< The query type, QUERY_TYPE_UNKNOWN for unknown types*/
uint32_t stmt_id; /**< Prepared statement ID, 0 for unknown */
};
typedef maxscale::QueryClassifier::RouteInfo RouteInfo;

View File

@ -150,10 +150,10 @@ void RWSplitSession::retry_query(GWBUF* querybuf)
bool RWSplitSession::route_single_stmt(GWBUF *querybuf, const RouteInfo& info)
{
bool succp = false;
uint32_t stmt_id = info.stmt_id;
uint8_t command = info.command;
uint32_t qtype = info.type;
route_target_t route_target = info.target;
uint32_t stmt_id = info.stmt_id();
uint8_t command = info.command();
uint32_t qtype = info.type_mask();
route_target_t route_target = info.target();
bool not_locked_to_master = !is_locked_to_master();
if (not_locked_to_master && mxs_mysql_is_ps_command(command))

View File

@ -122,7 +122,23 @@ int32_t RWSplitSession::routeQuery(GWBUF* querybuf)
m_qc.large_query()))
{
/** Gather the information required to make routing decisions */
RouteInfo info(this, querybuf);
QueryClassifier::current_target_t current_target;
if (m_target_node == NULL)
{
current_target = QueryClassifier::CURRENT_TARGET_UNDEFINED;
}
else if (m_target_node == m_current_master)
{
current_target = QueryClassifier::CURRENT_TARGET_MASTER;
}
else
{
current_target = QueryClassifier::CURRENT_TARGET_SLAVE;
}
RouteInfo info = m_qc.update_route_info(current_target, querybuf);
/** No active or pending queries */
if (route_single_stmt(querybuf, info))