Updates to how shards are discovered while the module is running
SHOW DATABASES now takes notice of the state of the backends Added scripts for sharding test preparation and local port blocking
This commit is contained in:
@ -328,8 +328,8 @@ static void* hfree(void* fval)
|
|||||||
*/
|
*/
|
||||||
bool update_dbnames_hash(ROUTER_INSTANCE* inst,BACKEND** backends, HASHTABLE* hashtable)
|
bool update_dbnames_hash(ROUTER_INSTANCE* inst,BACKEND** backends, HASHTABLE* hashtable)
|
||||||
{
|
{
|
||||||
const unsigned int connect_timeout = 15;
|
const unsigned int connect_timeout = 1;
|
||||||
const unsigned int read_timeout = 10;
|
const unsigned int read_timeout = 1;
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
SERVER* server;
|
SERVER* server;
|
||||||
int i, rc, numfields;
|
int i, rc, numfields;
|
||||||
@ -349,7 +349,8 @@ bool update_dbnames_hash(ROUTER_INSTANCE* inst,BACKEND** backends, HASHTABLE* ha
|
|||||||
"MySQL handle.")));
|
"MySQL handle.")));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rc = 0;
|
|
||||||
|
rc = 0;
|
||||||
rc |= mysql_options(handle,
|
rc |= mysql_options(handle,
|
||||||
MYSQL_OPT_CONNECT_TIMEOUT,
|
MYSQL_OPT_CONNECT_TIMEOUT,
|
||||||
(void *)&connect_timeout);
|
(void *)&connect_timeout);
|
||||||
@ -364,11 +365,17 @@ bool update_dbnames_hash(ROUTER_INSTANCE* inst,BACKEND** backends, HASHTABLE* ha
|
|||||||
mysql_close(handle);
|
mysql_close(handle);
|
||||||
rval = false;
|
rval = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
server = backends[i]->backend_server;
|
server = backends[i]->backend_server;
|
||||||
|
|
||||||
ss_dassert(server != NULL);
|
ss_dassert(server != NULL);
|
||||||
|
|
||||||
|
if(!SERVER_IS_RUNNING(server))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(server->monuser == NULL || server->monpw == NULL)
|
if(server->monuser == NULL || server->monpw == NULL)
|
||||||
{
|
{
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
@ -395,8 +402,9 @@ bool update_dbnames_hash(ROUTER_INSTANCE* inst,BACKEND** backends, HASHTABLE* ha
|
|||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error: failed to connect to backend "
|
"Error: failed to connect to backend "
|
||||||
"server '%s': %d %s",
|
"server '%s:%d': %d %s",
|
||||||
server->name,
|
server->name,
|
||||||
|
server->port,
|
||||||
mysql_errno(handle),
|
mysql_errno(handle),
|
||||||
mysql_error(handle))));
|
mysql_error(handle))));
|
||||||
rval = false;
|
rval = false;
|
||||||
@ -573,8 +581,13 @@ void* dbnames_hash_init(ROUTER_INSTANCE* inst,BACKEND** backends)
|
|||||||
/**Update the new hashtable with the key-value pairs*/
|
/**Update the new hashtable with the key-value pairs*/
|
||||||
if(!update_dbnames_hash(inst,backends,htbl))
|
if(!update_dbnames_hash(inst,backends,htbl))
|
||||||
{
|
{
|
||||||
hashtable_free(htbl);
|
/**
|
||||||
htbl = NULL;
|
* Log if there were some errors during the database configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Warning : Errors occurred while resolving shard locations.")));
|
||||||
}
|
}
|
||||||
return htbl;
|
return htbl;
|
||||||
}
|
}
|
||||||
@ -1709,7 +1722,9 @@ GWBUF* gen_show_dbs_response(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client)
|
|||||||
GWBUF* rval = NULL;
|
GWBUF* rval = NULL;
|
||||||
HASHTABLE* ht = router->dbnames_hash;
|
HASHTABLE* ht = router->dbnames_hash;
|
||||||
HASHITERATOR* iter = hashtable_iterator(ht);
|
HASHITERATOR* iter = hashtable_iterator(ht);
|
||||||
|
BACKEND** backends = router->servers;
|
||||||
unsigned int coldef_len = 0;
|
unsigned int coldef_len = 0;
|
||||||
|
int j;
|
||||||
char dbname[MYSQL_DATABASE_MAXLEN+1];
|
char dbname[MYSQL_DATABASE_MAXLEN+1];
|
||||||
char *value;
|
char *value;
|
||||||
unsigned char* ptr;
|
unsigned char* ptr;
|
||||||
@ -1805,23 +1820,33 @@ GWBUF* gen_show_dbs_response(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client)
|
|||||||
|
|
||||||
while((value = (char*)hashtable_next(iter)))
|
while((value = (char*)hashtable_next(iter)))
|
||||||
{
|
{
|
||||||
GWBUF* temp;
|
char* bend = hashtable_fetch(ht,value);
|
||||||
int plen = strlen(value) + 1;
|
for(j = 0;backends[j];j++)
|
||||||
|
{
|
||||||
|
if(strcmp(backends[j]->backend_server->unique_name,bend) == 0)
|
||||||
|
{
|
||||||
|
if(SERVER_IS_RUNNING(backends[j]->backend_server))
|
||||||
|
{
|
||||||
|
GWBUF* temp;
|
||||||
|
int plen = strlen(value) + 1;
|
||||||
|
|
||||||
sprintf(dbname,"%s",value);
|
sprintf(dbname,"%s",value);
|
||||||
temp = gwbuf_alloc(plen + 4);
|
temp = gwbuf_alloc(plen + 4);
|
||||||
|
|
||||||
ptr = temp->start;
|
ptr = temp->start;
|
||||||
*ptr++ = plen;
|
*ptr++ = plen;
|
||||||
*ptr++ = plen >> 8;
|
*ptr++ = plen >> 8;
|
||||||
*ptr++ = plen >> 16;
|
*ptr++ = plen >> 16;
|
||||||
*ptr++ = packet_num++;
|
*ptr++ = packet_num++;
|
||||||
*ptr++ = plen - 1;
|
*ptr++ = plen - 1;
|
||||||
memcpy(ptr,dbname,plen - 1);
|
memcpy(ptr,dbname,plen - 1);
|
||||||
|
|
||||||
/** Append the row*/
|
|
||||||
rval = gwbuf_append(rval,temp);
|
|
||||||
|
|
||||||
|
/** Append the row*/
|
||||||
|
rval = gwbuf_append(rval,temp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eof[3] = packet_num;
|
eof[3] = packet_num;
|
||||||
@ -2258,13 +2283,21 @@ static int routeQuery(
|
|||||||
succp = get_shard_dcb(&target_dcb, router_cli_ses, tname);
|
succp = get_shard_dcb(&target_dcb, router_cli_ses, tname);
|
||||||
|
|
||||||
if (!succp)
|
if (!succp)
|
||||||
{
|
{
|
||||||
LOGIF(LT, (skygw_log_write(
|
update_dbnames_hash(inst,inst->servers,inst->dbnames_hash);
|
||||||
LOGFILE_TRACE,
|
tname = get_shard_target_name(inst,router_cli_ses,querybuf,qtype);
|
||||||
"Was supposed to route to named server "
|
succp = get_shard_dcb(&target_dcb, router_cli_ses, tname);
|
||||||
"%s but couldn't find the server in a "
|
|
||||||
"suitable state.",
|
if (!succp)
|
||||||
tname)));
|
{
|
||||||
|
LOGIF(LT, (skygw_log_write(
|
||||||
|
LOGFILE_TRACE,
|
||||||
|
"Was supposed to route to named server "
|
||||||
|
"%s but couldn't find the server in a "
|
||||||
|
"suitable state.",
|
||||||
|
tname)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2989,25 +3022,25 @@ static bool connect_backend_servers(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOGIF(LE, (skygw_log_write(
|
/* LOGIF(LE, (skygw_log_write( */
|
||||||
LOGFILE_ERROR,
|
/* LOGFILE_ERROR, */
|
||||||
"Warning : Couldn't connect to all available "
|
/* "Warning : Couldn't connect to all available " */
|
||||||
"servers. Session can't be created.")));
|
/* "servers. Session can't be created."))); */
|
||||||
|
|
||||||
/** Clean up connections */
|
/* /\** Clean up connections *\/ */
|
||||||
for (i=0; i<router_nservers; i++)
|
/* for (i=0; i<router_nservers; i++) */
|
||||||
{
|
/* { */
|
||||||
if (BREF_IS_IN_USE((&backend_ref[i])))
|
/* if (BREF_IS_IN_USE((&backend_ref[i]))) */
|
||||||
{
|
/* { */
|
||||||
ss_dassert(backend_ref[i].bref_backend->backend_conn_count > 0);
|
/* ss_dassert(backend_ref[i].bref_backend->backend_conn_count > 0); */
|
||||||
|
|
||||||
/** disconnect opened connections */
|
/* /\** disconnect opened connections *\/ */
|
||||||
dcb_close(backend_ref[i].bref_dcb);
|
/* dcb_close(backend_ref[i].bref_dcb); */
|
||||||
bref_clear_state(&backend_ref[i], BREF_IN_USE);
|
/* bref_clear_state(&backend_ref[i], BREF_IN_USE); */
|
||||||
/** Decrease backend's connection counter. */
|
/* /\** Decrease backend's connection counter. *\/ */
|
||||||
atomic_add(&backend_ref[i].bref_backend->backend_conn_count, -1);
|
/* atomic_add(&backend_ref[i].bref_backend->backend_conn_count, -1); */
|
||||||
}
|
/* } */
|
||||||
}
|
/* } */
|
||||||
}
|
}
|
||||||
return succp;
|
return succp;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
if(MYSQLCLIENT_FOUND AND BUILD_TESTS)
|
if(MYSQLCLIENT_FOUND AND BUILD_TESTS)
|
||||||
add_executable(testdbshard testdbshard.c)
|
add_executable(testdbshard testdbshard.c)
|
||||||
target_link_libraries(testdbshard ${MYSQLCLIENT_LIBRARIES} ssl crypto dl z m rt pthread)
|
target_link_libraries(testdbshard ${MYSQLCLIENT_LIBRARIES} ssl crypto dl z m rt pthread)
|
||||||
add_test(NAME DBShardTest COMMAND $<TARGET_FILE:testdbshard> ${TEST_HOST} 3000 ${TEST_USER} ${TEST_PASSWORD})
|
foreach(VAR RANGE 3000 3003)
|
||||||
|
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/prepare_shard.sh ${TEST_HOST} ${VAR} ${TEST_USER} ${TEST_PASSWORD})
|
||||||
|
endforeach()
|
||||||
|
add_test(NAME DBShardTest COMMAND $<TARGET_FILE:testdbshard> ${TEST_HOST} ${TEST_PORT_DB} ${TEST_USER} ${TEST_PASSWORD})
|
||||||
endif()
|
endif()
|
||||||
|
9
server/modules/routing/dbshard/test/portblock.sh
Executable file
9
server/modules/routing/dbshard/test/portblock.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
if [ $# -lt 1 ]
|
||||||
|
then
|
||||||
|
echo "Usage $0 <port to block>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sudo iptables -I INPUT 1 -i lo -p tcp --dport $1 -j DROP
|
||||||
|
sudo iptables -I INPUT 1 -i lo -p tcp --sport $1 -j DROP
|
||||||
|
echo "Traffic to port $1 blocked."
|
13
server/modules/routing/dbshard/test/prepare_shard.sh
Executable file
13
server/modules/routing/dbshard/test/prepare_shard.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
if [ $# -lt 3 ]
|
||||||
|
then
|
||||||
|
echo "usage $0 <host> <port> <username> <password>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
HOST=$1
|
||||||
|
PORT=$2
|
||||||
|
USER=$3
|
||||||
|
PW=$4
|
||||||
|
SHD="shard$RANDOM"
|
||||||
|
mysql -u $USER -p$PW -P $PORT -h $HOST -e "create database $SHD;"
|
||||||
|
echo "Created database \"$SHD\" at $HOST:$PORT"
|
@ -39,6 +39,8 @@ int main(int argc, char** argv)
|
|||||||
password = strdup(argv[4]);
|
password = strdup(argv[4]);
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
|
printf("Connecting to %s:%d as %s/%s\n",host,port,username,password);
|
||||||
|
|
||||||
if((server = mysql_init(NULL)) == NULL){
|
if((server = mysql_init(NULL)) == NULL){
|
||||||
fprintf(stderr,"Error : Initialization of MySQL client failed.\n");
|
fprintf(stderr,"Error : Initialization of MySQL client failed.\n");
|
||||||
rval = 1;
|
rval = 1;
|
||||||
|
Reference in New Issue
Block a user