Added router_option slave_selection_criteria=[LEAST_GLOBAL_CONNECTIONS(default)|LEAST_BEHIND_MASTER] to readwritesplit section.
The option is reloadable in the same way as max_slave_connections parameter. Option value determines which sort function is called before to sort backend server pointers before selecting them and establishing connections to backends.
This commit is contained in:
@ -858,7 +858,9 @@ SERVER *server;
|
|||||||
char *auth;
|
char *auth;
|
||||||
char *enable_root_user;
|
char *enable_root_user;
|
||||||
|
|
||||||
enable_root_user = config_get_value(obj->parameters, "enable_root_user");
|
enable_root_user =
|
||||||
|
config_get_value(obj->parameters,
|
||||||
|
"enable_root_user");
|
||||||
|
|
||||||
user = config_get_value(obj->parameters,
|
user = config_get_value(obj->parameters,
|
||||||
"user");
|
"user");
|
||||||
|
|||||||
@ -50,9 +50,23 @@ typedef enum rses_property_type_t {
|
|||||||
RSES_PROP_TYPE_COUNT=RSES_PROP_TYPE_LAST+1
|
RSES_PROP_TYPE_COUNT=RSES_PROP_TYPE_LAST+1
|
||||||
} rses_property_type_t;
|
} rses_property_type_t;
|
||||||
|
|
||||||
|
typedef enum select_criteria {
|
||||||
|
UNDEFINED_CRITERIA=0,
|
||||||
|
LEAST_GLOBAL_CONNECTIONS,
|
||||||
|
DEFAULT_CRITERIA=LEAST_GLOBAL_CONNECTIONS,
|
||||||
|
LEAST_BEHIND_MASTER
|
||||||
|
} select_criteria_t;
|
||||||
|
|
||||||
|
|
||||||
/** default values for rwsplit configuration parameters */
|
/** default values for rwsplit configuration parameters */
|
||||||
#define CONFIG_MAX_SLAVE_CONN 1
|
#define CONFIG_MAX_SLAVE_CONN 1
|
||||||
|
|
||||||
|
#define GET_SELECT_CRITERIA(s) \
|
||||||
|
(strncmp(s,"LEAST_GLOBAL_CONNECTIONS", strlen("LEAST_GLOBAL_CONNECTIONS")) == 0 ? \
|
||||||
|
LEAST_GLOBAL_CONNECTIONS : ( \
|
||||||
|
strncmp(s,"LEAST_BEHIND_MASTER", strlen("LEAST_BEHIND_MASTER")) == 0 ? \
|
||||||
|
LEAST_BEHIND_MASTER : UNDEFINED_CRITERIA))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session variable command
|
* Session variable command
|
||||||
*/
|
*/
|
||||||
@ -144,6 +158,7 @@ typedef struct backend_ref_st {
|
|||||||
typedef struct rwsplit_config_st {
|
typedef struct rwsplit_config_st {
|
||||||
int rw_max_slave_conn_percent;
|
int rw_max_slave_conn_percent;
|
||||||
int rw_max_slave_conn_count;
|
int rw_max_slave_conn_count;
|
||||||
|
select_criteria_t rw_slave_select_criteria;
|
||||||
} rwsplit_config_t;
|
} rwsplit_config_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,11 @@ static void clientReply(
|
|||||||
DCB* backend_dcb);
|
DCB* backend_dcb);
|
||||||
static uint8_t getCapabilities (ROUTER* inst, void* router_session);
|
static uint8_t getCapabilities (ROUTER* inst, void* router_session);
|
||||||
|
|
||||||
int bref_cmp(
|
int bref_cmp_global_conn(
|
||||||
|
const void* bref1,
|
||||||
|
const void* bref2);
|
||||||
|
|
||||||
|
int bref_cmp_behind_master(
|
||||||
const void* bref1,
|
const void* bref1,
|
||||||
const void* bref2);
|
const void* bref2);
|
||||||
|
|
||||||
@ -79,6 +83,7 @@ static bool select_connect_backend_servers(
|
|||||||
backend_ref_t* backend_ref,
|
backend_ref_t* backend_ref,
|
||||||
int router_nservers,
|
int router_nservers,
|
||||||
int max_nslaves,
|
int max_nslaves,
|
||||||
|
select_criteria_t select_criteria,
|
||||||
SESSION* session,
|
SESSION* session,
|
||||||
ROUTER_INSTANCE* router);
|
ROUTER_INSTANCE* router);
|
||||||
|
|
||||||
@ -87,6 +92,11 @@ static bool get_dcb(
|
|||||||
ROUTER_CLIENT_SES* rses,
|
ROUTER_CLIENT_SES* rses,
|
||||||
backend_type_t btype);
|
backend_type_t btype);
|
||||||
|
|
||||||
|
static void rwsplit_process_options(
|
||||||
|
ROUTER_INSTANCE* router,
|
||||||
|
char** options);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static ROUTER_OBJECT MyObject = {
|
static ROUTER_OBJECT MyObject = {
|
||||||
createInstance,
|
createInstance,
|
||||||
@ -282,15 +292,6 @@ static ROUTER* createInstance(
|
|||||||
free(router);
|
free(router);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options != NULL)
|
|
||||||
{
|
|
||||||
LOGIF(LM, (skygw_log_write(
|
|
||||||
LOGFILE_MESSAGE,
|
|
||||||
"Router options supplied to read/write statement router "
|
|
||||||
"module but none are supported. The options will be "
|
|
||||||
"ignored.")));
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Create an array of the backend servers in the router structure to
|
* Create an array of the backend servers in the router structure to
|
||||||
* maintain a count of the number of connections to each
|
* maintain a count of the number of connections to each
|
||||||
@ -335,30 +336,20 @@ static ROUTER* createInstance(
|
|||||||
router->bitvalue = 0;
|
router->bitvalue = 0;
|
||||||
if (options)
|
if (options)
|
||||||
{
|
{
|
||||||
for (i = 0; options[i]; i++)
|
rwsplit_process_options(router, options);
|
||||||
{
|
|
||||||
if (!strcasecmp(options[i], "synced"))
|
|
||||||
{
|
|
||||||
router->bitmask |= (SERVER_JOINED);
|
|
||||||
router->bitvalue |= SERVER_JOINED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
|
||||||
LOGFILE_ERROR,
|
|
||||||
"Warning : Unsupported "
|
|
||||||
"router option \"%s\" "
|
|
||||||
"for readwritesplit router.",
|
|
||||||
options[i])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Set default value for max_slave_connections.
|
* Set default value for max_slave_connections and for slave selection
|
||||||
* If parameter is set in config file this setting will be overwritten.
|
* criteria. If parameter is set in config file max_slave_connections
|
||||||
|
* will be overwritten.
|
||||||
*/
|
*/
|
||||||
router->rwsplit_config.rw_max_slave_conn_count = CONFIG_MAX_SLAVE_CONN;
|
router->rwsplit_config.rw_max_slave_conn_count = CONFIG_MAX_SLAVE_CONN;
|
||||||
|
|
||||||
|
if (router->rwsplit_config.rw_slave_select_criteria == UNDEFINED_CRITERIA)
|
||||||
|
{
|
||||||
|
router->rwsplit_config.rw_slave_select_criteria = DEFAULT_CRITERIA;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy all config parameters from service to router instance.
|
* Copy all config parameters from service to router instance.
|
||||||
* Finally, copy version number to indicate that configs match.
|
* Finally, copy version number to indicate that configs match.
|
||||||
@ -435,6 +426,8 @@ static void* newSession(
|
|||||||
param = param->next;
|
param = param->next;
|
||||||
}
|
}
|
||||||
router->rwsplit_version = router->service->svc_config_version;
|
router->rwsplit_version = router->service->svc_config_version;
|
||||||
|
/** Read options */
|
||||||
|
rwsplit_process_options(router, router->service->routerOptions);
|
||||||
}
|
}
|
||||||
/** Copy config struct from router instance */
|
/** Copy config struct from router instance */
|
||||||
client_rses->rses_config = router->rwsplit_config;
|
client_rses->rses_config = router->rwsplit_config;
|
||||||
@ -559,6 +552,7 @@ static void* newSession(
|
|||||||
backend_ref,
|
backend_ref,
|
||||||
router_nservers,
|
router_nservers,
|
||||||
max_nslaves,
|
max_nslaves,
|
||||||
|
client_rses->rses_config.rw_slave_select_criteria,
|
||||||
session,
|
session,
|
||||||
router);
|
router);
|
||||||
|
|
||||||
@ -1306,7 +1300,7 @@ lock_failed:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int bref_cmp(
|
int bref_cmp_global_conn(
|
||||||
const void* bref1,
|
const void* bref1,
|
||||||
const void* bref2)
|
const void* bref2)
|
||||||
{
|
{
|
||||||
@ -1317,6 +1311,13 @@ int bref_cmp(
|
|||||||
((b1->backend_conn_count > b2->backend_conn_count) ? 1 : 0));
|
((b1->backend_conn_count > b2->backend_conn_count) ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bref_cmp_behind_master(
|
||||||
|
const void* bref1,
|
||||||
|
const void* bref2)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @node Search suitable backend servers from those of router instance.
|
* @node Search suitable backend servers from those of router instance.
|
||||||
*
|
*
|
||||||
@ -1352,6 +1353,7 @@ static bool select_connect_backend_servers(
|
|||||||
backend_ref_t* backend_ref,
|
backend_ref_t* backend_ref,
|
||||||
int router_nservers,
|
int router_nservers,
|
||||||
int max_nslaves,
|
int max_nslaves,
|
||||||
|
select_criteria_t select_criteria,
|
||||||
SESSION* session,
|
SESSION* session,
|
||||||
ROUTER_INSTANCE* router)
|
ROUTER_INSTANCE* router)
|
||||||
{
|
{
|
||||||
@ -1363,6 +1365,7 @@ static bool select_connect_backend_servers(
|
|||||||
int i;
|
int i;
|
||||||
const int min_nslaves = 0; /*< not configurable at the time */
|
const int min_nslaves = 0; /*< not configurable at the time */
|
||||||
bool is_synced_master;
|
bool is_synced_master;
|
||||||
|
int (*p)(const void *, const void *);
|
||||||
|
|
||||||
if (p_master_ref == NULL || backend_ref == NULL)
|
if (p_master_ref == NULL || backend_ref == NULL)
|
||||||
{
|
{
|
||||||
@ -1370,6 +1373,22 @@ static bool select_connect_backend_servers(
|
|||||||
succp = false;
|
succp = false;
|
||||||
goto return_succp;
|
goto return_succp;
|
||||||
}
|
}
|
||||||
|
/** Check slave selection criteria and set compare function */
|
||||||
|
switch (select_criteria) {
|
||||||
|
case LEAST_GLOBAL_CONNECTIONS:
|
||||||
|
p = bref_cmp_global_conn;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LEAST_BEHIND_MASTER:
|
||||||
|
p = bref_cmp_behind_master;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
succp = false;
|
||||||
|
goto return_succp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (router->bitvalue != 0) /*< 'synced' is the only bitvalue in rwsplit */
|
if (router->bitvalue != 0) /*< 'synced' is the only bitvalue in rwsplit */
|
||||||
{
|
{
|
||||||
@ -1397,7 +1416,7 @@ static bool select_connect_backend_servers(
|
|||||||
* a consequence those backends having least connections are in the
|
* a consequence those backends having least connections are in the
|
||||||
* beginning of the list.
|
* beginning of the list.
|
||||||
*/
|
*/
|
||||||
qsort((void *)backend_ref, (size_t)router_nservers, sizeof(backend_ref_t), bref_cmp);
|
qsort((void *)backend_ref, (size_t)router_nservers, sizeof(backend_ref_t), p);
|
||||||
|
|
||||||
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "Servers and conns after ordering:")));
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "Servers and conns after ordering:")));
|
||||||
|
|
||||||
@ -2324,3 +2343,39 @@ return_succp:
|
|||||||
return succp;
|
return succp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rwsplit_process_options(
|
||||||
|
ROUTER_INSTANCE* router,
|
||||||
|
char** options)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char* value;
|
||||||
|
|
||||||
|
for (i = 0; options[i]; i++)
|
||||||
|
{
|
||||||
|
if ((value = strchr(options[i], '=')) == NULL)
|
||||||
|
{
|
||||||
|
LOGIF(LE, (skygw_log_write(
|
||||||
|
LOGFILE_ERROR, "Warning : Unsupported "
|
||||||
|
"router option \"%s\" for "
|
||||||
|
"readwritesplit router.",
|
||||||
|
options[i])));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*value = 0;
|
||||||
|
value++;
|
||||||
|
if (strcmp(options[i], "slave_selection_criteria") == 0)
|
||||||
|
{
|
||||||
|
router->rwsplit_config.rw_slave_select_criteria =
|
||||||
|
GET_SELECT_CRITERIA(value);
|
||||||
|
ss_dassert(
|
||||||
|
router->rwsplit_config.rw_slave_select_criteria ==
|
||||||
|
LEAST_GLOBAL_CONNECTIONS ||
|
||||||
|
router->rwsplit_config.rw_slave_select_criteria ==
|
||||||
|
LEAST_BEHIND_MASTER ||
|
||||||
|
router->rwsplit_config.rw_slave_select_criteria ==
|
||||||
|
UNDEFINED_CRITERIA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user