MXS-1066 Add query hint to route to last used server

Add new hint type and support for it in the readwritesplit router.
This commit is contained in:
Marko 2018-07-09 11:07:33 +03:00
parent e2fb0093b1
commit 2acf5f545e
8 changed files with 37 additions and 1 deletions

View File

@ -31,6 +31,7 @@ typedef enum
HINT_ROUTE_TO_NAMED_SERVER,
HINT_ROUTE_TO_UPTODATE_SERVER, /*< not supported by RWSplit and HintRouter */
HINT_ROUTE_TO_ALL, /*< not supported by RWSplit, supported by HintRouter */
HINT_ROUTE_TO_LAST_USED,
HINT_PARAMETER
} HINT_TYPE;

View File

@ -117,7 +117,8 @@ public:
TARGET_SLAVE = 0x02,
TARGET_NAMED_SERVER = 0x04,
TARGET_ALL = 0x08,
TARGET_RLAG_MAX = 0x10
TARGET_RLAG_MAX = 0x10,
TARGET_LAST_USED = 0x20
};
static bool target_is_master(uint32_t t)
@ -145,6 +146,11 @@ public:
return (t & TARGET_RLAG_MAX);
}
static bool target_is_last_used(uint32_t t)
{
return (t & TARGET_LAST_USED);
}
enum current_target_t
{
CURRENT_TARGET_UNDEFINED, /**< Current target has not been set. */

View File

@ -530,6 +530,11 @@ uint32_t QueryClassifier::get_route_target(uint8_t command, uint32_t qtype, HINT
ss_dassert(false);
break;
case HINT_ROUTE_TO_LAST_USED:
MXS_DEBUG("Hint: route to last used");
target = TARGET_LAST_USED;
break;
case HINT_PARAMETER:
if (strncasecmp((char*)pHint->data, "max_slave_replication_lag",
strlen("max_slave_replication_lag")) == 0)

View File

@ -49,6 +49,7 @@ static struct
{ "master", TOK_MASTER},
{ "slave", TOK_SLAVE},
{ "server", TOK_SERVER},
{ "last" , TOK_LAST},
{ NULL, static_cast<TOKEN_VALUE>(0)}
};
@ -334,6 +335,12 @@ hint_parser(HINT_SESSION *session, GWBUF *request)
rval = hint_create_route(rval,
HINT_ROUTE_TO_SLAVE, NULL);
break;
case TOK_LAST:
rval = hint_create_route(rval,
HINT_ROUTE_TO_LAST_USED, NULL);
break;
case TOK_SERVER:
state = HS_ROUTE_SERVER;
break;

View File

@ -40,6 +40,7 @@ typedef enum
TOK_MASTER,
TOK_SLAVE,
TOK_SERVER,
TOK_LAST,
TOK_LINEBRK,
TOK_END
} TOKEN_VALUE;

View File

@ -281,6 +281,13 @@ bool RWSplitSession::route_single_stmt(GWBUF *querybuf)
succp = true;
}
}
else if (TARGET_IS_LAST_USED(route_target))
{
if ((target = get_last_used_backend()))
{
succp = true;
}
}
else if (TARGET_IS_SLAVE(route_target))
{
if ((target = handle_slave_is_target(command, stmt_id)))
@ -644,6 +651,11 @@ SRWBackend RWSplitSession::get_master_backend()
return rval;
}
SRWBackend RWSplitSession::get_last_used_backend()
{
return m_prev_target ? m_prev_target : get_master_backend();
}
/**
* Provide the router with a reference to a suitable backend
*

View File

@ -993,6 +993,7 @@ bool RWSplitSession::supports_hint(HINT_TYPE hint_type) const
case HINT_ROUTE_TO_MASTER:
case HINT_ROUTE_TO_SLAVE:
case HINT_ROUTE_TO_NAMED_SERVER:
case HINT_ROUTE_TO_LAST_USED:
case HINT_PARAMETER:
break;

View File

@ -27,6 +27,7 @@
#define TARGET_IS_NAMED_SERVER(t) maxscale::QueryClassifier::target_is_named_server(t)
#define TARGET_IS_ALL(t) maxscale::QueryClassifier::target_is_all(t)
#define TARGET_IS_RLAG_MAX(t) maxscale::QueryClassifier::target_is_rlag_max(t)
#define TARGET_IS_LAST_USED(t) maxscale::QueryClassifier::target_is_last_used(t)
typedef std::map<uint32_t, uint32_t> ClientHandleMap; /** External ID to internal ID */
@ -57,6 +58,7 @@ public:
TARGET_NAMED_SERVER = maxscale::QueryClassifier::TARGET_NAMED_SERVER,
TARGET_ALL = maxscale::QueryClassifier::TARGET_ALL,
TARGET_RLAG_MAX = maxscale::QueryClassifier::TARGET_RLAG_MAX,
TARGET_LAST_USED = maxscale::QueryClassifier::TARGET_LAST_USED,
};
enum otrx_state
@ -174,6 +176,7 @@ private:
mxs::SRWBackend get_hinted_backend(char *name);
mxs::SRWBackend get_slave_backend(int max_rlag);
mxs::SRWBackend get_master_backend();
mxs::SRWBackend get_last_used_backend();
mxs::SRWBackend get_target_backend(backend_type_t btype, char *name, int max_rlag);
bool handle_target_is_all(route_target_t route_target, GWBUF *querybuf,