Merge branch 'develop' into MAX-167
Conflicts: server/modules/monitor/mysql_mon.c server/modules/routing/readwritesplit/readwritesplit.c
This commit is contained in:
@ -128,6 +128,10 @@ struct subcommand showoptions[] = {
|
||||
"Show all currently loaded modules",
|
||||
"Show all currently loaded modules",
|
||||
{0, 0, 0} },
|
||||
{ "monitor", 1, monitorShow,
|
||||
"Show the monitor details",
|
||||
"Show the monitor details",
|
||||
{ARG_TYPE_MONITOR, 0, 0} },
|
||||
{ "monitors", 0, monitorShowAll,
|
||||
"Show the monitors that are configured",
|
||||
"Show the monitors that are configured",
|
||||
@ -168,6 +172,10 @@ struct subcommand showoptions[] = {
|
||||
* The subcommands of the list command
|
||||
*/
|
||||
struct subcommand listoptions[] = {
|
||||
{ "clients", 0, dListClients,
|
||||
"List all the client connections to MaxScale",
|
||||
"List all the client connections to MaxScale",
|
||||
{0, 0, 0} },
|
||||
{ "dcbs", 0, dListDCBs,
|
||||
"List all the DCBs active within MaxScale",
|
||||
"List all the DCBs active within MaxScale",
|
||||
@ -181,8 +189,12 @@ struct subcommand listoptions[] = {
|
||||
"List all the listeners defined within MaxScale",
|
||||
{0, 0, 0} },
|
||||
{ "modules", 0, dprintAllModules,
|
||||
"Show all currently loaded modules",
|
||||
"Show all currently loaded modules",
|
||||
"List all currently loaded modules",
|
||||
"List all currently loaded modules",
|
||||
{0, 0, 0} },
|
||||
{ "monitors", 0, monitorList,
|
||||
"List all monitors",
|
||||
"List all monitors",
|
||||
{0, 0, 0} },
|
||||
{ "services", 0, dListServices,
|
||||
"List all the services defined within MaxScale",
|
||||
@ -300,18 +312,30 @@ struct subcommand reloadoptions[] = {
|
||||
{ "dbusers", 1, reload_dbusers,
|
||||
"Reload the dbuser data for a service. E.g. reload dbusers \"splitter service\"",
|
||||
"Reload the dbuser data for a service. E.g. reload dbusers 0x849420",
|
||||
{ARG_TYPE_DBUSERS, 0, 0} },
|
||||
{ARG_TYPE_SERVICE, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
};
|
||||
|
||||
static void enable_log_action(DCB *, char *);
|
||||
static void disable_log_action(DCB *, char *);
|
||||
static void enable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor);
|
||||
static void disable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor);
|
||||
static void enable_service_root(DCB *dcb, SERVICE *service);
|
||||
static void disable_service_root(DCB *dcb, SERVICE *service);
|
||||
|
||||
/**
|
||||
* * The subcommands of the enable command
|
||||
* */
|
||||
struct subcommand enableoptions[] = {
|
||||
{
|
||||
"heartbeat",
|
||||
1,
|
||||
enable_monitor_replication_heartbeat,
|
||||
"Enable the monitor replication heartbeat, pass a monitor name as argument",
|
||||
"Enable the monitor replication heartbeat, pass a monitor name as argument",
|
||||
{ARG_TYPE_MONITOR, 0, 0}
|
||||
},
|
||||
{
|
||||
"log",
|
||||
1,
|
||||
@ -322,6 +346,14 @@ struct subcommand enableoptions[] = {
|
||||
"message E.g. enable log message.",
|
||||
{ARG_TYPE_STRING, 0, 0}
|
||||
},
|
||||
{
|
||||
"root",
|
||||
1,
|
||||
enable_service_root,
|
||||
"Enable root access to a service, pass a service name to enable root access",
|
||||
"Enable root access to a service, pass a service name to enable root access",
|
||||
{ARG_TYPE_SERVICE, 0, 0}
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
0,
|
||||
@ -337,24 +369,40 @@ struct subcommand enableoptions[] = {
|
||||
* * The subcommands of the disable command
|
||||
* */
|
||||
struct subcommand disableoptions[] = {
|
||||
{
|
||||
"log",
|
||||
1,
|
||||
disable_log_action,
|
||||
"Disable Log for MaxScale, Options: debug | trace | error | message "
|
||||
"E.g. disable log debug",
|
||||
"Disable Log for MaxScale, Options: debug | trace | error | message "
|
||||
"E.g. disable log debug",
|
||||
{ARG_TYPE_STRING, 0, 0}
|
||||
},
|
||||
{
|
||||
{
|
||||
"heartbeat",
|
||||
1,
|
||||
disable_monitor_replication_heartbeat,
|
||||
"Disable the monitor replication heartbeat",
|
||||
"Disable the monitor replication heartbeat",
|
||||
{ARG_TYPE_MONITOR, 0, 0}
|
||||
},
|
||||
{
|
||||
"log",
|
||||
1,
|
||||
disable_log_action,
|
||||
"Disable Log for MaxScale, Options: debug | trace | error | message "
|
||||
"E.g. disable log debug",
|
||||
"Disable Log for MaxScale, Options: debug | trace | error | message "
|
||||
"E.g. disable log debug",
|
||||
{ARG_TYPE_STRING, 0, 0}
|
||||
},
|
||||
{
|
||||
"root",
|
||||
1,
|
||||
disable_service_root,
|
||||
"Disable root access to a service",
|
||||
"Disable root access to a service",
|
||||
{ARG_TYPE_SERVICE, 0, 0}
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
{0, 0, 0}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
@ -850,7 +898,7 @@ unsigned int bitvalue;
|
||||
static void
|
||||
reload_dbusers(DCB *dcb, SERVICE *service)
|
||||
{
|
||||
dcb_printf(dcb, "Loaded %d database users for server %s.\n",
|
||||
dcb_printf(dcb, "Loaded %d database users for service %s.\n",
|
||||
reload_mysql_users(service), service->name);
|
||||
}
|
||||
|
||||
@ -958,6 +1006,55 @@ restart_monitor(DCB *dcb, MONITOR *monitor)
|
||||
monitorStart(monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable replication heartbeat for a monitor
|
||||
*
|
||||
* @param dcb Connection to user interface
|
||||
* @param monitor The monitor
|
||||
*/
|
||||
static void
|
||||
enable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor)
|
||||
{
|
||||
monitorSetReplicationHeartbeat(monitor, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable replication heartbeat for a monitor
|
||||
*
|
||||
* @param dcb Connection to user interface
|
||||
* @param monitor The monitor
|
||||
*/
|
||||
static void
|
||||
disable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor)
|
||||
{
|
||||
monitorSetReplicationHeartbeat(monitor, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable root access to a service
|
||||
*
|
||||
* @param dcb Connection to user interface
|
||||
* @param service The service
|
||||
*/
|
||||
static void
|
||||
enable_service_root(DCB *dcb, SERVICE *service)
|
||||
{
|
||||
serviceEnableRootUser(service, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable root access to a service
|
||||
*
|
||||
* @param dcb Connection to user interface
|
||||
* @param service The service
|
||||
*/
|
||||
static void
|
||||
disable_service_root(DCB *dcb, SERVICE *service)
|
||||
{
|
||||
serviceEnableRootUser(service, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The log enable action
|
||||
*/
|
||||
|
@ -65,6 +65,8 @@
|
||||
* or take different actions such as open a new backend connection
|
||||
* 20/02/2014 Massimiliano Pinto If router_options=slave, route traffic to master if no slaves available
|
||||
* 06/03/2014 Massimiliano Pinto Server connection counter is now updated in closeSession
|
||||
* 24/06/2014 Massimiliano Pinto New rules for selecting the Master server
|
||||
* 27/06/2014 Mark Riddoch Addition of server weighting
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -96,7 +98,7 @@ MODULE_INFO info = {
|
||||
"A connection based router to load balance based on connections"
|
||||
};
|
||||
|
||||
static char *version_str = "V1.0.2";
|
||||
static char *version_str = "V1.1.0";
|
||||
|
||||
/* The router entry points */
|
||||
static ROUTER *createInstance(SERVICE *service, char **options);
|
||||
@ -110,13 +112,13 @@ static void clientReply(
|
||||
void *router_session,
|
||||
GWBUF *queue,
|
||||
DCB *backend_dcb);
|
||||
static void handleError(
|
||||
ROUTER *instance,
|
||||
void *router_session,
|
||||
GWBUF *errbuf,
|
||||
DCB *backend_dcb,
|
||||
int action,
|
||||
bool *succp);
|
||||
static void handleError(
|
||||
ROUTER *instance,
|
||||
void *router_session,
|
||||
GWBUF *errbuf,
|
||||
DCB *backend_dcb,
|
||||
error_action_t action,
|
||||
bool *succp);
|
||||
static uint8_t getCapabilities (ROUTER* inst, void* router_session);
|
||||
|
||||
|
||||
@ -139,6 +141,9 @@ static bool rses_begin_locked_router_action(
|
||||
static void rses_end_locked_router_action(
|
||||
ROUTER_CLIENT_SES* rses);
|
||||
|
||||
static BACKEND *get_root_master(
|
||||
BACKEND **servers);
|
||||
|
||||
static SPINLOCK instlock;
|
||||
static ROUTER_INSTANCE *instances;
|
||||
|
||||
@ -196,6 +201,8 @@ createInstance(SERVICE *service, char **options)
|
||||
ROUTER_INSTANCE *inst;
|
||||
SERVER *server;
|
||||
int i, n;
|
||||
BACKEND *backend;
|
||||
char *weightby;
|
||||
|
||||
if ((inst = calloc(1, sizeof(ROUTER_INSTANCE))) == NULL) {
|
||||
return NULL;
|
||||
@ -231,10 +238,53 @@ int i, n;
|
||||
}
|
||||
inst->servers[n]->server = server;
|
||||
inst->servers[n]->current_connection_count = 0;
|
||||
inst->servers[n]->weight = 100;
|
||||
n++;
|
||||
}
|
||||
inst->servers[n] = NULL;
|
||||
|
||||
if ((weightby = serviceGetWeightingParameter(service)) != NULL)
|
||||
{
|
||||
int total = 0;
|
||||
for (n = 0; inst->servers[n]; n++)
|
||||
{
|
||||
backend = inst->servers[n];
|
||||
total += atoi(serverGetParameter(backend->server,
|
||||
weightby));
|
||||
}
|
||||
if (total == 0)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
||||
"WARNING: Weighting Parameter for service '%s' "
|
||||
"will be ignored as no servers have values "
|
||||
"for the parameter '%s'.\n",
|
||||
service->name, weightby)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (n = 0; inst->servers[n]; n++)
|
||||
{
|
||||
int perc;
|
||||
backend = inst->servers[n];
|
||||
perc = (atoi(serverGetParameter(backend->server,
|
||||
weightby)) * 100) / total;
|
||||
backend->weight = perc;
|
||||
if (perc == 0)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"Server '%s' has no value "
|
||||
"for weighting parameter '%s', "
|
||||
"no queries will be routed to "
|
||||
"this server.\n",
|
||||
server->unique_name,
|
||||
weightby)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the options
|
||||
*/
|
||||
@ -262,11 +312,11 @@ int i, n;
|
||||
else
|
||||
{
|
||||
LOGIF(LM, (skygw_log_write(
|
||||
LOGFILE_MESSAGE,
|
||||
"* Warning : Unsupported router "
|
||||
"option \'%s\' for readconnroute. "
|
||||
"Expected router options are "
|
||||
"[slave|master|synced]",
|
||||
LOGFILE_MESSAGE,
|
||||
"* Warning : Unsupported router "
|
||||
"option \'%s\' for readconnroute. "
|
||||
"Expected router options are "
|
||||
"[slave|master|synced]",
|
||||
options[i])));
|
||||
}
|
||||
}
|
||||
@ -299,7 +349,7 @@ ROUTER_INSTANCE *inst = (ROUTER_INSTANCE *)instance;
|
||||
ROUTER_CLIENT_SES *client_rses;
|
||||
BACKEND *candidate = NULL;
|
||||
int i;
|
||||
int master_host = -1;
|
||||
BACKEND *master_host = NULL;
|
||||
|
||||
LOGIF(LD, (skygw_log_write_flush(
|
||||
LOGFILE_DEBUG,
|
||||
@ -321,6 +371,11 @@ int master_host = -1;
|
||||
client_rses->rses_chk_tail = CHK_NUM_ROUTER_SES;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Find the Master host from available servers
|
||||
*/
|
||||
master_host = get_root_master(inst->servers);
|
||||
|
||||
/**
|
||||
* Find a backend server to connect to. This is the extent of the
|
||||
* load balancing algorithm we need to implement for this simple
|
||||
@ -356,36 +411,60 @@ int master_host = -1;
|
||||
if (SERVER_IN_MAINT(inst->servers[i]->server))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If router_options=slave, get the running master
|
||||
* It will be used if there are no running slaves at all
|
||||
*/
|
||||
if (inst->bitvalue == SERVER_SLAVE) {
|
||||
if (master_host < 0 && (SERVER_IS_MASTER(inst->servers[i]->server))) {
|
||||
master_host = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check server status bits against bitvalue from router_options */
|
||||
if (inst->servers[i] &&
|
||||
SERVER_IS_RUNNING(inst->servers[i]->server) &&
|
||||
(inst->servers[i]->server->status & inst->bitmask) ==
|
||||
inst->bitvalue)
|
||||
SERVER_IS_RUNNING(inst->servers[i]->server) &&
|
||||
(inst->servers[i]->server->status & inst->bitmask & inst->bitvalue))
|
||||
{
|
||||
if (master_host) {
|
||||
if (inst->servers[i] == master_host && (inst->bitvalue & SERVER_SLAVE)) {
|
||||
/* skip root Master here, as it could also be slave of an external server
|
||||
* that is not in the configuration.
|
||||
* Intermediate masters (Relay Servers) are also slave and will be selected
|
||||
* as Slave(s)
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
if (inst->servers[i] == master_host && (inst->bitvalue & SERVER_MASTER)) {
|
||||
/* If option is "master" return only the root Master as there
|
||||
* could be intermediate masters (Relay Servers)
|
||||
* and they must not be selected.
|
||||
*/
|
||||
|
||||
candidate = master_host;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* master_host is NULL, no master server.
|
||||
* If requested router_option is 'master'
|
||||
* candidate wll be NULL.
|
||||
*/
|
||||
if (inst->bitvalue & SERVER_MASTER) {
|
||||
candidate = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no candidate set, set first running server as
|
||||
our initial candidate server */
|
||||
if (candidate == NULL)
|
||||
{
|
||||
candidate = inst->servers[i];
|
||||
}
|
||||
else if (inst->servers[i]->current_connection_count <
|
||||
candidate->current_connection_count)
|
||||
else if ((inst->servers[i]->current_connection_count
|
||||
* 100) / inst->servers[i]->weight <
|
||||
(candidate->current_connection_count *
|
||||
100) / candidate->weight)
|
||||
{
|
||||
/* This running server has fewer
|
||||
connections, set it as a new candidate */
|
||||
candidate = inst->servers[i];
|
||||
}
|
||||
else if (inst->servers[i]->current_connection_count ==
|
||||
candidate->current_connection_count &&
|
||||
else if ((inst->servers[i]->current_connection_count
|
||||
* 100) / inst->servers[i]->weight ==
|
||||
(candidate->current_connection_count *
|
||||
100) / candidate->weight &&
|
||||
inst->servers[i]->server->stats.n_connections <
|
||||
candidate->server->stats.n_connections)
|
||||
{
|
||||
@ -403,8 +482,8 @@ int master_host = -1;
|
||||
* Otherwise, just clean up and return NULL
|
||||
*/
|
||||
if (!candidate) {
|
||||
if (master_host >= 0) {
|
||||
candidate = inst->servers[master_host];
|
||||
if (master_host) {
|
||||
candidate = master_host;
|
||||
} else {
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
@ -649,6 +728,8 @@ diagnostics(ROUTER *router, DCB *dcb)
|
||||
ROUTER_INSTANCE *router_inst = (ROUTER_INSTANCE *)router;
|
||||
ROUTER_CLIENT_SES *session;
|
||||
int i = 0;
|
||||
BACKEND *backend;
|
||||
char *weightby;
|
||||
|
||||
spinlock_acquire(&router_inst->lock);
|
||||
session = router_inst->connections;
|
||||
@ -664,6 +745,24 @@ int i = 0;
|
||||
dcb_printf(dcb, "\tCurrent no. of router sessions: %d\n", i);
|
||||
dcb_printf(dcb, "\tNumber of queries forwarded: %d\n",
|
||||
router_inst->stats.n_queries);
|
||||
if ((weightby = serviceGetWeightingParameter(router_inst->service))
|
||||
!= NULL)
|
||||
{
|
||||
dcb_printf(dcb, "\tConnection distribution based on %s "
|
||||
"server parameter.\n",
|
||||
weightby);
|
||||
dcb_printf(dcb,
|
||||
"\t\tServer Target %% Connections\n");
|
||||
for (i = 0; router_inst->servers[i]; i++)
|
||||
{
|
||||
backend = router_inst->servers[i];
|
||||
dcb_printf(dcb, "\t\t%-20s %3d%% %d\n",
|
||||
backend->server->unique_name,
|
||||
backend->weight,
|
||||
backend->current_connection_count);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -706,12 +805,12 @@ clientReply(
|
||||
*/
|
||||
static void
|
||||
handleError(
|
||||
ROUTER *instance,
|
||||
void *router_session,
|
||||
GWBUF *errbuf,
|
||||
DCB *backend_dcb,
|
||||
int action,
|
||||
bool *succp)
|
||||
ROUTER *instance,
|
||||
void *router_session,
|
||||
GWBUF *errbuf,
|
||||
DCB *backend_dcb,
|
||||
error_action_t action,
|
||||
bool *succp)
|
||||
{
|
||||
DCB *client = NULL;
|
||||
SESSION *session = backend_dcb->session;
|
||||
@ -785,3 +884,56 @@ static uint8_t getCapabilities(
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************
|
||||
* This routine return the root master server from MySQL replication tree
|
||||
* Get the root Master rule:
|
||||
*
|
||||
* (1) find server(s) with lowest replication depth level
|
||||
* (2) check for SERVER_MASTER bitvalue in those servers
|
||||
* Servers are checked even if they are in 'maintenance'
|
||||
* SERVER_IS_DOWN is the only status to skip.
|
||||
*
|
||||
* @param servers The list of servers
|
||||
* @return The Master found
|
||||
*
|
||||
*/
|
||||
|
||||
static BACKEND *get_root_master(BACKEND **servers) {
|
||||
int i = 0;
|
||||
BACKEND * master_host = NULL;
|
||||
|
||||
/* (1) find root server(s) with lowest replication depth level */
|
||||
for (i = 0; servers[i]; i++) {
|
||||
if (servers[i] && (! SERVER_IS_DOWN(servers[i]->server))) {
|
||||
if (master_host && servers[i]->server->depth < master_host->server->depth) {
|
||||
master_host = servers[i];
|
||||
} else {
|
||||
if (master_host == NULL) {
|
||||
master_host = servers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (2) get the status of server(s) with lowest replication level and check it against SERVER_MASTER bitvalue */
|
||||
if (master_host) {
|
||||
int found = 0;
|
||||
for (i = 0; servers[i]; i++) {
|
||||
if (servers[i] && (! SERVER_IS_DOWN(servers[i]->server)) && (servers[i]->server->depth == master_host->server->depth)) {
|
||||
if (servers[i]->server->status & SERVER_MASTER) {
|
||||
master_host = servers[i];
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
master_host = NULL;
|
||||
|
||||
/* return NULL if the server is SERVER_IN_MAINT */
|
||||
if (found && SERVER_IN_MAINT(master_host->server))
|
||||
master_host = NULL;
|
||||
}
|
||||
|
||||
return master_host;
|
||||
}
|
||||
|
@ -247,6 +247,10 @@ static bool handle_error_new_connection(
|
||||
GWBUF* errmsg);
|
||||
static bool handle_error_reply_client(SESSION* ses, GWBUF* errmsg);
|
||||
|
||||
static BACKEND *get_root_master(
|
||||
backend_ref_t *servers,
|
||||
int router_nservers);
|
||||
|
||||
static SPINLOCK instlock;
|
||||
static ROUTER_INSTANCE* instances;
|
||||
|
||||
@ -621,7 +625,8 @@ static void* newSession(
|
||||
}
|
||||
/** Copy backend pointers to router session. */
|
||||
client_rses->rses_master_ref = master_ref;
|
||||
ss_dassert(SERVER_IS_MASTER(master_ref->bref_backend->backend_server));
|
||||
/* assert with master_host */
|
||||
ss_dassert(master_ref && (master_ref->bref_backend->backend_server && SERVER_MASTER));
|
||||
client_rses->rses_backend_ref = backend_ref;
|
||||
client_rses->rses_nbackends = router_nservers; /*< # of backend servers */
|
||||
client_rses->rses_capabilities = RCAP_TYPE_STMT_INPUT;
|
||||
@ -802,6 +807,7 @@ static bool get_dcb(
|
||||
int smallest_nconn = -1;
|
||||
int i;
|
||||
bool succp = false;
|
||||
BACKEND *master_host = NULL;
|
||||
|
||||
CHK_CLIENT_RSES(rses);
|
||||
ss_dassert(p_dcb != NULL && *(p_dcb) == NULL);
|
||||
@ -812,13 +818,18 @@ static bool get_dcb(
|
||||
}
|
||||
backend_ref = rses->rses_backend_ref;
|
||||
|
||||
/* get root master from availbal servers */
|
||||
master_host = get_root_master(backend_ref, rses->rses_nbackends);
|
||||
|
||||
if (btype == BE_SLAVE)
|
||||
{
|
||||
for (i=0; i<rses->rses_nbackends; i++)
|
||||
{
|
||||
BACKEND* b = backend_ref[i].bref_backend;
|
||||
/* check slave bit, also for relay servers (Master & Servers) */
|
||||
if (BREF_IS_IN_USE((&backend_ref[i])) &&
|
||||
SERVER_IS_SLAVE(b->backend_server) &&
|
||||
(SERVER_IS_SLAVE(b->backend_server) || SERVER_IS_RELAY_SERVER(b->backend_server)) &&
|
||||
(master_host != NULL && b->backend_server != master_host->backend_server) &&
|
||||
(smallest_nconn == -1 ||
|
||||
b->backend_conn_count < smallest_nconn))
|
||||
{
|
||||
@ -837,11 +848,12 @@ static bool get_dcb(
|
||||
{
|
||||
*p_dcb = backend_ref->bref_dcb;
|
||||
succp = true;
|
||||
|
||||
ss_dassert(backend_ref->bref_dcb->state != DCB_STATE_ZOMBIE);
|
||||
|
||||
ss_dassert(
|
||||
SERVER_IS_MASTER(backend_ref->bref_backend->backend_server) &&
|
||||
smallest_nconn == -1);
|
||||
(master_host && (backend_ref->bref_backend->backend_server == master_host->backend_server)) &&
|
||||
smallest_nconn == -1);
|
||||
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
@ -859,9 +871,9 @@ static bool get_dcb(
|
||||
for (i=0; i<rses->rses_nbackends; i++)
|
||||
{
|
||||
BACKEND* b = backend_ref[i].bref_backend;
|
||||
|
||||
|
||||
if (BREF_IS_IN_USE((&backend_ref[i])) &&
|
||||
(SERVER_IS_MASTER(b->backend_server)))
|
||||
(master_host && (b->backend_server == master_host->backend_server)))
|
||||
{
|
||||
*p_dcb = backend_ref[i].bref_dcb;
|
||||
succp = true;
|
||||
@ -1641,6 +1653,7 @@ static bool select_connect_backend_servers(
|
||||
const int min_nslaves = 0; /*< not configurable at the time */
|
||||
bool is_synced_master;
|
||||
int (*p)(const void *, const void *);
|
||||
BACKEND *master_host = NULL;
|
||||
|
||||
if (p_master_ref == NULL || backend_ref == NULL)
|
||||
{
|
||||
@ -1648,7 +1661,10 @@ static bool select_connect_backend_servers(
|
||||
succp = false;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
|
||||
/* get the root Master */
|
||||
master_host = get_root_master(backend_ref, router_nservers);
|
||||
|
||||
/** Master is already chosen and connected. This is slave failure case */
|
||||
if (*p_master_ref != NULL &&
|
||||
BREF_IS_IN_USE((*p_master_ref)))
|
||||
@ -1662,7 +1678,8 @@ static bool select_connect_backend_servers(
|
||||
|
||||
master_found = true;
|
||||
master_connected = true;
|
||||
ss_dassert(SERVER_IS_MASTER((*p_master_ref)->bref_backend->backend_server));
|
||||
/* assert with master_host */
|
||||
ss_dassert(master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER);
|
||||
}
|
||||
/** New session or master failure case */
|
||||
else
|
||||
@ -1713,8 +1730,9 @@ static bool select_connect_backend_servers(
|
||||
b->backend_conn_count)));
|
||||
}
|
||||
#endif
|
||||
/* assert with master_host */
|
||||
ss_dassert(!master_connected ||
|
||||
SERVER_IS_MASTER((*p_master_ref)->bref_backend->backend_server));
|
||||
(master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER));
|
||||
/**
|
||||
* Sort the pointer list to servers according to connection counts. As
|
||||
* a consequence those backends having least connections are in the
|
||||
@ -1784,13 +1802,15 @@ static bool select_connect_backend_servers(
|
||||
b->backend_server->port,
|
||||
STRSRVSTATUS(b->backend_server),
|
||||
b->backend_server->stats.n_current_ops)));
|
||||
|
||||
|
||||
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 &&
|
||||
SERVER_IS_SLAVE(b->backend_server))
|
||||
(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;
|
||||
|
||||
@ -1848,7 +1868,8 @@ static bool select_connect_backend_servers(
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SERVER_IS_MASTER(b->backend_server))
|
||||
/* take the master_host for master */
|
||||
else if (master_host && (b->backend_server == master_host->backend_server))
|
||||
{
|
||||
*p_master_ref = &backend_ref[i];
|
||||
|
||||
@ -1915,8 +1936,9 @@ static bool select_connect_backend_servers(
|
||||
b->backend_server->port,
|
||||
b->backend_conn_count)));
|
||||
}
|
||||
/* assert with master_host */
|
||||
ss_dassert(!master_connected ||
|
||||
SERVER_IS_MASTER((*p_master_ref)->bref_backend->backend_server));
|
||||
(master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER));
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -2485,7 +2507,7 @@ static bool execute_sescmd_in_backend(
|
||||
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
|
||||
if (!sescmd_cursor_is_active(scur))
|
||||
{
|
||||
/** Cursor is left active when function returns. */
|
||||
@ -3060,9 +3082,7 @@ static bool handle_error_new_connection(
|
||||
DCB* client_dcb;
|
||||
client_dcb = ses->client;
|
||||
client_dcb->func.write(client_dcb, errmsg);
|
||||
#if 1
|
||||
bref_clear_state(bref, BREF_WAITING_RESULT);
|
||||
#endif
|
||||
}
|
||||
bref_clear_state(bref, BREF_IN_USE);
|
||||
bref_set_state(bref, BREF_CLOSED);
|
||||
@ -3257,7 +3277,6 @@ return_rc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static sescmd_cursor_t* backend_ref_get_sescmd_cursor (
|
||||
backend_ref_t* bref)
|
||||
{
|
||||
@ -3324,3 +3343,60 @@ static bool prep_stmt_drop(
|
||||
return true;
|
||||
}
|
||||
#endif /*< PREP_STMT_CACHING */
|
||||
|
||||
/********************************
|
||||
* This routine return the root master server from MySQL replication tree
|
||||
* Get the root Master rule:
|
||||
*
|
||||
* (1) find server(s) with lowest replication depth level
|
||||
* (2) check for SERVER_MASTER bitvalue in those servers
|
||||
* Servers are checked even if they are in 'maintenance'
|
||||
* SERVER_IS_DOWN is the only status to skip.
|
||||
*
|
||||
* @param servers The list of servers
|
||||
* @param The number of servers
|
||||
* @return The Master found
|
||||
*
|
||||
*/
|
||||
static BACKEND *get_root_master(backend_ref_t *servers, int router_nservers) {
|
||||
int i = 0;
|
||||
BACKEND * master_host = NULL;
|
||||
|
||||
/* (1) find root server(s) with lowest replication depth level */
|
||||
for (i = 0; i< router_nservers; i++) {
|
||||
BACKEND* b = NULL;
|
||||
b = servers[i].bref_backend;
|
||||
if (b && (! SERVER_IS_DOWN(b->backend_server))) {
|
||||
if (master_host && b->backend_server->depth < master_host->backend_server->depth) {
|
||||
master_host = b;
|
||||
} else {
|
||||
if (master_host == NULL) {
|
||||
master_host = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (2) get the status of server(s) with lowest replication level and check it against SERVER_MASTER bitvalue */
|
||||
if (master_host) {
|
||||
int found = 0;
|
||||
for (i = 0; i<router_nservers; i++) {
|
||||
BACKEND* b = NULL;
|
||||
b = servers[i].bref_backend;
|
||||
if (b && (! SERVER_IS_DOWN(b->backend_server)) && (b->backend_server->depth == master_host->backend_server->depth)) {
|
||||
if (b->backend_server->status & SERVER_MASTER) {
|
||||
master_host = b;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
master_host = NULL;
|
||||
|
||||
if (found && SERVER_IN_MAINT(master_host->backend_server))
|
||||
master_host = NULL;
|
||||
}
|
||||
|
||||
return master_host;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user