Replaced the use of the shared MySQLSession structure with an internal variable
that tracks the currently active database.
This commit is contained in:
Markus Makela
2015-10-29 20:24:26 +02:00
parent 18c53bebf1
commit d5c38b93f6
6 changed files with 27 additions and 56 deletions

View File

@ -323,6 +323,7 @@ struct router_client_session {
struct router_client_session* next; /*< List of router sessions */ struct router_client_session* next; /*< List of router sessions */
shard_map_t* shardmap; /*< Database hash containing names of the databases mapped to the servers that contain them */ shard_map_t* shardmap; /*< Database hash containing names of the databases mapped to the servers that contain them */
char connect_db[MYSQL_DATABASE_MAXLEN+1]; /*< Database the user was trying to connect to */ char connect_db[MYSQL_DATABASE_MAXLEN+1]; /*< Database the user was trying to connect to */
char current_db[MYSQL_DATABASE_MAXLEN + 1]; /*< Current active database */
init_mask_t init; /*< Initialization state bitmask */ init_mask_t init; /*< Initialization state bitmask */
GWBUF* queue; /*< Query that was received before the session was ready */ GWBUF* queue; /*< Query that was received before the session was ready */
DCB* dcb_route; /*< Internal DCB used to trigger re-routing of buffers */ DCB* dcb_route; /*< Internal DCB used to trigger re-routing of buffers */

View File

@ -12,8 +12,6 @@
bool extract_database(GWBUF* buf, char* str); bool extract_database(GWBUF* buf, char* str);
void create_error_reply(char* fail_str,DCB* dcb); void create_error_reply(char* fail_str,DCB* dcb);
bool change_current_db(MYSQL_session* mysql_session, bool change_current_db(char* dest, HASHTABLE* dbhash, GWBUF* buf);
HASHTABLE* dbhash,
GWBUF* buf);
#endif #endif

View File

@ -204,6 +204,7 @@ struct router_client_session {
SESSION* session; SESSION* session;
GWBUF* queue; GWBUF* queue;
char connect_db[MYSQL_DATABASE_MAXLEN+1]; /*< Database the user was trying to connect to */ char connect_db[MYSQL_DATABASE_MAXLEN+1]; /*< Database the user was trying to connect to */
char current_db[MYSQL_DATABASE_MAXLEN + 1]; /*< Current active database */
shard_init_mask_t init; /*< Initialization state bitmask */ shard_init_mask_t init; /*< Initialization state bitmask */
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
skygw_chk_t rses_chk_tail; skygw_chk_t rses_chk_tail;

View File

@ -583,9 +583,9 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client,
if(tmp == NULL) if(tmp == NULL)
{ {
rval = (char*) hashtable_fetch(ht, client->rses_mysql_session->db); rval = (char*) hashtable_fetch(ht, client->current_db);
skygw_log_write(LOGFILE_TRACE,"schemarouter: SHOW TABLES query, current database '%s' on server '%s'", skygw_log_write(LOGFILE_TRACE,"schemarouter: SHOW TABLES query, current database '%s' on server '%s'",
client->rses_mysql_session->db,rval); client->current_db,rval);
} }
else else
{ {
@ -613,17 +613,17 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client,
} }
} }
if(rval == NULL && !has_dbs && client->rses_mysql_session->db[0] != '\0') if(rval == NULL && !has_dbs && client->current_db[0] != '\0')
{ {
/** /**
* If the target name has not been found and the session has an * If the target name has not been found and the session has an
* active database, set is as the target * active database, set is as the target
*/ */
rval = (char*) hashtable_fetch(ht, client->rses_mysql_session->db); rval = (char*) hashtable_fetch(ht, client->current_db);
if(rval) if(rval)
{ {
skygw_log_write(LOGFILE_TRACE,"schemarouter: Using active database '%s'",client->rses_mysql_session->db); skygw_log_write(LOGFILE_TRACE,"schemarouter: Using active database '%s'",client->current_db);
} }
} }
@ -1585,7 +1585,7 @@ ROUTER* instance,
rses_property_t* rses_prop_tmp; rses_property_t* rses_prop_tmp;
rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES];
dbname = router_cli_ses->rses_mysql_session->db; dbname = router_cli_ses->current_db;
if (is_drop_table_query(querybuf)) if (is_drop_table_query(querybuf))
{ {
@ -1643,7 +1643,7 @@ ROUTER* instance,
rses_property_t* rses_prop_tmp; rses_property_t* rses_prop_tmp;
rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES];
dbname = router_cli_ses->rses_mysql_session->db; dbname = router_cli_ses->current_db;
if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) || if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_LOCAL_READ) || QUERY_IS_TYPE(qtype, QUERY_TYPE_LOCAL_READ) ||
@ -1722,7 +1722,7 @@ void check_create_tmp_table(
HASHTABLE* h; HASHTABLE* h;
rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES];
dbname = router_cli_ses->rses_mysql_session->db; dbname = router_cli_ses->current_db;
if (QUERY_IS_TYPE(type, QUERY_TYPE_CREATE_TMP_TABLE)) if (QUERY_IS_TYPE(type, QUERY_TYPE_CREATE_TMP_TABLE))
@ -2248,7 +2248,7 @@ static int routeQuery(
op == QUERY_OP_CHANGE_DB) op == QUERY_OP_CHANGE_DB)
{ {
spinlock_acquire(&router_cli_ses->shardmap->lock); spinlock_acquire(&router_cli_ses->shardmap->lock);
change_successful = change_current_db(router_cli_ses->rses_mysql_session, change_successful = change_current_db(router_cli_ses->current_db,
router_cli_ses->shardmap->hash, router_cli_ses->shardmap->hash,
querybuf); querybuf);
spinlock_release(&router_cli_ses->shardmap->lock); spinlock_release(&router_cli_ses->shardmap->lock);
@ -2259,6 +2259,10 @@ static int routeQuery(
difftime(now,router_cli_ses->rses_config.last_refresh) > difftime(now,router_cli_ses->rses_config.last_refresh) >
router_cli_ses->rses_config.refresh_min_interval) router_cli_ses->rses_config.refresh_min_interval)
{ {
spinlock_acquire(&router_cli_ses->shardmap->lock);
router_cli_ses->shardmap->state = SHMAP_STALE;
spinlock_release(&router_cli_ses->shardmap->lock);
rses_begin_locked_router_action(router_cli_ses); rses_begin_locked_router_action(router_cli_ses);
router_cli_ses->rses_config.last_refresh = now; router_cli_ses->rses_config.last_refresh = now;
@ -2319,13 +2323,13 @@ static int routeQuery(
route_target = TARGET_UNDEFINED; route_target = TARGET_UNDEFINED;
spinlock_acquire(&router_cli_ses->shardmap->lock); spinlock_acquire(&router_cli_ses->shardmap->lock);
tname = hashtable_fetch(router_cli_ses->shardmap->hash,router_cli_ses->rses_mysql_session->db); tname = hashtable_fetch(router_cli_ses->shardmap->hash,router_cli_ses->current_db);
spinlock_release(&router_cli_ses->shardmap->lock); spinlock_release(&router_cli_ses->shardmap->lock);
if(tname) if(tname)
{ {
skygw_log_write(LOGFILE_TRACE,"schemarouter: INIT_DB for database '%s' on server '%s'", skygw_log_write(LOGFILE_TRACE,"schemarouter: INIT_DB for database '%s' on server '%s'",
router_cli_ses->rses_mysql_session->db,tname); router_cli_ses->current_db,tname);
route_target = TARGET_NAMED_SERVER; route_target = TARGET_NAMED_SERVER;
} }
else else
@ -2361,9 +2365,9 @@ static int routeQuery(
if( (tname == NULL && if( (tname == NULL &&
packet_type != MYSQL_COM_INIT_DB && packet_type != MYSQL_COM_INIT_DB &&
router_cli_ses->rses_mysql_session->db[0] == '\0') || router_cli_ses->current_db[0] == '\0') ||
packet_type == MYSQL_COM_FIELD_LIST || packet_type == MYSQL_COM_FIELD_LIST ||
(router_cli_ses->rses_mysql_session->db[0] != '\0')) (router_cli_ses->current_db[0] != '\0'))
{ {
/** /**
* No current database and no databases in query or * No current database and no databases in query or
@ -2806,7 +2810,7 @@ static void clientReply(ROUTER* instance,
router_cli_ses->connect_db, router_cli_ses->connect_db,
router_cli_ses->rses_client_dcb->session); router_cli_ses->rses_client_dcb->session);
router_cli_ses->init &= ~INIT_USE_DB; router_cli_ses->init &= ~INIT_USE_DB;
strcpy(router_cli_ses->rses_mysql_session->db, router_cli_ses->connect_db); strcpy(router_cli_ses->current_db, router_cli_ses->connect_db);
ss_dassert(router_cli_ses->init == INIT_READY); ss_dassert(router_cli_ses->init == INIT_READY);
if (router_cli_ses->queue) if (router_cli_ses->queue)
@ -3728,22 +3732,6 @@ static bool execute_sescmd_in_backend(
sescmd_cursor_clone_querybuf(scur)); sescmd_cursor_clone_querybuf(scur));
break; break;
case MYSQL_COM_INIT_DB:
{
/**
* Record database name and store to session.
*/
GWBUF* tmpbuf;
MYSQL_session* data;
unsigned int qlen;
data = dcb->session->data;
tmpbuf = scur->scmd_cur_cmd->my_sescmd_buf;
qlen = MYSQL_GET_PACKET_LEN((unsigned char*)tmpbuf->start);
memset(data->db,0,MYSQL_DATABASE_MAXLEN+1);
strncpy(data->db,tmpbuf->start+5,qlen - 1);
}
/** Fallthrough */
case MYSQL_COM_QUERY: case MYSQL_COM_QUERY:
default: default:
/** /**

View File

@ -100,17 +100,17 @@ void create_error_reply(char* fail_str,DCB* dcb)
} }
/** /**
* Read new database name from MYSQL_COM_INIT_DB packet or a literal USE ... COM_QUERY packet, check that it exists * Read new database name from MYSQL_COM_INIT_DB packet or a literal USE ... COM_QUERY
* in the hashtable and copy its name to MYSQL_session. * packet, check that it exists in the hashtable and copy its name to MYSQL_session.
* *
* @param mysql_session The MySQL session structure * @param dest Destination where the database name will be written
* @param dbhash Hashtable containing valid databases * @param dbhash Hashtable containing valid databases
* @param buf Buffer containing the database change query * @param buf Buffer containing the database change query
* *
* @return true if new database is set, false if non-existent database was tried * @return true if new database is set, false if non-existent database was tried
* to be set * to be set
*/ */
bool change_current_db(MYSQL_session* mysql_session, bool change_current_db(char* dest,
HASHTABLE* dbhash, HASHTABLE* dbhash,
GWBUF* buf) GWBUF* buf)
{ {
@ -139,7 +139,7 @@ bool change_current_db(MYSQL_session* mysql_session,
} }
else else
{ {
strncpy(mysql_session->db,db,MYSQL_DATABASE_MAXLEN); strncpy(dest,db,MYSQL_DATABASE_MAXLEN);
skygw_log_write(LOGFILE_TRACE,"change_current_db: database is on server: '%s'.",target); skygw_log_write(LOGFILE_TRACE,"change_current_db: database is on server: '%s'.",target);
succp = true; succp = true;
goto retblock; goto retblock;

View File

@ -1698,7 +1698,7 @@ routeQuery(ROUTER* instance,
if(packet_type == MYSQL_COM_INIT_DB) if(packet_type == MYSQL_COM_INIT_DB)
{ {
if(!(change_successful = change_current_db(router_cli_ses->rses_mysql_session, if(!(change_successful = change_current_db(router_cli_ses->current_db,
router_cli_ses->dbhash, router_cli_ses->dbhash,
querybuf))) querybuf)))
{ {
@ -2471,23 +2471,6 @@ execute_sescmd_in_backend(SUBSERVICE* subsvc)
rc = SESSION_ROUTE_QUERY(subsvc->session,sescmd_cursor_clone_querybuf(scur)); rc = SESSION_ROUTE_QUERY(subsvc->session,sescmd_cursor_clone_querybuf(scur));
break; break;
case MYSQL_COM_INIT_DB:
{
/**
* Record database name and store to session.
*/
GWBUF* tmpbuf;
MYSQL_session* data;
unsigned int qlen;
data = subsvc->session->data;
tmpbuf = scur->scmd_cur_cmd->my_sescmd_buf;
qlen = MYSQL_GET_PACKET_LEN((unsigned char*) tmpbuf->start);
memset(data->db, 0, MYSQL_DATABASE_MAXLEN + 1);
strncpy(data->db, tmpbuf->start + 5, qlen - 1);
rc = SESSION_ROUTE_QUERY(subsvc->session,sescmd_cursor_clone_querybuf(scur));
}
/** Fallthrough */
case MYSQL_COM_QUERY: case MYSQL_COM_QUERY:
default: default:
/** /**