Added dbshard template to MaxScale_template.cnf

Added NULL-check to createInstance to avoid NULL-pointer reference if user/pwd is missing from config.
Removed unnecessary code, added error messages, fixed intendation.
This commit is contained in:
VilhoRaatikka
2014-12-07 23:34:47 +02:00
parent 0348df5147
commit 4c1ed65617
3 changed files with 131 additions and 95 deletions

View File

@ -184,7 +184,7 @@ replace=select
# max_slave_replication_lag=<allowed lag in seconds for a slave> # max_slave_replication_lag=<allowed lag in seconds for a slave>
# #
# Valid router modules currently are: # Valid router modules currently are:
# readwritesplit, readconnroute, debugcli and CLI # readwritesplit, readconnroute, dbshard, debugcli and CLI
# #
## Examples: ## Examples:
@ -208,6 +208,13 @@ passwd=mypwd
#router_options=slave_selection_criteria= #router_options=slave_selection_criteria=
#filters=fetch|qla #filters=fetch|qla
[DBShard Router]
type=service
router=dbshard
servers=server1,server2
user=maxuser
passwd=maxpwd
[HTTPD Router] [HTTPD Router]
type=service type=service
router=testroute router=testroute
@ -263,6 +270,12 @@ protocol=MySQLClient
port=4006 port=4006
#socket=/tmp/rwsplit.sock #socket=/tmp/rwsplit.sock
[DBShard Listener]
type=listener
service=DBShard Router
protocol=MySQLClient
port=4010
[Debug Listener] [Debug Listener]
type=listener type=listener
service=Debug Interface service=Debug Interface

View File

