MXS-1625 Move RouteInfo to QueryClassifier
This commit is contained in:
@ -30,6 +30,70 @@ class QueryClassifier
|
|||||||
QueryClassifier& operator = (const QueryClassifier&) = delete;
|
QueryClassifier& operator = (const QueryClassifier&) = delete;
|
||||||
|
|
||||||
public:
|
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
|
class Handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -97,6 +161,17 @@ public:
|
|||||||
MXS_SESSION* pSession,
|
MXS_SESSION* pSession,
|
||||||
mxs_target_t use_sql_variables_in);
|
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()
|
void master_replaced()
|
||||||
{
|
{
|
||||||
// As the master has changed, we can reset the temporary table information
|
// 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);
|
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,
|
* @brief Update the current RouteInfo.
|
||||||
uint8_t* command,
|
*
|
||||||
uint32_t* type,
|
* @param current_target What the current target is.
|
||||||
uint32_t* stmt_id);
|
* @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:
|
private:
|
||||||
bool multi_statements_allowed() const
|
bool multi_statements_allowed() const
|
||||||
@ -251,6 +330,12 @@ private:
|
|||||||
uint8_t packet_type,
|
uint8_t packet_type,
|
||||||
uint32_t *qtype);
|
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:
|
private:
|
||||||
class PSManager;
|
class PSManager;
|
||||||
typedef std::shared_ptr<PSManager> SPSManager;
|
typedef std::shared_ptr<PSManager> SPSManager;
|
||||||
@ -273,6 +358,7 @@ private:
|
|||||||
bool m_multi_statements_allowed; /**< Are multi-statements allowed */
|
bool m_multi_statements_allowed; /**< Are multi-statements allowed */
|
||||||
SPSManager m_sPs_manager;
|
SPSManager m_sPs_manager;
|
||||||
HandleMap m_ps_handles; /** External ID to internal ID */
|
HandleMap m_ps_handles; /** External ID to internal ID */
|
||||||
|
RouteInfo m_route_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -177,6 +177,22 @@ bool foreach_table(QueryClassifier& qc,
|
|||||||
namespace maxscale
|
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
|
class QueryClassifier::PSManager
|
||||||
{
|
{
|
||||||
PSManager(const PSManager&) = delete;
|
PSManager(const PSManager&) = delete;
|
||||||
@ -809,6 +825,24 @@ QueryClassifier::handle_multi_temp_and_load(QueryClassifier::current_target_t cu
|
|||||||
return rv;
|
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,
|
uint32_t QueryClassifier::get_target_type(QueryClassifier::current_target_t current_target,
|
||||||
GWBUF *buffer,
|
GWBUF *buffer,
|
||||||
uint8_t* command,
|
uint8_t* command,
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
add_library(readwritesplit SHARED
|
add_library(readwritesplit SHARED
|
||||||
readwritesplit.cc
|
readwritesplit.cc
|
||||||
routeinfo.cc
|
|
||||||
rwsplitsession.cc
|
rwsplitsession.cc
|
||||||
rwsplit_mysql.cc
|
rwsplit_mysql.cc
|
||||||
rwsplit_route_stmt.cc
|
rwsplit_route_stmt.cc
|
||||||
|
|||||||
@ -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));
|
|
||||||
}
|
|
||||||
@ -13,15 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "readwritesplit.hh"
|
#include "readwritesplit.hh"
|
||||||
|
#include <maxscale/queryclassifier.hh>
|
||||||
|
|
||||||
class RWSplitSession;
|
typedef maxscale::QueryClassifier::RouteInfo RouteInfo;
|
||||||
|
|
||||||
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 */
|
|
||||||
};
|
|
||||||
|
|||||||
@ -150,10 +150,10 @@ void RWSplitSession::retry_query(GWBUF* querybuf)
|
|||||||
bool RWSplitSession::route_single_stmt(GWBUF *querybuf, const RouteInfo& info)
|
bool RWSplitSession::route_single_stmt(GWBUF *querybuf, const RouteInfo& info)
|
||||||
{
|
{
|
||||||
bool succp = false;
|
bool succp = false;
|
||||||
uint32_t stmt_id = info.stmt_id;
|
uint32_t stmt_id = info.stmt_id();
|
||||||
uint8_t command = info.command;
|
uint8_t command = info.command();
|
||||||
uint32_t qtype = info.type;
|
uint32_t qtype = info.type_mask();
|
||||||
route_target_t route_target = info.target;
|
route_target_t route_target = info.target();
|
||||||
bool not_locked_to_master = !is_locked_to_master();
|
bool not_locked_to_master = !is_locked_to_master();
|
||||||
|
|
||||||
if (not_locked_to_master && mxs_mysql_is_ps_command(command))
|
if (not_locked_to_master && mxs_mysql_is_ps_command(command))
|
||||||
|
|||||||
@ -122,7 +122,23 @@ int32_t RWSplitSession::routeQuery(GWBUF* querybuf)
|
|||||||
m_qc.large_query()))
|
m_qc.large_query()))
|
||||||
{
|
{
|
||||||
/** Gather the information required to make routing decisions */
|
/** 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 */
|
/** No active or pending queries */
|
||||||
if (route_single_stmt(querybuf, info))
|
if (route_single_stmt(querybuf, info))
|
||||||
|
|||||||
Reference in New Issue
Block a user