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:
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user