Merge branch 'Z3' into log_manager_test

Conflicts:
	server/modules/routing/readwritesplit/test/rwsplit.sh
This commit is contained in:
Markus Makela 2014-09-10 12:14:54 +03:00
commit f0bed1a8cc
9 changed files with 228 additions and 145 deletions

View File

@ -51,9 +51,8 @@ passwd=maxpwd
# enable_root_user=<0 or 1, default is 0>
# version_string=<specific string for server handshake,
# default is the MariaDB embedded library version>
#
# read_ses_variables_from_slaves=<Y|N> Default is Yes
# write_ses_variables_to_all=<Y|(N)> Default is No
#
# use_sql_variables_in=[master|all] (default all)
# router_options=<option[=value]>,<option[=value]>,...
# where value=[master|slave|synced]
#
@ -72,8 +71,7 @@ router=readwritesplit
servers=server1,server2,server3
user=maxuser
passwd=maxpwd
read_ses_variables_from_slaves=No
write_ses_variables_to_all=Yes
use_sql_variables_in=all
max_slave_connections=50%
max_slave_replication_lag=30
router_options=slave_selection_criteria=LEAST_BEHIND_MASTER

View File

@ -333,13 +333,20 @@ int error_count = 0;
param = config_get_param(obj->parameters,
"max_slave_connections");
succp = service_set_param_value(
obj->element,
param,
max_slave_conn_str,
COUNT_ATMOST,
(COUNT_TYPE|PERCENT_TYPE));
if (param == NULL)
{
succp = false;
}
else
{
succp = service_set_param_value(
obj->element,
param,
max_slave_conn_str,
COUNT_ATMOST,
(COUNT_TYPE|PERCENT_TYPE));
}
if (!succp)
{
LOGIF(LM, (skygw_log_write(
@ -365,13 +372,20 @@ int error_count = 0;
obj->parameters,
"max_slave_replication_lag");
succp = service_set_param_value(
obj->element,
param,
max_slave_rlag_str,
COUNT_ATMOST,
COUNT_TYPE);
if (param == NULL)
{
succp = false;
}
else
{
succp = service_set_param_value(
obj->element,
param,
max_slave_rlag_str,
COUNT_ATMOST,
COUNT_TYPE);
}
if (!succp)
{
LOGIF(LM, (skygw_log_write(
@ -389,60 +403,40 @@ int error_count = 0;
if (is_rwsplit)
{
CONFIG_PARAMETER* param;
char* write_sesvars_to_all;
char* read_sesvars_from_slaves;
char* use_sql_variables_in;
bool succp;
write_sesvars_to_all =
use_sql_variables_in =
config_get_value(obj->parameters,
"write_ses_variables_to_all");
"use_sql_variables_in");
if (write_sesvars_to_all != NULL)
if (use_sql_variables_in != NULL)
{
param = config_get_param(
obj->parameters,
"write_ses_variables_to_all");
succp = service_set_param_value(obj->element,
param,
write_sesvars_to_all,
COUNT_NONE,
BOOL_TYPE);
if (!succp)
"use_sql_variables_in");
if (param == NULL)
{
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"* Warning : invalid value type "
"for parameter \'%s.%s = %s\'\n\tExpected "
"type is <true/false> for write session "
"variables to all backends.",
((SERVICE*)obj->element)->name,
param->name,
param->value)));
succp = false;
}
}
read_sesvars_from_slaves =
config_get_value(
obj->parameters,
"read_ses_variables_from_slaves");
if (read_sesvars_from_slaves != NULL)
{
param = config_get_param(
obj->parameters,
"read_ses_variables_from_slaves");
succp = service_set_param_value(obj->element,
param,
read_sesvars_from_slaves,
COUNT_NONE,
BOOL_TYPE);
else
{
succp = service_set_param_value(obj->element,
param,
use_sql_variables_in,
COUNT_NONE,
SQLVAR_TARGET_TYPE);
}
if (!succp)
{
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"* Warning : invalid value type "
"for parameter \'%s.%s = %s\'\n\tExpected "
"type is <true/false> for write session "
"variables to all backends.",
"type is [master|all] for "
"use sql variables in.",
((SERVICE*)obj->element)->name,
param->name,
param->value)));
@ -896,7 +890,7 @@ bool config_get_valint(
{
bool succp = false;;
ss_dassert(ptype == COUNT_TYPE || ptype == PERCENT_TYPE);
ss_dassert((ptype == COUNT_TYPE || ptype == PERCENT_TYPE) && param != NULL);
while (param)
{
@ -933,8 +927,9 @@ bool config_get_valbool(
bool succp;
ss_dassert(ptype == BOOL_TYPE);
ss_dassert(param != NULL);
if (ptype != BOOL_TYPE)
if (ptype != BOOL_TYPE || param == NULL)
{
succp = false;
goto return_succp;
@ -958,6 +953,40 @@ return_succp:
}
bool config_get_valtarget(
target_t* val,
CONFIG_PARAMETER* param,
const char* name,
config_param_type_t ptype)
{
bool succp;
ss_dassert(ptype == SQLVAR_TARGET_TYPE);
ss_dassert(param != NULL);
if (ptype != SQLVAR_TARGET_TYPE || param == NULL)
{
succp = false;
goto return_succp;
}
while (param)
{
if (name == NULL || !strncmp(param->name, name, MAX_PARAM_LEN))
{
*val = param->qfd.valtarget;
succp = true;
goto return_succp;
}
param = param->next;
}
succp = false;
return_succp:
return succp;
}
CONFIG_PARAMETER* config_clone_param(
CONFIG_PARAMETER* param)
{
@ -1135,13 +1164,20 @@ SERVER *server;
param = config_get_param(obj->parameters,
"max_slave_connections");
succp = service_set_param_value(
service,
param,
max_slave_conn_str,
COUNT_ATMOST,
(PERCENT_TYPE|COUNT_TYPE));
if (param == NULL)
{
succp = false;
}
else
{
succp = service_set_param_value(
service,
param,
max_slave_conn_str,
COUNT_ATMOST,
(PERCENT_TYPE|COUNT_TYPE));
}
if (!succp)
{
LOGIF(LM, (skygw_log_write(
@ -1171,13 +1207,20 @@ SERVER *server;
obj->parameters,
"max_slave_replication_lag");
succp = service_set_param_value(
service,
param,
max_slave_rlag_str,
COUNT_ATMOST,
COUNT_TYPE);
if (param == NULL)
{
succp = false;
}
else
{
succp = service_set_param_value(
service,
param,
max_slave_rlag_str,
COUNT_ATMOST,
COUNT_TYPE);
}
if (!succp)
{
LOGIF(LM, (skygw_log_write(
@ -1426,8 +1469,7 @@ static char *service_params[] =
"enable_root_user",
"max_slave_connections",
"max_slave_replication_lag",
"write_ses_variables_to_all", /*< rwsplit only */
"read_ses_variables_from_slaves", /*< rwsplit only */
"use_sql_variables_in", /*< rwsplit only */
"version_string",
"filters",
NULL
@ -1551,7 +1593,11 @@ bool config_set_qualified_param(
param->qfd.valbool = *(bool *)val;
succp = true;
break;
case SQLVAR_TARGET_TYPE:
param->qfd.valtarget = *(target_t *)val;
succp = true;
break;
default:
succp = false;
break;

View File

@ -52,8 +52,6 @@
#include <poll.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <../../../mariadb-5.5.30/include/ft_global.h>
extern int lm_enabled_logfiles_bitmask;
@ -63,9 +61,17 @@ typedef struct typelib_st {
const char* tl_name;
const char** tl_p_elems;
} typelib_t;
/** Set of subsequent false,true pairs */
static const char* bool_strings[11] = {"FALSE", "TRUE", "OFF", "ON", "N", "Y", "0", "1", "NO", "YES", 0};
typelib_t bool_type = {array_nelems(bool_strings)-1, "bool_type", bool_strings};
static const char* bool_strings[11]= {"FALSE", "TRUE", "OFF", "ON", "N", "Y", "0", "1", "NO", "YES", 0};
typelib_t bool_type = {array_nelems(bool_strings)-1, "bool_type", bool_strings};
/** List of valid values */
static const char* sqlvar_target_strings[4] = {"MASTER", "ALL", 0};
typelib_t sqlvar_target_type = {
array_nelems(sqlvar_target_strings)-1,
"sqlvar_target_type",
sqlvar_target_strings
};
static SPINLOCK service_spin = SPINLOCK_INIT;
static SERVICE *allServices = NULL;
@ -1021,10 +1027,11 @@ bool service_set_param_value (
count_spec_t count_spec,
config_param_type_t type)
{
char* p;
int valint;
bool valbool;
bool succp = true;
char* p;
int valint;
bool valbool;
target_t valtarget;
bool succp = true;
if (PARAM_IS_TYPE(type,PERCENT_TYPE) ||PARAM_IS_TYPE(type,COUNT_TYPE))
{
@ -1113,6 +1120,34 @@ bool service_set_param_value (
succp = false;
}
}
else if (type == SQLVAR_TARGET_TYPE)
{
unsigned int rc;
rc = find_type(&sqlvar_target_type, valstr, strlen(valstr)+1);
if (rc > 0 && rc < 3)
{
succp = true;
if (rc == 1)
{
valtarget = TYPE_MASTER;
}
else if (rc == 2)
{
valtarget = TYPE_ALL;
}
/** add param to config */
config_set_qualified_param(param,
(void *)&valtarget,
SQLVAR_TARGET_TYPE);
}
else
{
succp = false;
}
}
if (succp)
{
service_add_qualified_param(service, param); /*< add param to svc */

View File

@ -39,13 +39,20 @@
enum {MAX_PARAM_LEN=256};
typedef enum {
UNDEFINED_TYPE = 0x00,
STRING_TYPE = 0x01,
COUNT_TYPE = 0x02,
PERCENT_TYPE = 0x04,
BOOL_TYPE = 0x08
UNDEFINED_TYPE = 0x00,
STRING_TYPE = 0x01,
COUNT_TYPE = 0x02,
PERCENT_TYPE = 0x04,
BOOL_TYPE = 0x08,
SQLVAR_TARGET_TYPE = 0x10
} config_param_type_t;
typedef enum {
TYPE_UNDEFINED = 0,
TYPE_MASTER,
TYPE_ALL
} target_t;
enum {MAX_RLAG_NOT_AVAILABLE=-1, MAX_RLAG_UNDEFINED=-2};
#define PARAM_IS_TYPE(p,t) ((p) & (t))
@ -61,6 +68,7 @@ typedef struct config_parameter {
int valcount; /*< int */
int valpercent; /*< int */
bool valbool; /*< bool */
target_t valtarget; /*< sql variable route target */
} qfd;
config_param_type_t qfd_param_type;
struct config_parameter *next; /**< Next pointer in the linked list */
@ -111,4 +119,9 @@ bool config_get_valbool(
const char* name, /*< if NULL examine current param only */
config_param_type_t ptype);
bool config_get_valtarget(
target_t* val,
CONFIG_PARAMETER* param,
const char* name, /*< if NULL examine current param only */
config_param_type_t ptype);
#endif

View File

@ -118,8 +118,7 @@ typedef enum select_criteria {
/** default values for rwsplit configuration parameters */
#define CONFIG_MAX_SLAVE_CONN 1
#define CONFIG_MAX_SLAVE_RLAG -1 /*< not used */
#define CONFIG_READ_SESVARS_FROM_SLAVES false
#define CONFIG_WRITE_SESVARS_TO_ALL true
#define CONFIG_SQL_VARIABLES_IN TYPE_ALL
#define GET_SELECT_CRITERIA(s) \
(strncmp(s,"LEAST_GLOBAL_CONNECTIONS", strlen("LEAST_GLOBAL_CONNECTIONS")) == 0 ? \
@ -234,9 +233,7 @@ typedef struct rwsplit_config_st {
int rw_max_slave_conn_count;
select_criteria_t rw_slave_select_criteria;
int rw_max_slave_replication_lag;
/** Route user- & system variable writes to all backends */
bool rw_write_sesvars_to_all;
/** Route queries including user- & system variables to slaves */
target_t rw_use_sql_variables_in;
bool rw_read_sesvars_from_slaves;
} rwsplit_config_t;

View File

@ -34,6 +34,7 @@
* 28/02/2014 Massimiliano Pinto Added: client IPv4 in dcb->ipv4 and inet_ntop for string representation
* 11/03/2014 Massimiliano Pinto Added: Unix socket support
* 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake
* 09/09/2014 Massimiliano Pinto Added: 777 permission for socket path
*
*/
#include <skygw_utils.h>
@ -985,6 +986,16 @@ int gw_MySQLListener(
return 0;
}
/* set permission for all users */
if (chmod(config_bind, 0777) < 0) {
fprintf(stderr,
"\n* chmod failed for %s due error %i, %s.\n\n",
config_bind,
errno,
strerror(errno));
}
break;
case AF_INET:

View File

@ -99,11 +99,10 @@ 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 (
skygw_query_type_t qtype,
bool read_sesvars_from_slaves,
bool write_sesvars_to_all,
bool trx_active,
HINT* hint);
skygw_query_type_t qtype,
bool trx_active,
target_t use_sql_variables_in,
HINT* hint);
static uint8_t getCapabilities (ROUTER* inst, void* router_session);
@ -383,6 +382,11 @@ static void refreshInstance(
while (param != NULL)
{
/** Catch unused parameter types */
ss_dassert(paramtype == COUNT_TYPE ||
paramtype == PERCENT_TYPE ||
paramtype == SQLVAR_TARGET_TYPE);
if (paramtype == COUNT_TYPE)
{
if (strncmp(param->name, "max_slave_connections", MAX_PARAM_LEN) == 0)
@ -431,35 +435,20 @@ static void refreshInstance(
}
}
}
if (paramtype == BOOL_TYPE)
else if (paramtype == SQLVAR_TARGET_TYPE)
{
if (strncmp(param->name,
"read_ses_variables_from_slaves",
"use_sql_variables_in",
MAX_PARAM_LEN) == 0)
{
bool val;
target_t valtarget;
bool succp;
succp = config_get_valbool(&val, param, NULL, paramtype);
succp = config_get_valtarget(&valtarget, param, NULL, paramtype);
if (succp)
{
router->rwsplit_config.rw_read_sesvars_from_slaves = val;
}
}
else if (strncmp(param->name,
"write_ses_variables_to_all",
MAX_PARAM_LEN) == 0)
{
bool val;
bool succp;
succp = config_get_valbool(&val, param, NULL, paramtype);
if (succp)
{
router->rwsplit_config.rw_write_sesvars_to_all = val;
router->rwsplit_config.rw_use_sql_variables_in = valtarget;
}
}
}
@ -693,16 +682,9 @@ createInstance(SERVICE *service, char **options)
}
router->rwsplit_version = service->svc_config_version;
/** Set default values */
router->rwsplit_config.rw_read_sesvars_from_slaves = CONFIG_READ_SESVARS_FROM_SLAVES;
router->rwsplit_config.rw_write_sesvars_to_all = CONFIG_WRITE_SESVARS_TO_ALL;
param = config_get_param(service->svc_config_param, "read_ses_variables_from_slaves");
if (param != NULL)
{
refreshInstance(router, param);
}
param = config_get_param(service->svc_config_param, "write_ses_variables_to_all");
router->rwsplit_config.rw_use_sql_variables_in = CONFIG_SQL_VARIABLES_IN;
param = config_get_param(service->svc_config_param, "use_sql_variable_in");
if (param != NULL)
{
refreshInstance(router, param);
@ -1185,8 +1167,7 @@ return_succp:
static route_target_t get_route_target (
skygw_query_type_t qtype,
bool trx_active,
bool read_ses_variables_from_slaves,
bool write_ses_variables_to_all,
target_t use_sql_variables_in,
HINT* hint)
{
route_target_t target;
@ -1197,7 +1178,7 @@ static route_target_t get_route_target (
(QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_STMT) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_NAMED_STMT) ||
/** Configured to allow writing variables to all nodes */
(write_ses_variables_to_all &&
(use_sql_variables_in == TYPE_ALL &&
(QUERY_IS_TYPE(qtype, QUERY_TYPE_SESSION_WRITE) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_WRITE)))))
{
@ -1217,7 +1198,7 @@ static route_target_t get_route_target (
/** First set expected targets before evaluating hints */
if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) ||
/** Configured to allow reading variables from slaves */
(read_ses_variables_from_slaves &&
(use_sql_variables_in == TYPE_ALL &&
(QUERY_IS_TYPE(qtype, QUERY_TYPE_USERVAR_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_SYSVAR_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_READ))))
@ -1226,13 +1207,12 @@ static route_target_t get_route_target (
}
else if (QUERY_IS_TYPE(qtype, QUERY_TYPE_EXEC_STMT) ||
/** Configured not to allow reading variables from slaves */
(!read_ses_variables_from_slaves &&
(use_sql_variables_in == TYPE_MASTER &&
(QUERY_IS_TYPE(qtype, QUERY_TYPE_USERVAR_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_SYSVAR_READ))))
{
target = TARGET_MASTER;
}
/** process routing hints */
while (hint != NULL)
{
@ -1306,13 +1286,13 @@ static route_target_t get_route_target (
QUERY_IS_TYPE(qtype, QUERY_TYPE_MASTER_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_SESSION_WRITE) ||
(QUERY_IS_TYPE(qtype, QUERY_TYPE_USERVAR_READ) &&
!write_ses_variables_to_all) ||
use_sql_variables_in == TYPE_MASTER) ||
(QUERY_IS_TYPE(qtype, QUERY_TYPE_SYSVAR_READ) &&
!write_ses_variables_to_all) ||
use_sql_variables_in == TYPE_MASTER) ||
(QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_READ) &&
!write_ses_variables_to_all) ||
use_sql_variables_in == TYPE_MASTER) ||
(QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_WRITE) &&
!write_ses_variables_to_all) ||
use_sql_variables_in == TYPE_MASTER) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_BEGIN_TRX) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_ENABLE_AUTOCOMMIT) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_DISABLE_AUTOCOMMIT) ||
@ -1422,7 +1402,11 @@ skygw_query_type_t is_read_tmp_table(
data = (MYSQL_session*)master_dcb->session->data;
dbname = (char*)data->db;
if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ))
if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_LOCAL_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_USERVAR_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_SYSVAR_READ) ||
QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_READ))
{
tbl = skygw_get_table_names(querybuf,&tsize,false);
@ -1771,8 +1755,7 @@ static int routeQuery(
*/
route_target = get_route_target(qtype,
router_cli_ses->rses_transaction_active,
router_cli_ses->rses_config.rw_read_sesvars_from_slaves,
router_cli_ses->rses_config.rw_write_sesvars_to_all,
router_cli_ses->rses_config.rw_use_sql_variables_in,
querybuf->hint);
if (TARGET_IS_ALL(route_target))

View File

@ -279,9 +279,9 @@ do
printf "."
fi
b=`$RUNCMD < $TINPUT 2>&1`
if [[ "`echo "$b"|grep -i 'null|error'`" != "" ]]
if [[ "`echo "$b"|grep -i 'null\|error'`" != "" ]]
then
err=`echo "$b" | grep -i 'null\|error'`
err=`echo "$b" | grep -i null\|error`
break
fi
done