Fixed hashing function returning wrong values and added more logging.
This commit is contained in:
@ -41,12 +41,8 @@ MODULE_INFO info = {
|
|||||||
ROUTER_VERSION,
|
ROUTER_VERSION,
|
||||||
"A database sharding router for simple sharding"
|
"A database sharding router for simple sharding"
|
||||||
};
|
};
|
||||||
#if defined(SS_DEBUG)
|
|
||||||
# include <mysql_client_server_protocol.h>
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Defined in log_manager.cc */
|
/** Defined in log_manager.cc */
|
||||||
extern int lm_enabled_logfiles_bitmask;
|
extern int lm_enabled_logfiles_bitmask;
|
||||||
extern size_t log_ses_count[];
|
extern size_t log_ses_count[];
|
||||||
@ -246,12 +242,13 @@ static int hashkeyfun(void* key)
|
|||||||
if(key == NULL){
|
if(key == NULL){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned int hash = 0,c = 0;
|
int hash = 0,c = 0;
|
||||||
char* ptr = (char*)key;
|
char* ptr = (char*)key;
|
||||||
while((c = *ptr++)){
|
while((c = *ptr++)){
|
||||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
}
|
}
|
||||||
return *(int *)key;
|
|
||||||
|
return hash >= 0 ? hash:-hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hashcmpfun(
|
static int hashcmpfun(
|
||||||
@ -353,7 +350,7 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client,
|
|||||||
for(i = 0; i < sz; i++){
|
for(i = 0; i < sz; i++){
|
||||||
|
|
||||||
if((rval = (char*)hashtable_fetch(ht,dbnms[i]))){
|
if((rval = (char*)hashtable_fetch(ht,dbnms[i]))){
|
||||||
skygw_log_write(LOGFILE_TRACE,"dbshard: Query targets specific database (%s)",rval);
|
skygw_log_write(LOGFILE_TRACE,"dbshard: Query targets database '%s' on server '%s",dbnms[i],rval);
|
||||||
for(j = i;j < sz;j++) free(dbnms[j]);
|
for(j = i;j < sz;j++) free(dbnms[j]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -366,25 +363,31 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client,
|
|||||||
|
|
||||||
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_TABLES))
|
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_TABLES))
|
||||||
{
|
{
|
||||||
|
|
||||||
query = modutil_get_SQL(buffer);
|
query = modutil_get_SQL(buffer);
|
||||||
if((tmp = strstr(query,"from")))
|
if((tmp = strcasestr(query,"from")))
|
||||||
{
|
{
|
||||||
char* tok = strtok(tmp, " ;");
|
char* tok = strtok(tmp, " ;");
|
||||||
tok = strtok(NULL," ;");
|
tok = strtok(NULL," ;");
|
||||||
ss_dassert(tok != NULL);
|
ss_dassert(tok != NULL);
|
||||||
tmp = (char*) hashtable_fetch(ht, tok);
|
tmp = (char*) hashtable_fetch(ht, tok);
|
||||||
|
|
||||||
|
if(tmp)
|
||||||
|
skygw_log_write(LOGFILE_TRACE,"dbshard: SHOW TABLES with specific database '%s' on server '%s'", tok, tmp);
|
||||||
}
|
}
|
||||||
free(query);
|
free(query);
|
||||||
|
|
||||||
if(tmp == NULL)
|
if(tmp == NULL)
|
||||||
{
|
{
|
||||||
rval = (char*) hashtable_fetch(ht, client->rses_mysql_session->db);
|
rval = (char*) hashtable_fetch(ht, client->rses_mysql_session->db);
|
||||||
|
skygw_log_write(LOGFILE_TRACE,"dbshard: SHOW TABLES query, current database '%s' on server '%s'",
|
||||||
|
client->rses_mysql_session->db,rval);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rval = tmp;
|
rval = tmp;
|
||||||
has_dbs = true;
|
has_dbs = true;
|
||||||
skygw_log_write(LOGFILE_TRACE,"dbshard: SHOW TABLES with specific database (%s)", tmp);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return rval;
|
return rval;
|
||||||
@ -1535,8 +1538,6 @@ gen_show_dbs_response(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client)
|
|||||||
* In any tolerated failure, handleError is called and if necessary,
|
* In any tolerated failure, handleError is called and if necessary,
|
||||||
* an error message is sent to the client.
|
* an error message is sent to the client.
|
||||||
*
|
*
|
||||||
* For now, routeQuery don't tolerate errors, so any error will close
|
|
||||||
* the session. vraa 14.6.14
|
|
||||||
*/
|
*/
|
||||||
static int routeQuery(
|
static int routeQuery(
|
||||||
ROUTER* instance,
|
ROUTER* instance,
|
||||||
@ -1692,8 +1693,8 @@ static int routeQuery(
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Generate custom response that contains all the databases
|
* Generate custom response that contains all the databases
|
||||||
* after updating the hashtable
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
backend_ref_t* backend = NULL;
|
backend_ref_t* backend = NULL;
|
||||||
DCB* backend_dcb = NULL;
|
DCB* backend_dcb = NULL;
|
||||||
|
|
||||||
@ -3902,7 +3903,7 @@ static bool change_current_db(
|
|||||||
uint8_t* packet;
|
uint8_t* packet;
|
||||||
unsigned int plen;
|
unsigned int plen;
|
||||||
int message_len;
|
int message_len;
|
||||||
char* fail_str;
|
char* fail_str,*target;
|
||||||
|
|
||||||
if(GWBUF_LENGTH(buf) <= MYSQL_DATABASE_MAXLEN - 5)
|
if(GWBUF_LENGTH(buf) <= MYSQL_DATABASE_MAXLEN - 5)
|
||||||
{
|
{
|
||||||
@ -3913,15 +3914,18 @@ static bool change_current_db(
|
|||||||
|
|
||||||
memcpy(rses->rses_mysql_session->db,packet + 5,plen);
|
memcpy(rses->rses_mysql_session->db,packet + 5,plen);
|
||||||
memset(rses->rses_mysql_session->db + plen,0,1);
|
memset(rses->rses_mysql_session->db + plen,0,1);
|
||||||
|
|
||||||
|
skygw_log_write(LOGFILE_TRACE,"dbshard: INIT_DB with database '%s'",
|
||||||
|
rses->rses_mysql_session->db);
|
||||||
/**
|
/**
|
||||||
* Update the session's active database only if it's in the hashtable.
|
* Update the session's active database only if it's in the hashtable.
|
||||||
* If it isn't found, send a custom error packet to the client.
|
* If it isn't found, send a custom error packet to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
if(hashtable_fetch(
|
if((target = (char*)hashtable_fetch(
|
||||||
rses->dbhash,
|
rses->dbhash,
|
||||||
(char*)rses->rses_mysql_session->db) == NULL)
|
(char*)rses->rses_mysql_session->db)) == NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Create error message */
|
/** Create error message */
|
||||||
@ -3937,6 +3941,7 @@ static bool change_current_db(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
skygw_log_write(LOGFILE_TRACE,"dbshard: database is on server: '%s'.",target);
|
||||||
succp = true;
|
succp = true;
|
||||||
goto retblock;
|
goto retblock;
|
||||||
}
|
}
|
||||||
@ -3944,6 +3949,10 @@ static bool change_current_db(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/** Create error message */
|
/** Create error message */
|
||||||
|
skygw_log_write_flush(LOGFILE_ERROR,
|
||||||
|
"dbshard: failed to change database: Query buffer too large");
|
||||||
|
skygw_log_write_flush(LOGFILE_TRACE,
|
||||||
|
"dbshard: failed to change database: Query buffer too large [%d bytes]",GWBUF_LENGTH(buf));
|
||||||
message_len = 25 + MYSQL_DATABASE_MAXLEN;
|
message_len = 25 + MYSQL_DATABASE_MAXLEN;
|
||||||
fail_str = calloc(1, message_len+1);
|
fail_str = calloc(1, message_len+1);
|
||||||
snprintf(fail_str,
|
snprintf(fail_str,
|
||||||
@ -3978,6 +3987,21 @@ reply_error:
|
|||||||
* Create an incoming event for randomly selected backend DCB which
|
* Create an incoming event for randomly selected backend DCB which
|
||||||
* will then be notified and replied 'back' to the client.
|
* will then be notified and replied 'back' to the client.
|
||||||
*/
|
*/
|
||||||
|
DCB *dcb = NULL;
|
||||||
|
int i;
|
||||||
|
for(i = 0;i<rses->rses_nbackends;i++)
|
||||||
|
{
|
||||||
|
if(rses->rses_backend_ref[i].bref_dcb){
|
||||||
|
dcb = rses->rses_backend_ref[i].bref_dcb;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dcb == NULL)
|
||||||
|
{
|
||||||
|
skygw_log_write_flush(LOGFILE_ERROR,"Error : All backend connections are down.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
poll_add_epollin_event_to_dcb(rses->rses_backend_ref->bref_dcb,
|
poll_add_epollin_event_to_dcb(rses->rses_backend_ref->bref_dcb,
|
||||||
gwbuf_clone(errbuf));
|
gwbuf_clone(errbuf));
|
||||||
gwbuf_free(errbuf);
|
gwbuf_free(errbuf);
|
||||||
|
@ -238,13 +238,13 @@ hashkeyfun(void* key)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned int hash = 0, c = 0;
|
int hash = 0, c = 0;
|
||||||
char* ptr = (char*) key;
|
char* ptr = (char*) key;
|
||||||
while((c = *ptr++))
|
while((c = *ptr++))
|
||||||
{
|
{
|
||||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
}
|
}
|
||||||
return *(int *) key;
|
return hash >= 0 ? hash : -hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -394,7 +394,7 @@ get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, GWBUF*
|
|||||||
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_TABLES))
|
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_TABLES))
|
||||||
{
|
{
|
||||||
query = modutil_get_SQL(buffer);
|
query = modutil_get_SQL(buffer);
|
||||||
if((tmp = strstr(query,"from")))
|
if((tmp = strcasestr(query,"from")))
|
||||||
{
|
{
|
||||||
char* tok = strtok(tmp, " ;");
|
char* tok = strtok(tmp, " ;");
|
||||||
tok = strtok(NULL," ;");
|
tok = strtok(NULL," ;");
|
||||||
@ -560,7 +560,6 @@ retblock:
|
|||||||
if(tmp)
|
if(tmp)
|
||||||
{
|
{
|
||||||
poll_add_epollin_event_to_dcb(rses->queue_dcb,tmp);
|
poll_add_epollin_event_to_dcb(rses->queue_dcb,tmp);
|
||||||
//routeQuery((ROUTER*) rses->router, rses, tmp);
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user