Added createInstance and newSession, cleaned up things related to other routers.

This commit is contained in:
VilhoRaatikka
2014-12-01 15:52:00 +02:00
parent 43d348e3ac
commit a78ac19a87
2 changed files with 165 additions and 559 deletions

View File

@ -23,7 +23,7 @@
#include <stdint.h>
#include <router.h>
#include <readwritesplit.h>
#include <dbshard.h>
#include <mysql.h>
#include <skygw_utils.h>
@ -96,8 +96,6 @@ static void handleError(
static void print_error_packet(ROUTER_CLIENT_SES* rses, GWBUF* buf, DCB* dcb);
static int router_get_servercount(ROUTER_INSTANCE* router);
static int rses_get_max_slavecount(ROUTER_CLIENT_SES* rses, int router_nservers);
static int rses_get_max_replication_lag(ROUTER_CLIENT_SES* rses);
static backend_ref_t* get_bref_from_dcb(ROUTER_CLIENT_SES* rses, DCB* dcb);
static route_target_t get_route_target (
@ -142,26 +140,9 @@ int bref_cmp_current_load(
const void* bref1,
const void* bref2);
/**
* The order of functions _must_ match with the order the select criteria are
* listed in select_criteria_t definition in readwritesplit.h
*/
int (*criteria_cmpfun[LAST_CRITERIA])(const void*, const void*)=
{
NULL,
bref_cmp_global_conn,
bref_cmp_router_conn,
bref_cmp_behind_master,
bref_cmp_current_load
};
static bool select_connect_backend_servers(
backend_ref_t** p_master_ref,
backend_ref_t* backend_ref,
int router_nservers,
int max_nslaves,
int max_rlag,
select_criteria_t select_criteria,
SESSION* session,
ROUTER_INSTANCE* router);
@ -177,7 +158,6 @@ static void rwsplit_process_router_options(
char** options);
static ROUTER_OBJECT MyObject = {
createInstance,
newSession,
@ -286,11 +266,6 @@ static BACKEND* get_root_master(
backend_ref_t* servers,
int router_nservers);
static bool have_enough_servers(
ROUTER_CLIENT_SES** rses,
const int nsrv,
int router_nsrv,
ROUTER_INSTANCE* router);
static SPINLOCK instlock;
static ROUTER_INSTANCE* instances;
@ -598,7 +573,7 @@ createInstance(SERVICE *service, char **options)
* Read config version number from service to inform what configuration
* is used if any.
*/
router->rwsplit_version = service->svc_config_version;
router->dbshard_version = service->svc_config_version;
/**
* Get hashtable which includes dbname,backend pairs
@ -632,13 +607,10 @@ static void* newSession(
SESSION* session)
{
backend_ref_t* backend_ref; /*< array of backend references (DCB,BACKEND,cursor) */
backend_ref_t* master_ref = NULL; /*< pointer to selected master */
ROUTER_CLIENT_SES* client_rses = NULL;
ROUTER_INSTANCE* router = (ROUTER_INSTANCE *)router_inst;
bool succp;
int router_nservers = 0; /*< # of servers in total */
int max_nslaves; /*< max # of slaves used in this session */
int max_slave_rlag; /*< max allowed replication lag for any slave */
int i;
const int min_nservers = 1; /*< hard-coded for now */
@ -661,27 +633,35 @@ static void* newSession(
*/
spinlock_acquire(&router->lock);
if (router->service->svc_config_version > router->rwsplit_version)
/**
* ??? tarvitaanko
*/
if (router->service->svc_config_version > router->dbshard_version)
{
/** re-read all parameters to rwsplit config structure */
refreshInstance(router, NULL); /*< scan through all parameters */
/** increment rwsplit router's config version number */
router->rwsplit_version = router->service->svc_config_version;
router->dbshard_version = router->service->svc_config_version;
/** Read options */
rwsplit_process_router_options(router, router->service->routerOptions);
dbshard_process_router_options(router, router->service->routerOptions);
}
/** Copy config struct from router instance */
client_rses->rses_config = router->rwsplit_config;
client_rses->rses_config = router->dbshard_config;
spinlock_release(&router->lock);
/**
* Set defaults to session variables.
* ??? tarvitaanko
*/
client_rses->rses_autocommit_enabled = true;
client_rses->rses_transaction_active = false;
/**
* Instead of calling this, ensure that there is at least one
* responding server.
*/
#if 0
router_nservers = router_get_servercount(router);
if (!have_enough_servers(&client_rses,
min_nservers,
router_nservers,
@ -689,6 +669,7 @@ static void* newSession(
{
goto return_rses;
}
#endif
/**
* Create backend reference objects for this session.
*/
@ -723,8 +704,6 @@ static void* newSession(
&client_rses->rses_properties[RSES_PROP_TYPE_SESCMD];
backend_ref[i].bref_sescmd_cur.scmd_cur_cmd = NULL;
}
max_nslaves = rses_get_max_slavecount(client_rses, router_nservers);
max_slave_rlag = rses_get_max_replication_lag(client_rses);
spinlock_init(&client_rses->rses_lock);
client_rses->rses_backend_ref = backend_ref;
@ -733,7 +712,6 @@ static void* newSession(
* Find a backend servers to connect to.
* This command requires that rsession's lock is held.
*/
succp = rses_begin_locked_router_action(client_rses);
if(!succp)
@ -743,14 +721,10 @@ static void* newSession(
client_rses = NULL;
goto return_rses;
}
succp = select_connect_backend_servers(&master_ref,
backend_ref,
router_nservers,
max_nslaves,
max_slave_rlag,
client_rses->rses_config.rw_slave_select_criteria,
session,
router);
succp = connect_backend_servers(backend_ref,
router_nservers,
session,
router);
rses_end_locked_router_action(client_rses);
@ -764,9 +738,6 @@ static void* newSession(
goto return_rses;
}
/** Copy backend pointers to router session. */
client_rses->rses_master_ref = master_ref;
/* assert with master_host */
ss_dassert(master_ref && (master_ref->bref_backend->backend_server && SERVER_MASTER));
client_rses->rses_capabilities = RCAP_TYPE_STMT_INPUT;
client_rses->rses_backend_ref = backend_ref;
client_rses->rses_nbackends = router_nservers; /*< # of backend servers */
@ -2599,13 +2570,9 @@ static void bref_set_state(
}
/**
* @node Search suitable backend servers from those of router instance.
* @node Search all RUNNING backend servers and connect
*
* Parameters:
* @param p_master_ref - in, use, out
* Pointer to location where master's backend reference is to be stored.
* NULL is not allowed.
*
* @param backend_ref - in, use, out
* Pointer to backend server reference object array.
* NULL is not allowed.
@ -2628,80 +2595,22 @@ static void bref_set_state(
* @return true, if at least one master and one slave was found.
*
*
* @details It is assumed that there is only one master among servers of
* a router instance. As a result, the first master found is chosen.
* There will possibly be more backend references than connected backends
* because only those in correct state are connected to.
* @details It is assumed that there is only one available server.
* There will be exactly as many backend references than there are
* connections because all servers are supposed to be operational. It is,
* however, possible that there are less available servers than expected.
*/
static bool select_connect_backend_servers(
backend_ref_t** p_master_ref,
static bool connect_backend_servers(
backend_ref_t* backend_ref,
int router_nservers,
int max_nslaves,
int max_slave_rlag,
select_criteria_t select_criteria,
SESSION* session,
ROUTER_INSTANCE* router)
{
bool succp = true;
bool master_found;
bool master_connected;
int slaves_found = 0;
int slaves_connected = 0;
int servers_found = 0;
int servers_connected = 0;
int i;
const int min_nslaves = 0; /*< not configurable at the time */
bool is_synced_master;
int (*p)(const void *, const void *);
BACKEND* master_host;
if (p_master_ref == NULL || backend_ref == NULL)
{
ss_dassert(FALSE);
succp = false;
goto return_succp;
}
/* get the root Master */
master_host = get_root_master(backend_ref, router_nservers);
/**
* Existing session : master is already chosen and connected.
* The function was called because new slave must be selected to replace
* failed one.
*/
if (*p_master_ref != NULL)
{
/**
* Ensure that backend reference is in use, stored master is
* still current root master.
*/
if (!BREF_IS_IN_USE((*p_master_ref)) ||
!SERVER_IS_MASTER((*p_master_ref)->bref_backend->backend_server) ||
master_host != (*p_master_ref)->bref_backend)
{
succp = false;
goto return_succp;
}
master_found = true;
master_connected = true;
}
/**
* New session : select master and slaves
*/
else
{
master_found = false;
master_connected = false;
}
/** Check slave selection criteria and set compare function */
p = criteria_cmpfun[select_criteria];
if (p == NULL)
{
succp = false;
goto return_succp;
}
if (router->bitvalue != 0) /*< 'synced' is the only bitvalue in rwsplit */
{
is_synced_master = true;
@ -2719,8 +2628,7 @@ static bool select_connect_backend_servers(
BACKEND* b = backend_ref[i].bref_backend;
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
"master bref %p bref %p %d %s %d:%d",
*p_master_ref,
"bref %p %d %s %d:%d",
&backend_ref[i],
backend_ref[i].bref_state,
b->backend_server->name,
@ -2728,12 +2636,6 @@ static bool select_connect_backend_servers(
b->backend_conn_count)));
}
#endif
/**
* Sort the pointer list to servers according to connection counts. As
* a consequence those backends having least connections are in the
* beginning of the list.
*/
qsort(backend_ref, (size_t)router_nservers, sizeof(backend_ref_t), p);
if (LOG_IS_ENABLED(LOGFILE_TRACE))
{
@ -2743,197 +2645,98 @@ static bool select_connect_backend_servers(
select_criteria == LEAST_CURRENT_OPERATIONS)
{
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
"Servers and %s connection counts:",
select_criteria == LEAST_GLOBAL_CONNECTIONS ?
"all MaxScale" : "router")));
"Servers and connection counts:")));
for (i=0; i<router_nservers; i++)
{
BACKEND* b = backend_ref[i].bref_backend;
switch(select_criteria) {
case LEAST_GLOBAL_CONNECTIONS:
LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE,
"MaxScale connections : %d in \t%s:%d %s",
b->backend_server->stats.n_current,
b->backend_server->name,
b->backend_server->port,
STRSRVSTATUS(b->backend_server))));
break;
case LEAST_ROUTER_CONNECTIONS:
LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE,
"RWSplit connections : %d in \t%s:%d %s",
b->backend_conn_count,
b->backend_server->name,
b->backend_server->port,
STRSRVSTATUS(b->backend_server))));
break;
case LEAST_CURRENT_OPERATIONS:
LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE,
"current operations : %d in \t%s:%d %s",
b->backend_server->stats.n_current_ops,
b->backend_server->name,
b->backend_server->port,
STRSRVSTATUS(b->backend_server))));
break;
case LEAST_BEHIND_MASTER:
LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE,
"replication lag : %d in \t%s:%d %s",
b->backend_server->rlag,
b->backend_server->name,
b->backend_server->port,
STRSRVSTATUS(b->backend_server))));
default:
break;
}
}
LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE,
"MaxScale connections : %d (%d) in \t%s:%d %s",
b->backend_conn_count,
b->backend_server->stats.n_current,
b->backend_server->name,
b->backend_server->port,
STRSRVSTATUS(b->backend_server))));
}
}
} /*< log only */
} /*< log only */
/**
* Choose at least 1+min_nslaves (master and slave) and at most 1+max_nslaves
* servers from the sorted list. First master found is selected.
* Choose at least onr server from the list.
*/
for (i=0;
i<router_nservers &&
(slaves_connected < max_nslaves || !master_connected);
(server_connected < max_nservers || !master_connected);
i++)
{
BACKEND* b = backend_ref[i].bref_backend;
if (router->servers[i]->weight == 0)
{
continue;
}
if (SERVER_IS_RUNNING(b->backend_server) &&
((b->backend_server->status & router->bitmask) ==
router->bitvalue))
{
/* check also for relay servers and don't take the master_host */
if (slaves_found < max_nslaves &&
(max_slave_rlag == MAX_RLAG_UNDEFINED ||
(b->backend_server->rlag != MAX_RLAG_NOT_AVAILABLE &&
b->backend_server->rlag <= max_slave_rlag)) &&
(SERVER_IS_SLAVE(b->backend_server) ||
SERVER_IS_RELAY_SERVER(b->backend_server)) &&
(master_host != NULL &&
(b->backend_server != master_host->backend_server)))
{
slaves_found += 1;
servers_found += 1;
/** Slave is already connected */
if (BREF_IS_IN_USE((&backend_ref[i])))
{
slaves_connected += 1;
}
/** New slave connection is taking place */
else
{
backend_ref[i].bref_dcb = dcb_connect(
b->backend_server,
session,
b->backend_server->protocol);
if (backend_ref[i].bref_dcb != NULL)
{
slaves_connected += 1;
/**
* Start executing session command
* history.
*/
execute_sescmd_history(&backend_ref[i]);
/**
* When server fails, this callback
* is called.
*/
dcb_add_callback(
backend_ref[i].bref_dcb,
DCB_REASON_NOT_RESPONDING,
&router_handle_state_switch,
(void *)&backend_ref[i]);
backend_ref[i].bref_state = 0;
bref_set_state(&backend_ref[i],
BREF_IN_USE);
/**
* Increase backend connection counter.
* Server's stats are _increased_ in
* dcb.c:dcb_alloc !
* But decreased in the calling function
* of dcb_close.
*/
atomic_add(&b->backend_conn_count, 1);
}
else
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to establish "
"connection with slave %s:%d",
b->backend_server->name,
b->backend_server->port)));
/* handle connect error */
}
}
}
/* take the master_host for master */
else if (master_host &&
(b->backend_server == master_host->backend_server))
{
/**
* *p_master_ref must be assigned with this
* backend_ref pointer because its original value
* may have been lost when backend references were
* sorted (qsort).
*/
*p_master_ref = &backend_ref[i];
if (master_connected)
{
continue;
}
master_found = true;
backend_ref[i].bref_dcb = dcb_connect(
b->backend_server,
session,
b->backend_server->protocol);
if (backend_ref[i].bref_dcb != NULL)
{
master_connected = true;
/**
* When server fails, this callback
* is called.
*/
dcb_add_callback(
backend_ref[i].bref_dcb,
DCB_REASON_NOT_RESPONDING,
&router_handle_state_switch,
(void *)&backend_ref[i]);
backend_ref[i].bref_state = 0;
bref_set_state(&backend_ref[i],
BREF_IN_USE);
/** Increase backend connection counters */
atomic_add(&b->backend_conn_count, 1);
}
else
{
succp = false;
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to establish "
"connection with master %s:%d",
b->backend_server->name,
b->backend_server->port)));
/** handle connect error */
}
}
}
/** Server is already connected */
if (BREF_IS_IN_USE((&backend_ref[i])))
{
slaves_connected += 1;
}
/** New server connection */
else
{
backend_ref[i].bref_dcb = dcb_connect(
b->backend_server,
session,
b->backend_server->protocol);
if (backend_ref[i].bref_dcb != NULL)
{
servers_connected += 1;
/**
* Start executing session command
* history.
*/
execute_sescmd_history(&backend_ref[i]);
/**
* When server fails, this callback
* is called.
* !!! Todo, routine which removes
* corresponding entries from the hash
* table.
*/
#if 0
dcb_add_callback(
backend_ref[i].bref_dcb,
DCB_REASON_NOT_RESPONDING,
&router_handle_state_switch,
(void *)&backend_ref[i]);
#endif
backend_ref[i].bref_state = 0;
bref_set_state(&backend_ref[i],
BREF_IN_USE);
/**
* Increase backend connection counter.
* Server's stats are _increased_ in
* dcb.c:dcb_alloc !
* But decreased in the calling function
* of dcb_close.
*/
atomic_add(&b->backend_conn_count, 1);
}
else
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to establish "
"connection with slave %s:%d",
b->backend_server->name,
b->backend_server->port)));
/* handle connect error */
}
}
}
} /*< for */
#if defined(EXTRA_SS_DEBUG)
@ -2943,178 +2746,66 @@ static bool select_connect_backend_servers(
{
BACKEND* b = backend_ref[i].bref_backend;
LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE,
"master bref %p bref %p %d %s %d:%d",
*p_master_ref,
&backend_ref[i],
backend_ref[i].bref_state,
b->backend_server->name,
b->backend_server->port,
b->backend_conn_count)));
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
"bref %p %d %s %d:%d",
&backend_ref[i],
backend_ref[i].bref_state,
b->backend_server->name,
b->backend_server->port,
b->backend_conn_count)));
}
/* assert with master_host */
ss_dassert(!master_connected ||
(master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) &&
SERVER_MASTER));
#endif
#endif
/**
* Successful cases
*/
if (master_connected &&
slaves_connected >= min_nslaves &&
slaves_connected <= max_nslaves)
if (servers_connected > 0)
{
succp = true;
if (slaves_connected == 0 && slaves_found > 0)
if (servers_connected == 0)
{
/** Failure case */
succp = false;
}
else
{
succp = true;
if (LOG_IS_ENABLED(LT))
{
for (i=0; i<router_nservers; i++)
{
BACKEND* b = backend_ref[i].bref_backend;
if (BREF_IS_IN_USE((&backend_ref[i])))
{
LOGIF(LT, (skygw_log_write(
LOGFILE_TRACE,
"Connected %s in \t%s:%d",
STRSRVSTATUS(b->backend_server),
b->backend_server->name,
b->backend_server->port)));
}
} /* for */
}
}
if (servers_connected < router_nservers)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Warning : Couldn't connect to any of the %d "
"slaves. Routing to %s only.",
slaves_found,
(is_synced_master ? "Galera nodes" : "Master"))));
"Warning : Couldn't connect to all available "
"servers. Routing to %d out of %d only.",
servers_found,
router_nservers)));
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"* Warning : Couldn't connect to any of the %d "
"slaves. Routing to %s only.",
slaves_found,
(is_synced_master ? "Galera nodes" : "Master"))));
}
else if (slaves_found == 0)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Warning : Couldn't find any slaves from existing "
"%d servers. Routing to %s only.",
router_nservers,
(is_synced_master ? "Galera nodes" : "Master"))));
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"* Warning : Couldn't find any slaves from existing "
"%d servers. Routing to %s only.",
router_nservers,
(is_synced_master ? "Galera nodes" : "Master"))));
}
else if (slaves_connected < max_nslaves)
{
LOGIF(LT, (skygw_log_write_flush(
LOGFILE_TRACE,
"Note : Couldn't connect to maximum number of "
"slaves. Connected successfully to %d slaves "
"of %d of them.",
slaves_connected,
slaves_found)));
}
if (LOG_IS_ENABLED(LT))
{
for (i=0; i<router_nservers; i++)
{
BACKEND* b = backend_ref[i].bref_backend;
if (BREF_IS_IN_USE((&backend_ref[i])))
{
LOGIF(LT, (skygw_log_write(
LOGFILE_TRACE,
"Selected %s in \t%s:%d",
STRSRVSTATUS(b->backend_server),
b->backend_server->name,
b->backend_server->port)));
}
} /* for */
}
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"* Warning : Couldn't connect to all available "
"servers. Routing to %d out of %d only.",
servers_found,
router_nservers)));
}
}
/**
* Failure cases
*/
else
{
succp = false;
if (!master_found)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Error : Couldn't find suitable %s from %d "
"candidates.",
(is_synced_master ? "Galera node" : "Master"),
router_nservers)));
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"Error : Couldn't find suitable %s from %d "
"candidates.",
(is_synced_master ? "Galera node" : "Master"),
router_nservers)));
LOGIF(LT, (skygw_log_write(
LOGFILE_TRACE,
"Error : Couldn't find suitable %s from %d "
"candidates.",
(is_synced_master ? "Galera node" : "Master"),
router_nservers)));
}
else if (!master_connected)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Error : Couldn't connect to any %s although "
"there exists at least one %s node in the "
"cluster.",
(is_synced_master ? "Galera node" : "Master"),
(is_synced_master ? "Galera node" : "Master"))));
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"Error : Couldn't connect to any %s although "
"there exists at least one %s node in the "
"cluster.",
(is_synced_master ? "Galera node" : "Master"),
(is_synced_master ? "Galera node" : "Master"))));
LOGIF(LT, (skygw_log_write(
LOGFILE_TRACE,
"Error : Couldn't connect to any %s although "
"there exists at least one %s node in the "
"cluster.",
(is_synced_master ? "Galera node" : "Master"),
(is_synced_master ? "Galera node" : "Master"))));
}
if (slaves_connected < min_nslaves)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Error : Couldn't establish required amount of "
"slave connections for router session.")));
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"Error : Couldn't establish required amount of "
"slave connections for router session.")));
}
/** Clean up connections */
for (i=0; i<router_nservers; i++)
{
if (BREF_IS_IN_USE((&backend_ref[i])))
{
ss_dassert(backend_ref[i].bref_backend->backend_conn_count > 0);
/** disconnect opened connections */
dcb_close(backend_ref[i].bref_dcb);
bref_clear_state(&backend_ref[i], BREF_IN_USE);
/** Decrease backend's connection counter. */
atomic_add(&backend_ref[i].bref_backend->backend_conn_count, -1);
}
}
master_connected = false;
slaves_connected = 0;
}
return_succp:
return succp;
@ -4048,30 +3739,15 @@ static void handleError (
*succp = false;
return;
}
if (rses->rses_master_ref->bref_dcb == backend_dcb &&
!SERVER_IS_MASTER(rses->rses_master_ref->bref_backend->backend_server))
{
/** Master failed, can't recover */
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Master node have failed. "
"Session will be closed.")));
*succp = false;
}
else
{
/**
* This is called in hope of getting replacement for
* failed slave(s).
*/
*succp = handle_error_new_connection(inst,
rses,
backend_dcb,
errmsgbuf);
}
rses_end_locked_router_action(rses);
/**
* This is called in hope of getting replacement for
* failed slave(s).
*/
*succp = handle_error_new_connection(inst,
rses,
backend_dcb,
errmsgbuf);
rses_end_locked_router_action(rses);
break;
}
@ -4126,8 +3802,7 @@ static void handle_error_reply_client(
/**
* Check if there is backend reference pointing at failed DCB, and reset its
* flags. Then clear DCB's callback and finally : try to find replacement(s)
* for failed slave(s).
* flags. Then clear DCB's callback and finally try to reconnect.
*
* This must be called with router lock.
*
@ -4161,7 +3836,8 @@ static bool handle_error_new_connection(
*/
if ((bref = get_bref_from_dcb(rses, backend_dcb)) == NULL)
{
succp = true;
ss_dassert(bref != NULL);
succp = false;
goto return_succp;
}
CHK_BACKEND_REF(bref);
@ -4202,19 +3878,13 @@ static bool handle_error_new_connection(
(void *)bref);
router_nservers = router_get_servercount(inst);
max_nslaves = rses_get_max_slavecount(rses, router_nservers);
max_slave_rlag = rses_get_max_replication_lag(rses);
/**
* Try to get replacement slave or at least the minimum
* number of slave connections for router session.
*/
succp = select_connect_backend_servers(
&rses->rses_master_ref,
rses->rses_backend_ref,
router_nservers,
max_nslaves,
max_slave_rlag,
rses->rses_config.rw_slave_select_criteria,
ses,
inst);
@ -4288,70 +3958,6 @@ static int router_get_servercount(
return router_nservers;
}
static bool have_enough_servers(
ROUTER_CLIENT_SES** p_rses,
const int min_nsrv,
int router_nsrv,
ROUTER_INSTANCE* router)
{
bool succp;
/** With too few servers session is not created */
if (router_nsrv < min_nsrv ||
MAX((*p_rses)->rses_config.rw_max_slave_conn_count,
(router_nsrv*(*p_rses)->rses_config.rw_max_slave_conn_percent)/100)
< min_nsrv)
{
if (router_nsrv < min_nsrv)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to start %s service. There are "
"too few backend servers available. Found %d "
"when %d is required.",
router->service->name,
router_nsrv,
min_nsrv)));
}
else
{
int pct = (*p_rses)->rses_config.rw_max_slave_conn_percent/100;
int nservers = router_nsrv*pct;
if ((*p_rses)->rses_config.rw_max_slave_conn_count < min_nsrv)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to start %s service. There are "
"too few backend servers configured in "
"MaxScale.cnf. Found %d when %d is required.",
router->service->name,
(*p_rses)->rses_config.rw_max_slave_conn_count,
min_nsrv)));
}
if (nservers < min_nsrv)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to start %s service. There are "
"too few backend servers configured in "
"MaxScale.cnf. Found %d%% when at least %d%% "
"would be required.",
router->service->name,
(*p_rses)->rses_config.rw_max_slave_conn_percent,
min_nsrv/(router_nsrv/100))));
}
}
free(*p_rses);
*p_rses = NULL;
succp = false;
}
else
{
succp = true;
}
return succp;
}
/**
* Find out the number of read backend servers.