config.h: Added enumerated types MAX_RLAG_AVAILABLE and MAX_RLAG_UNDEFINED to be used instead of magic numbers as max_slave_replication_lag values.
readwritesplit.h: Added TARGET_RLAG_MAX to the list of hint targets. It is used in case of hint max_slave_replication_lag=<value> readwritesplit.c: get_dcb is called when readwritesplit router chooses target backend for a query. Backend is selected from those the router has connection to. get_dcb now takes additional parameters, name and max_rlag. Name is used if there is a hint route to server <server name>. max_rlag is used for hint max_slave_replication_lag=<value> or if it doesn't exist, then for configure parameter max_slave_replication_lag=<configured value> or if both are absent, ignored.
This commit is contained in:
@ -46,6 +46,8 @@ typedef enum {
|
|||||||
BOOL_TYPE = 0x08
|
BOOL_TYPE = 0x08
|
||||||
} config_param_type_t;
|
} config_param_type_t;
|
||||||
|
|
||||||
|
enum {MAX_RLAG_NOT_AVAILABLE=-1, MAX_RLAG_UNDEFINED=-2};
|
||||||
|
|
||||||
#define PARAM_IS_TYPE(p,t) ((p) & (t))
|
#define PARAM_IS_TYPE(p,t) ((p) & (t))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,13 +75,15 @@ typedef enum {
|
|||||||
TARGET_MASTER = 0x01,
|
TARGET_MASTER = 0x01,
|
||||||
TARGET_SLAVE = 0x02,
|
TARGET_SLAVE = 0x02,
|
||||||
TARGET_NAMED_SERVER = 0x04,
|
TARGET_NAMED_SERVER = 0x04,
|
||||||
TARGET_ALL = 0x08
|
TARGET_ALL = 0x08,
|
||||||
|
TARGET_RLAG_MAX = 0x10
|
||||||
} route_target_t;
|
} route_target_t;
|
||||||
|
|
||||||
#define TARGET_IS_MASTER(t) (t & TARGET_MASTER)
|
#define TARGET_IS_MASTER(t) (t & TARGET_MASTER)
|
||||||
#define TARGET_IS_SLAVE(t) (t & TARGET_SLAVE)
|
#define TARGET_IS_SLAVE(t) (t & TARGET_SLAVE)
|
||||||
#define TARGET_IS_NAMED_SERVER(t) (t & TARGET_NAMED_SERVER)
|
#define TARGET_IS_NAMED_SERVER(t) (t & TARGET_NAMED_SERVER)
|
||||||
#define TARGET_IS_ALL(t) (t & TARGET_ALL)
|
#define TARGET_IS_ALL(t) (t & TARGET_ALL)
|
||||||
|
#define TARGET_IS_RLAG_MAX(t) (t & TARGET_RLAG_MAX)
|
||||||
|
|
||||||
typedef struct rses_property_st rses_property_t;
|
typedef struct rses_property_st rses_property_t;
|
||||||
typedef struct router_client_session ROUTER_CLIENT_SES;
|
typedef struct router_client_session ROUTER_CLIENT_SES;
|
||||||
|
@ -160,7 +160,8 @@ static bool get_dcb(
|
|||||||
DCB** dcb,
|
DCB** dcb,
|
||||||
ROUTER_CLIENT_SES* rses,
|
ROUTER_CLIENT_SES* rses,
|
||||||
backend_type_t btype,
|
backend_type_t btype,
|
||||||
char* name);
|
char* name,
|
||||||
|
int max_rlag);
|
||||||
|
|
||||||
static void rwsplit_process_router_options(
|
static void rwsplit_process_router_options(
|
||||||
ROUTER_INSTANCE* router,
|
ROUTER_INSTANCE* router,
|
||||||
@ -388,7 +389,7 @@ static void refreshInstance(
|
|||||||
* used in slave selection.
|
* used in slave selection.
|
||||||
*/
|
*/
|
||||||
if (!rlag_enabled)
|
if (!rlag_enabled)
|
||||||
{
|
{
|
||||||
if (rlag_limited)
|
if (rlag_limited)
|
||||||
{
|
{
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
@ -934,7 +935,8 @@ static bool get_dcb(
|
|||||||
DCB** p_dcb,
|
DCB** p_dcb,
|
||||||
ROUTER_CLIENT_SES* rses,
|
ROUTER_CLIENT_SES* rses,
|
||||||
backend_type_t btype,
|
backend_type_t btype,
|
||||||
char* name)
|
char* name,
|
||||||
|
int max_rlag)
|
||||||
{
|
{
|
||||||
backend_ref_t* backend_ref;
|
backend_ref_t* backend_ref;
|
||||||
int smallest_nconn = -1;
|
int smallest_nconn = -1;
|
||||||
@ -951,7 +953,7 @@ static bool get_dcb(
|
|||||||
}
|
}
|
||||||
backend_ref = rses->rses_backend_ref;
|
backend_ref = rses->rses_backend_ref;
|
||||||
|
|
||||||
/* get root master from available servers */
|
/** get root master from available servers */
|
||||||
master_host = get_root_master(backend_ref, rses->rses_nbackends);
|
master_host = get_root_master(backend_ref, rses->rses_nbackends);
|
||||||
|
|
||||||
if (btype == BE_SLAVE)
|
if (btype == BE_SLAVE)
|
||||||
@ -975,6 +977,9 @@ static bool get_dcb(
|
|||||||
b->backend_server->unique_name,
|
b->backend_server->unique_name,
|
||||||
MIN(strlen(b->backend_server->unique_name), PATH_MAX)) == 0) &&
|
MIN(strlen(b->backend_server->unique_name), PATH_MAX)) == 0) &&
|
||||||
master_host != NULL &&
|
master_host != NULL &&
|
||||||
|
(max_rlag == MAX_RLAG_UNDEFINED ||
|
||||||
|
(b->backend_server->rlag != MAX_RLAG_NOT_AVAILABLE &&
|
||||||
|
b->backend_server->rlag <= max_rlag)) &&
|
||||||
(SERVER_IS_SLAVE(b->backend_server) ||
|
(SERVER_IS_SLAVE(b->backend_server) ||
|
||||||
SERVER_IS_RELAY_SERVER(b->backend_server) ||
|
SERVER_IS_RELAY_SERVER(b->backend_server) ||
|
||||||
SERVER_IS_MASTER(b->backend_server)))
|
SERVER_IS_MASTER(b->backend_server)))
|
||||||
@ -1004,6 +1009,9 @@ static bool get_dcb(
|
|||||||
if (BREF_IS_IN_USE((&backend_ref[i])) &&
|
if (BREF_IS_IN_USE((&backend_ref[i])) &&
|
||||||
master_host != NULL &&
|
master_host != NULL &&
|
||||||
b->backend_server != master_host->backend_server &&
|
b->backend_server != master_host->backend_server &&
|
||||||
|
(max_rlag == MAX_RLAG_UNDEFINED ||
|
||||||
|
(b->backend_server->rlag != MAX_RLAG_NOT_AVAILABLE &&
|
||||||
|
b->backend_server->rlag <= max_rlag)) &&
|
||||||
(SERVER_IS_SLAVE(b->backend_server) ||
|
(SERVER_IS_SLAVE(b->backend_server) ||
|
||||||
SERVER_IS_RELAY_SERVER(b->backend_server)) &&
|
SERVER_IS_RELAY_SERVER(b->backend_server)) &&
|
||||||
(smallest_nconn == -1 ||
|
(smallest_nconn == -1 ||
|
||||||
@ -1100,8 +1108,25 @@ static route_target_t get_route_target (
|
|||||||
{
|
{
|
||||||
/** not implemented */
|
/** not implemented */
|
||||||
}
|
}
|
||||||
|
else if (hint->type == HINT_PARAMETER)
|
||||||
|
{
|
||||||
|
if (strncasecmp(
|
||||||
|
(char *)hint->data,
|
||||||
|
"max_replication_lag",
|
||||||
|
strlen("max_replication_lag")) == 0)
|
||||||
|
{
|
||||||
|
target |= TARGET_RLAG_MAX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Warning : Unknown routing parameter hint : %s",
|
||||||
|
(char *)hint->data)));
|
||||||
|
}
|
||||||
|
}
|
||||||
hint = hint->next;
|
hint = hint->next;
|
||||||
}
|
} /*< while (hint != NULL) */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1343,6 +1368,7 @@ static int routeQuery(
|
|||||||
bool succp = true;
|
bool succp = true;
|
||||||
HINT* hint;
|
HINT* hint;
|
||||||
char* named_server = NULL;
|
char* named_server = NULL;
|
||||||
|
int rlag_max = MAX_RLAG_UNDEFINED;
|
||||||
|
|
||||||
if (router_cli_ses->rses_transaction_active) /*< all to master */
|
if (router_cli_ses->rses_transaction_active) /*< all to master */
|
||||||
{
|
{
|
||||||
@ -1362,25 +1388,45 @@ static int routeQuery(
|
|||||||
|
|
||||||
if (TARGET_IS_SLAVE(route_target))
|
if (TARGET_IS_SLAVE(route_target))
|
||||||
{
|
{
|
||||||
if (TARGET_IS_NAMED_SERVER(route_target))
|
if (TARGET_IS_NAMED_SERVER(route_target) ||
|
||||||
|
TARGET_IS_RLAG_MAX(route_target))
|
||||||
{
|
{
|
||||||
hint = querybuf->hint;
|
hint = querybuf->hint;
|
||||||
|
|
||||||
while (hint != NULL &&
|
while (hint != NULL)
|
||||||
hint->type != HINT_ROUTE_TO_NAMED_SERVER)
|
|
||||||
{
|
{
|
||||||
|
if (hint->type == HINT_ROUTE_TO_NAMED_SERVER)
|
||||||
|
{
|
||||||
|
named_server = hint->data;
|
||||||
|
}
|
||||||
|
else if (hint->type == HINT_PARAMETER &&
|
||||||
|
(strncasecmp(
|
||||||
|
(char *)hint->data,
|
||||||
|
"max_replication_lag",
|
||||||
|
strlen("max_replication_lag")) == 0))
|
||||||
|
{
|
||||||
|
int val = (int) strtol((char *)hint->data,
|
||||||
|
(char **)NULL, 10);
|
||||||
|
|
||||||
|
if (val != 0 || errno == 0)
|
||||||
|
{
|
||||||
|
rlag_max = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
hint = hint->next;
|
hint = hint->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hint != NULL)
|
|
||||||
{
|
|
||||||
named_server = hint->data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rlag_max == MAX_RLAG_UNDEFINED) /*< no rlag max hint, use config */
|
||||||
|
{
|
||||||
|
rlag_max = rses_get_max_replication_lag(router_cli_ses);
|
||||||
|
}
|
||||||
|
|
||||||
succp = get_dcb(&target_dcb,
|
succp = get_dcb(&target_dcb,
|
||||||
router_cli_ses,
|
router_cli_ses,
|
||||||
BE_SLAVE,
|
BE_SLAVE,
|
||||||
named_server);
|
named_server,
|
||||||
|
rlag_max);
|
||||||
}
|
}
|
||||||
else if (TARGET_IS_MASTER(route_target))
|
else if (TARGET_IS_MASTER(route_target))
|
||||||
{
|
{
|
||||||
@ -1389,7 +1435,8 @@ static int routeQuery(
|
|||||||
succp = get_dcb(&master_dcb,
|
succp = get_dcb(&master_dcb,
|
||||||
router_cli_ses,
|
router_cli_ses,
|
||||||
BE_MASTER,
|
BE_MASTER,
|
||||||
NULL);
|
NULL,
|
||||||
|
MAX_RLAG_UNDEFINED);
|
||||||
}
|
}
|
||||||
target_dcb = master_dcb;
|
target_dcb = master_dcb;
|
||||||
}
|
}
|
||||||
@ -1964,7 +2011,9 @@ static bool select_connect_backend_servers(
|
|||||||
#endif
|
#endif
|
||||||
/* assert with master_host */
|
/* assert with master_host */
|
||||||
ss_dassert(!master_connected ||
|
ss_dassert(!master_connected ||
|
||||||
(master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER));
|
(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
|
* Sort the pointer list to servers according to connection counts. As
|
||||||
* a consequence those backends having least connections are in the
|
* a consequence those backends having least connections are in the
|
||||||
@ -2024,7 +2073,8 @@ static bool select_connect_backend_servers(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} /*< log only */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Choose at least 1+min_nslaves (master and slave) and at most 1+max_nslaves
|
* 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.
|
* servers from the sorted list. First master found is selected.
|
||||||
@ -2041,8 +2091,8 @@ static bool select_connect_backend_servers(
|
|||||||
{
|
{
|
||||||
/* check also for relay servers and don't take the master_host */
|
/* check also for relay servers and don't take the master_host */
|
||||||
if (slaves_found < max_nslaves &&
|
if (slaves_found < max_nslaves &&
|
||||||
(max_slave_rlag == -2 ||
|
(max_slave_rlag == MAX_RLAG_UNDEFINED ||
|
||||||
(b->backend_server->rlag != -1 && /*< information currently not available */
|
(b->backend_server->rlag != MAX_RLAG_NOT_AVAILABLE &&
|
||||||
b->backend_server->rlag <= max_slave_rlag)) &&
|
b->backend_server->rlag <= max_slave_rlag)) &&
|
||||||
(SERVER_IS_SLAVE(b->backend_server) || SERVER_IS_RELAY_SERVER(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)))
|
(master_host != NULL && (b->backend_server != master_host->backend_server)))
|
||||||
|
Reference in New Issue
Block a user