@ -282,6 +282,8 @@ int error_count = 0;
char *weightby; char *weightby;
char *version_string; char *version_string;
bool is_rwsplit = false; bool is_rwsplit = false;
bool is_dbshard = false;
char *allow_localhost_match_wildcard_host;
obj->element = service_alloc(obj->object, router); obj->element = service_alloc(obj->object, router);
user = config_get_value(obj->parameters, "user"); user = config_get_value(obj->parameters, "user");
@ -289,6 +291,9 @@ int error_count = 0;
enable_root_user = config_get_value( enable_root_user = config_get_value(
obj->parameters, obj->parameters,
"enable_root_user"); "enable_root_user");
allow_localhost_match_wildcard_host =
config_get_value(obj->parameters,
"localhost_match_wildcard_host");
weightby = config_get_value(obj->parameters, "weightby"); weightby = config_get_value(obj->parameters, "weightby");
version_string = config_get_value(obj->parameters, version_string = config_get_value(obj->parameters,
@ -298,9 +303,10 @@ int error_count = 0;
{ {
is_rwsplit = true; is_rwsplit = true;
} }
else if (strncasecmp(router, "dbshard", strlen("dbshard")+1) == 0)
char *allow_localhost_match_wildcard_host = {
config_get_value(obj->parameters, "localhost_match_wildcard_host"); is_dbshard = true;
}
if (obj->element == NULL) /*< if module load failed */ if (obj->element == NULL) /*< if module load failed */
{ {
@ -315,19 +321,30 @@ int error_count = 0;
continue; /*< process next obj */ continue; /*< process next obj */
} }
if (version_string) { if (version_string != NULL)
((SERVICE *)(obj->element))->version_string = strdup(version_string); {
} else { ((SERVICE *)(obj->element))->version_string =
if (gateway.version_string) strdup(version_string);
((SERVICE *)(obj->element))->version_string = strdup(gateway.version_string); }
else
{
if (gateway.version_string != NULL)
{
((SERVICE *)(obj->element))->version_string =
strdup(gateway.version_string);
}
} }
max_slave_conn_str =
config_get_value(obj->parameters,
"max_slave_connections");
max_slave_rlag_str = if (is_rwsplit)
config_get_value(obj->parameters, {
"max_slave_replication_lag"); max_slave_conn_str =
config_get_value(obj->parameters,
"max_slave_connections");
max_slave_rlag_str =
config_get_value(obj->parameters,
"max_slave_replication_lag");
}
if (enable_root_user) if (enable_root_user)
serviceEnableRootUser( serviceEnableRootUser(
@ -347,9 +364,7 @@ int error_count = 0;
if (obj->element && user && auth) if (obj->element && user && auth)
{ {
serviceSetUser(obj->element, serviceSetUser(obj->element, user, auth);
user,
auth);
} }
else if (user && auth == NULL) else if (user && auth == NULL)
{ {
@ -361,7 +376,7 @@ int error_count = 0;
obj->object))); obj->object)));
} }
/** Read, validate and set max_slave_connections */ /** Read, validate and set max_slave_connections */
if (max_slave_conn_str != NULL) if (is_rwsplit && max_slave_conn_str != NULL)
{ {
CONFIG_PARAMETER* param; CONFIG_PARAMETER* param;
bool succp; bool succp;
@ -399,7 +414,7 @@ int error_count = 0;
} }
} }
/** Read, validate and set max_slave_replication_lag */ /** Read, validate and set max_slave_replication_lag */
if (max_slave_rlag_str != NULL) if (is_rwsplit && max_slave_rlag_str != NULL)
{ {
CONFIG_PARAMETER* param; CONFIG_PARAMETER* param;
bool succp; bool succp;
@ -1293,10 +1308,14 @@ SERVER *server;
version_string = config_get_value(obj->parameters, "version_string"); version_string = config_get_value(obj->parameters, "version_string");
allow_localhost_match_wildcard_host = config_get_value(obj->parameters, "localhost_match_wildcard_host"); allow_localhost_match_wildcard_host =
config_get_value(obj->parameters,
"localhost_match_wildcard_host");
if (version_string) { if (version_string)
if (service->version_string) { {
if (service->version_string)
{
free(service->version_string); free(service->version_string);
} }
service->version_string = strdup(version_string); service->version_string = strdup(version_string);

View File

@ -330,20 +330,21 @@ bool update_dbnames_hash(BACKEND** backends, HASHTABLE* hashtable)
SERVER* server; SERVER* server;
int i, rc, numfields; int i, rc, numfields;
for(i = 0;backends[i];i++)
{
MYSQL* handle = mysql_init(NULL);
MYSQL_RES* result = NULL;
MYSQL_ROW row;
char *user,*pwd = NULL;
if(handle == NULL)
for(i = 0;backends[i];i++){ {
LOGIF(LE, (skygw_log_write_flush(
MYSQL* handle = mysql_init(NULL); LOGFILE_ERROR,
MYSQL_RES* result = NULL; "Error: Failed to initialize "
MYSQL_ROW row; "MySQL handle.")));
char *user,*pwd = NULL; return false;
}
if(handle == NULL){
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to initialize MySQL handle.")));
return false;
}
rc = 0; rc = 0;
rc |= mysql_options(handle, rc |= mysql_options(handle,
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_CONNECT_TIMEOUT,
@ -360,41 +361,40 @@ bool update_dbnames_hash(BACKEND** backends, HASHTABLE* hashtable)
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->monuser == NULL || server->monpw == NULL){ if(server->monuser == NULL || server->monpw == NULL)
{
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error: No username or password defined for server '%s'.",server->unique_name))); "Error: No username or password "
"defined for server '%s'.",
server->unique_name)));
rval = false; rval = false;
goto cleanup; goto cleanup;
} }
/** Plain-text password used for authentication for now */ /** Plain-text password used for authentication for now */
user = server->monuser; user = server->monuser;
pwd = server->monpw; pwd = server->monpw;
if (mysql_real_connect(handle, if (mysql_real_connect(handle,
server->name, server->name,
user, user,
pwd, pwd,
NULL, NULL,
server->port, server->port,
NULL, NULL,
0) == NULL) 0) == NULL)
{ {
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 %s",
server->name, server->name,
mysql_errno(handle), mysql_errno(handle),
mysql_error(handle)))); mysql_error(handle))));
rval = false; rval = false;
goto cleanup; goto cleanup;
} }
@ -402,13 +402,14 @@ bool update_dbnames_hash(BACKEND** backends, HASHTABLE* hashtable)
* The server was successfully connected to, proceed to query for database names * The server was successfully connected to, proceed to query for database names
*/ */
if((result = mysql_list_dbs(handle,NULL)) == NULL){ if((result = mysql_list_dbs(handle,NULL)) == NULL)
{
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,
"Error: Failed to retrieve databases from backend " "Error: Failed to retrieve databases from backend "
"server '%s': %d %s", "server '%s': %d %s",
server->name, server->name,
mysql_errno(handle), mysql_errno(handle),
mysql_error(handle)))); mysql_error(handle))));
goto cleanup; goto cleanup;
} }
numfields = mysql_num_fields(result); numfields = mysql_num_fields(result);
@ -450,6 +451,7 @@ bool update_dbnames_hash(BACKEND** backends, HASHTABLE* hashtable)
if(hashtable_add(hashtable,dbnm,servnm) == 0) if(hashtable_add(hashtable,dbnm,servnm) == 0)
{ {
char* srvname;
#ifdef SHARD_UPDATES #ifdef SHARD_UPDATES
{ {
char* old_backend = (char*)hashtable_fetch(hashtable,dbnm); char* old_backend = (char*)hashtable_fetch(hashtable,dbnm);
@ -493,7 +495,7 @@ bool update_dbnames_hash(BACKEND** backends, HASHTABLE* hashtable)
} }
#endif /*< SHARD_UPDATES */ #endif /*< SHARD_UPDATES */
/*Check if the failure was due to a duplicate value*/ /*Check if the failure was due to a duplicate value*/
if(hashtable_fetch(hashtable,dbnm) == NULL) if((srvname = hashtable_fetch(hashtable,dbnm)) == NULL)
{ {
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
@ -503,7 +505,13 @@ bool update_dbnames_hash(BACKEND** backends, HASHTABLE* hashtable)
{ {
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error: Duplicate value found."))); "Error : Conflicting "
"databases found. "
"Both \"%s\" and \"%s\" "
"have a database \"%s\".",
server->unique_name,
srvname,
dbnm)));
} }
rval = false; rval = false;
free(dbnm); free(dbnm);
@ -796,14 +804,16 @@ createInstance(SERVICE *service, char **options)
router->servers[nservers]->backend_conn_count = 0; router->servers[nservers]->backend_conn_count = 0;
router->servers[nservers]->weight = 1; router->servers[nservers]->weight = 1;
router->servers[nservers]->be_valid = false; router->servers[nservers]->be_valid = false;
if(server->monuser == NULL) if(server->monuser == NULL && service->credentials.name != NULL)
{ {
router->servers[nservers]->backend_server->monuser = strdup(service->credentials.name); router->servers[nservers]->backend_server->monuser =
} strdup(service->credentials.name);
if(server->monpw == NULL) }
{ if(server->monpw == NULL && service->credentials.authdata != NULL)
router->servers[nservers]->backend_server->monpw = strdup(service->credentials.authdata); {
} router->servers[nservers]->backend_server->monpw =
strdup(service->credentials.authdata);
}
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
router->servers[nservers]->be_chk_top = CHK_NUM_BACKEND; router->servers[nservers]->be_chk_top = CHK_NUM_BACKEND;
router->servers[nservers]->be_chk_tail = CHK_NUM_BACKEND; router->servers[nservers]->be_chk_tail = CHK_NUM_BACKEND;
@ -906,8 +916,9 @@ static void* newSession(
spinlock_acquire(&router->lock); spinlock_acquire(&router->lock);
/** /**
* ??? tarvitaanko * ??? tarvitaanko - ei vielä
*/ */
#if 0
if (router->service->svc_config_version > router->dbshard_version) if (router->service->svc_config_version > router->dbshard_version)
{ {
/** re-read all parameters to rwsplit config structure */ /** re-read all parameters to rwsplit config structure */
@ -919,7 +930,7 @@ static void* newSession(
} }
/** Copy config struct from router instance */ /** Copy config struct from router instance */
client_rses->rses_config = router->dbshard_config; client_rses->rses_config = router->dbshard_config;
#endif
spinlock_release(&router->lock); spinlock_release(&router->lock);
/** /**
* Set defaults to session variables. * Set defaults to session variables.
@ -985,9 +996,7 @@ static void* newSession(
* Find a backend servers to connect to. * Find a backend servers to connect to.
* This command requires that rsession's lock is held. * This command requires that rsession's lock is held.
*/ */
succp = rses_begin_locked_router_action(client_rses); if (!(succp = rses_begin_locked_router_action(client_rses)))
if(!succp)
{ {
free(client_rses->rses_backend_ref); free(client_rses->rses_backend_ref);
free(client_rses); free(client_rses);
@ -2403,12 +2412,6 @@ static void bref_set_state(
* @param router_nservers - in, use * @param router_nservers - in, use
* Number of backend server pointers pointed to by b. * Number of backend server pointers pointed to by b.
* *
* @param max_nslaves - in, use
* Upper limit for the number of slaves. Configuration parameter or default.
*
* @param max_slave_rlag - in, use
* Maximum allowed replication lag for any slave. Configuration parameter or default.
*
* @param session - in, use * @param session - in, use
* MaxScale session pointer used when connection to backend is established. * MaxScale session pointer used when connection to backend is established.
* *
@ -2437,7 +2440,7 @@ static bool connect_backend_servers(
int servers_found = 0; int servers_found = 0;
int servers_connected = 0; int servers_connected = 0;
int slaves_connected = 0; int slaves_connected = 0;
int i,max_nservers = router_nservers; int i;
/* /*
select_criteria_t select_criteria = LEAST_GLOBAL_CONNECTIONS; select_criteria_t select_criteria = LEAST_GLOBAL_CONNECTIONS;
*/ */
@ -2488,9 +2491,10 @@ static bool connect_backend_servers(
} }
} /*< log only */ } /*< log only */
/** /**
* Choose at least onr server from the list. * Scan server list and connect each of them. None should fail or session
* can't be established.
*/ */
for (i=0; i < router_nservers && servers_connected < max_nservers; i++) for (i=0; i < router_nservers; i++)
{ {
BACKEND* b = backend_ref[i].bref_backend; BACKEND* b = backend_ref[i].bref_backend;
@ -2540,12 +2544,12 @@ static bool connect_backend_servers(
bref_set_state(&backend_ref[i], bref_set_state(&backend_ref[i],
BREF_IN_USE); BREF_IN_USE);
/** /**
* Increase backend connection counter. * Increase backend connection counter.
* Server's stats are _increased_ in * Server's stats are _increased_ in
* dcb.c:dcb_alloc ! * dcb.c:dcb_alloc !
* But decreased in the calling function * But decreased in the calling function
* of dcb_close. * of dcb_close.
*/ */
atomic_add(&b->backend_conn_count, 1); atomic_add(&b->backend_conn_count, 1);
} }
else else