MXS-1310: Route implicit table queries to the current shard
When a query that implicitly uses the current database is detected, it will be routed to the shard which has the current database.
This commit is contained in:
parent
374c204a04
commit
c6b579619a
@ -663,7 +663,8 @@ bool extract_database(GWBUF* buf, char* str)
|
||||
plen = gw_mysql_get_byte3(packet) - 1;
|
||||
|
||||
/** Copy database name from MySQL packet to session */
|
||||
if (qc_get_operation(buf) == QUERY_OP_CHANGE_DB)
|
||||
if (mxs_mysql_get_command(buf) == MYSQL_COM_QUERY &&
|
||||
qc_get_operation(buf) == QUERY_OP_CHANGE_DB)
|
||||
{
|
||||
const char *delim = "` \n\t;";
|
||||
|
||||
@ -1405,22 +1406,43 @@ SERVER* SchemaRouterSession::get_shard_target(GWBUF* buffer, uint32_t qtype)
|
||||
{
|
||||
SERVER *rval = NULL;
|
||||
bool has_dbs = false; /**If the query targets any database other than the current one*/
|
||||
const QC_FIELD_INFO* info;
|
||||
size_t n_info;
|
||||
|
||||
qc_get_field_info(buffer, &info, &n_info);
|
||||
|
||||
for (size_t i = 0; i < n_info; i++)
|
||||
if (mxs_mysql_get_command(buffer) == MYSQL_COM_QUERY)
|
||||
{
|
||||
if (info[i].database)
|
||||
bool uses_current_database = false;
|
||||
int n_tables = 0;
|
||||
char** tables = qc_get_table_names(buffer, &n_tables, true);
|
||||
|
||||
for (int i = 0; i < n_tables; i++)
|
||||
{
|
||||
if (strcmp(info[i].database, "information_schema") == 0 && rval == NULL)
|
||||
if (strchr(tables[i], '.') == NULL)
|
||||
{
|
||||
uses_current_database = true;
|
||||
}
|
||||
|
||||
MXS_FREE(tables[i]);
|
||||
}
|
||||
|
||||
MXS_FREE(tables);
|
||||
|
||||
if (uses_current_database)
|
||||
{
|
||||
MXS_INFO("Query uses current database");
|
||||
return m_shard.get_location(m_current_db);
|
||||
}
|
||||
|
||||
int n_databases = 0;
|
||||
char** databases = qc_get_database_names(buffer, &n_databases);
|
||||
|
||||
for (int i = 0; i < n_databases; i++)
|
||||
{
|
||||
if (strcasecmp(databases[i], "information_schema") == 0 && rval == NULL)
|
||||
{
|
||||
has_dbs = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SERVER* target = m_shard.get_location(info[i].database);
|
||||
SERVER* target = m_shard.get_location(databases[i]);
|
||||
|
||||
if (target)
|
||||
{
|
||||
@ -1435,15 +1457,18 @@ SERVER* SchemaRouterSession::get_shard_target(GWBUF* buffer, uint32_t qtype)
|
||||
rval = target;
|
||||
has_dbs = true;
|
||||
MXS_INFO("Query targets database '%s' on server '%s'",
|
||||
info[i].database, rval->unique_name);
|
||||
databases[i], rval->unique_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MXS_FREE(databases[i]);
|
||||
}
|
||||
|
||||
MXS_FREE(databases);
|
||||
}
|
||||
|
||||
/* Check if the query is a show tables query with a specific database */
|
||||
|
||||
if (qc_query_is_type(qtype, QUERY_TYPE_SHOW_TABLES))
|
||||
{
|
||||
char *query = modutil_get_SQL(buffer);
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include "shard_map.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <maxscale/alloc.h>
|
||||
|
||||
Shard::Shard():
|
||||
@ -26,12 +28,14 @@ Shard::~Shard()
|
||||
|
||||
bool Shard::add_location(std::string db, SERVER* target)
|
||||
{
|
||||
std::transform(db.begin(), db.end(), db.begin(), ::tolower);
|
||||
return m_map.insert(std::make_pair(db, target)).second;
|
||||
}
|
||||
|
||||
SERVER* Shard::get_location(std::string db)
|
||||
{
|
||||
SERVER* rval = NULL;
|
||||
std::transform(db.begin(), db.end(), db.begin(), ::tolower);
|
||||
ServerMap::iterator iter = m_map.find(db);
|
||||
|
||||
if (iter != m_map.end())
|
||||
|
Loading…
x
Reference in New Issue
Block a user