Merge branch 'develop' of github.com:skysql/MaxScale into develop
Conflicts: server/modules/filter/regexfilter.c
This commit is contained in:
@ -423,9 +423,17 @@ static bool logmanager_init_nomutex(
|
|||||||
return_succp:
|
return_succp:
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
{
|
{
|
||||||
skygw_message_done(lm->lm_clientmes);
|
if (lm != NULL)
|
||||||
skygw_message_done(lm->lm_logmes);
|
{
|
||||||
|
if (lm->lm_clientmes != NULL)
|
||||||
|
{
|
||||||
|
skygw_message_done(lm->lm_clientmes);
|
||||||
|
}
|
||||||
|
if (lm->lm_logmes != NULL)
|
||||||
|
{
|
||||||
|
skygw_message_done(lm->lm_logmes);
|
||||||
|
}
|
||||||
|
}
|
||||||
/** This releases memory of all created objects */
|
/** This releases memory of all created objects */
|
||||||
logmanager_done_nomutex();
|
logmanager_done_nomutex();
|
||||||
fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n");
|
fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n");
|
||||||
@ -1895,15 +1903,18 @@ static char* form_full_file_name(
|
|||||||
fprintf(stderr, "Error : Too long file name= %d.\n", (int)fnlen);
|
fprintf(stderr, "Error : Too long file name= %d.\n", (int)fnlen);
|
||||||
goto return_filename;
|
goto return_filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = (char*)calloc(1, fnlen);
|
filename = (char*)calloc(1, fnlen);
|
||||||
snprintf(seqnostr, s+1, "%d", seqno);
|
|
||||||
|
if (seqnostr != NULL)
|
||||||
|
{
|
||||||
|
snprintf(seqnostr, s+1, "%d", seqno);
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0, p=parts; p->sp_string != NULL; i++, p=p->sp_next)
|
for (i=0, p=parts; p->sp_string != NULL; i++, p=p->sp_next)
|
||||||
{
|
{
|
||||||
if (i == seqnoidx)
|
if (seqnostr != NULL && i == seqnoidx)
|
||||||
{
|
{
|
||||||
strcat(filename, seqnostr);
|
strcat(filename, seqnostr); /*< add sequence number */
|
||||||
}
|
}
|
||||||
strcat(filename, p->sp_string);
|
strcat(filename, p->sp_string);
|
||||||
|
|
||||||
|
@ -45,8 +45,9 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
block_size = atoi(argv[3]);
|
block_size = atoi(argv[3]);
|
||||||
if(block_size < 1){
|
if(block_size < 1 || block_size > 1024){
|
||||||
fprintf(stderr,"Message size too small, must be at least 1 byte long.");
|
fprintf(stderr,"Message size too small or large, must be at least 1 byte long and must not exceed 1024 bytes.");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1088,30 +1088,31 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize, bool fullnames)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(tmp != NULL){
|
||||||
|
char *catnm = NULL;
|
||||||
|
|
||||||
char *catnm = NULL;
|
if(fullnames)
|
||||||
|
{
|
||||||
if(fullnames)
|
if(tbl->db && strcmp(tbl->db,"skygw_virtual") != 0)
|
||||||
{
|
{
|
||||||
if(tbl->db && strcmp(tbl->db,"skygw_virtual") != 0)
|
catnm = (char*)calloc(strlen(tbl->db) + strlen(tbl->table_name) + 2,sizeof(char));
|
||||||
{
|
strcpy(catnm,tbl->db);
|
||||||
catnm = (char*)calloc(strlen(tbl->db) + strlen(tbl->table_name) + 2,sizeof(char));
|
strcat(catnm,".");
|
||||||
strcpy(catnm,tbl->db);
|
strcat(catnm,tbl->table_name);
|
||||||
strcat(catnm,".");
|
}
|
||||||
strcat(catnm,tbl->table_name);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(catnm)
|
if(catnm)
|
||||||
{
|
{
|
||||||
tables[i++] = catnm;
|
tables[i++] = catnm;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tables[i++] = strdup(tbl->table_name);
|
tables[i++] = strdup(tbl->table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
tbl=tbl->next_local;
|
tbl=tbl->next_local;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lex->current_select = lex->current_select->next_select_in_list();
|
lex->current_select = lex->current_select->next_select_in_list();
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,9 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
fgets(readbuff,4092,infile);
|
fgets(readbuff,4092,infile);
|
||||||
psize = strlen(readbuff);
|
psize = strlen(readbuff);
|
||||||
|
if(psize < 0 || psize > 4092){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
qbuff = gwbuf_alloc(psize + 7);
|
qbuff = gwbuf_alloc(psize + 7);
|
||||||
*(qbuff->sbuf->data + 0) = (unsigned char)psize;
|
*(qbuff->sbuf->data + 0) = (unsigned char)psize;
|
||||||
*(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8);
|
*(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8);
|
||||||
|
@ -1268,7 +1268,7 @@ SERVER *server;
|
|||||||
(PERCENT_TYPE|COUNT_TYPE));
|
(PERCENT_TYPE|COUNT_TYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!succp)
|
if (!succp && param != NULL)
|
||||||
{
|
{
|
||||||
LOGIF(LM, (skygw_log_write(
|
LOGIF(LM, (skygw_log_write(
|
||||||
LOGFILE_MESSAGE,
|
LOGFILE_MESSAGE,
|
||||||
@ -1359,10 +1359,10 @@ SERVER *server;
|
|||||||
serviceSetUser(obj->element,
|
serviceSetUser(obj->element,
|
||||||
user,
|
user,
|
||||||
auth);
|
auth);
|
||||||
if (enable_root_user && service)
|
if (enable_root_user)
|
||||||
serviceEnableRootUser(service, atoi(enable_root_user));
|
serviceEnableRootUser(service, atoi(enable_root_user));
|
||||||
|
|
||||||
if (allow_localhost_match_wildcard_host)
|
if (allow_localhost_match_wildcard_host && service)
|
||||||
serviceEnableLocalhostMatchWildcardHost(
|
serviceEnableLocalhostMatchWildcardHost(
|
||||||
service,
|
service,
|
||||||
atoi(allow_localhost_match_wildcard_host));
|
atoi(allow_localhost_match_wildcard_host));
|
||||||
|
@ -1479,7 +1479,11 @@ int main(int argc, char **argv)
|
|||||||
bool succp;
|
bool succp;
|
||||||
|
|
||||||
sprintf(buf, "%s/log", home_dir);
|
sprintf(buf, "%s/log", home_dir);
|
||||||
mkdir(buf, 0777);
|
if(mkdir(buf, 0777) != 0){
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error: Cannot create log directory: %s\n",buf);
|
||||||
|
goto return_main;
|
||||||
|
}
|
||||||
argv[0] = "MaxScale";
|
argv[0] = "MaxScale";
|
||||||
argv[1] = "-j";
|
argv[1] = "-j";
|
||||||
argv[2] = buf;
|
argv[2] = buf;
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *enc;
|
char *enc, *pw;
|
||||||
|
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
{
|
{
|
||||||
@ -47,9 +47,21 @@ char *enc;
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((enc = encryptPassword(argv[1])) != NULL)
|
pw = calloc(81,sizeof(char));
|
||||||
|
|
||||||
|
if(pw == NULL){
|
||||||
|
fprintf(stderr, "Error: cannot allocate enough memory.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(pw,argv[1],80);
|
||||||
|
|
||||||
|
if ((enc = encryptPassword(pw)) != NULL){
|
||||||
printf("%s\n", enc);
|
printf("%s\n", enc);
|
||||||
else
|
}else{
|
||||||
fprintf(stderr, "Failed to encode the password\n");
|
fprintf(stderr, "Failed to encode the password\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pw);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,9 @@ int buflen;
|
|||||||
ss_info_dassert(0 == GWBUF_EMPTY(buffer), "Buffer should not be empty");
|
ss_info_dassert(0 == GWBUF_EMPTY(buffer), "Buffer should not be empty");
|
||||||
ss_info_dassert(GWBUF_IS_TYPE_UNDEFINED(buffer), "Buffer type should be undefined");
|
ss_info_dassert(GWBUF_IS_TYPE_UNDEFINED(buffer), "Buffer type should be undefined");
|
||||||
ss_dfprintf(stderr, "\t..done\nSet a hint for the buffer");
|
ss_dfprintf(stderr, "\t..done\nSet a hint for the buffer");
|
||||||
hint = hint_create_parameter(NULL, strdup("name"), "value");
|
char* name = strdup("name");
|
||||||
|
hint = hint_create_parameter(NULL, name, "value");
|
||||||
|
free(name);
|
||||||
gwbuf_add_hint(buffer, hint);
|
gwbuf_add_hint(buffer, hint);
|
||||||
ss_info_dassert(hint == buffer->hint, "Buffer should point to first and only hint");
|
ss_info_dassert(hint == buffer->hint, "Buffer should point to first and only hint");
|
||||||
ss_dfprintf(stderr, "\t..done\nSet a property for the buffer");
|
ss_dfprintf(stderr, "\t..done\nSet a property for the buffer");
|
||||||
|
@ -415,6 +415,7 @@ GWBUF *clone = NULL;
|
|||||||
modutil_MySQL_Query(queue, &dummy, &length, &residual);
|
modutil_MySQL_Query(queue, &dummy, &length, &residual);
|
||||||
clone = gwbuf_clone(queue);
|
clone = gwbuf_clone(queue);
|
||||||
my_session->residual = residual;
|
my_session->residual = residual;
|
||||||
|
free(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,8 +137,8 @@ FILTER_PARAMETER** read_params(int* paramc)
|
|||||||
do_read = 0;
|
do_read = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FILTER_PARAMETER** params;
|
FILTER_PARAMETER** params = NULL;
|
||||||
if((params = malloc(sizeof(FILTER_PARAMETER*)*(pc+1)))!=NULL){
|
if((params = malloc(sizeof(FILTER_PARAMETER*)*(pc+1))) != NULL){
|
||||||
for(i = 0;i<pc;i++){
|
for(i = 0;i<pc;i++){
|
||||||
params[i] = malloc(sizeof(FILTER_PARAMETER));
|
params[i] = malloc(sizeof(FILTER_PARAMETER));
|
||||||
if(params[i]){
|
if(params[i]){
|
||||||
@ -147,10 +147,10 @@ FILTER_PARAMETER** read_params(int* paramc)
|
|||||||
}
|
}
|
||||||
free(names[i]);
|
free(names[i]);
|
||||||
free(values[i]);
|
free(values[i]);
|
||||||
}
|
}
|
||||||
|
params[pc] = NULL;
|
||||||
|
*paramc = pc;
|
||||||
}
|
}
|
||||||
params[pc] = NULL;
|
|
||||||
*paramc = pc;
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ int load_query()
|
|||||||
int i, qcount = 0, qbuff_sz = 10, rval = 0;
|
int i, qcount = 0, qbuff_sz = 10, rval = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
unsigned int qlen = 0;
|
unsigned int qlen = 0;
|
||||||
buffer = (char*)malloc(4092*sizeof(char));
|
buffer = (char*)calloc(4092,sizeof(char));
|
||||||
if(buffer == NULL){
|
if(buffer == NULL){
|
||||||
printf("Error: cannot allocate enough memory.\n");
|
printf("Error: cannot allocate enough memory.\n");
|
||||||
skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n");
|
skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n");
|
||||||
@ -925,8 +925,9 @@ GWBUF* gen_packet(PACKET pkt)
|
|||||||
|
|
||||||
int process_opts(int argc, char** argv)
|
int process_opts(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int fd = open_file("harness.cnf",1), buffsize = 1024;
|
unsigned int fd = open_file("harness.cnf",1), buffsize = 1024;
|
||||||
int rd,fsize,rdsz;
|
int rd,rdsz;
|
||||||
|
unsigned int fsize;
|
||||||
char *buff = calloc(buffsize,sizeof(char)), *tok = NULL;
|
char *buff = calloc(buffsize,sizeof(char)), *tok = NULL;
|
||||||
|
|
||||||
/**Parse 'harness.cnf' file*/
|
/**Parse 'harness.cnf' file*/
|
||||||
|
@ -453,12 +453,13 @@ static int gw_read_backend_event(DCB *dcb) {
|
|||||||
0,
|
0,
|
||||||
"Read from backend failed");
|
"Read from backend failed");
|
||||||
|
|
||||||
router->handleError(router_instance,
|
router->handleError(
|
||||||
session->router_session,
|
router_instance,
|
||||||
errbuf,
|
session->router_session,
|
||||||
dcb,
|
errbuf,
|
||||||
ERRACT_NEW_CONNECTION,
|
dcb,
|
||||||
&succp);
|
ERRACT_NEW_CONNECTION,
|
||||||
|
&succp);
|
||||||
gwbuf_free(errbuf);
|
gwbuf_free(errbuf);
|
||||||
|
|
||||||
if (!succp)
|
if (!succp)
|
||||||
@ -1170,7 +1171,7 @@ static int backend_write_delayqueue(DCB *dcb)
|
|||||||
0,
|
0,
|
||||||
"Failed to write buffered data to back-end server. "
|
"Failed to write buffered data to back-end server. "
|
||||||
"Buffer was empty or back-end was disconnected during "
|
"Buffer was empty or back-end was disconnected during "
|
||||||
"operation. Session will be closed.");
|
"operation. Attempting to find a new backend.");
|
||||||
|
|
||||||
router->handleError(router_instance,
|
router->handleError(router_instance,
|
||||||
rsession,
|
rsession,
|
||||||
|
@ -1406,7 +1406,7 @@ void check_drop_tmp_table(
|
|||||||
{
|
{
|
||||||
|
|
||||||
int tsize = 0, klen = 0,i;
|
int tsize = 0, klen = 0,i;
|
||||||
char** tbl;
|
char** tbl = NULL;
|
||||||
char *hkey,*dbname;
|
char *hkey,*dbname;
|
||||||
MYSQL_session* data;
|
MYSQL_session* data;
|
||||||
|
|
||||||
@ -1425,29 +1425,31 @@ void check_drop_tmp_table(
|
|||||||
if (is_drop_table_query(querybuf))
|
if (is_drop_table_query(querybuf))
|
||||||
{
|
{
|
||||||
tbl = skygw_get_table_names(querybuf,&tsize,false);
|
tbl = skygw_get_table_names(querybuf,&tsize,false);
|
||||||
|
if(tbl != NULL){
|
||||||
for(i = 0; i<tsize; i++)
|
for(i = 0; i<tsize; i++)
|
||||||
{
|
{
|
||||||
klen = strlen(dbname) + strlen(tbl[i]) + 2;
|
klen = strlen(dbname) + strlen(tbl[i]) + 2;
|
||||||
hkey = calloc(klen,sizeof(char));
|
hkey = calloc(klen,sizeof(char));
|
||||||
strcpy(hkey,dbname);
|
strcpy(hkey,dbname);
|
||||||
strcat(hkey,".");
|
strcat(hkey,".");
|
||||||
strcat(hkey,tbl[i]);
|
strcat(hkey,tbl[i]);
|
||||||
|
|
||||||
if (rses_prop_tmp &&
|
if (rses_prop_tmp &&
|
||||||
rses_prop_tmp->rses_prop_data.temp_tables)
|
rses_prop_tmp->rses_prop_data.temp_tables)
|
||||||
{
|
{
|
||||||
if (hashtable_delete(rses_prop_tmp->rses_prop_data.temp_tables,
|
if (hashtable_delete(rses_prop_tmp->rses_prop_data.temp_tables,
|
||||||
(void *)hkey))
|
(void *)hkey))
|
||||||
{
|
{
|
||||||
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
|
||||||
"Temporary table dropped: %s",hkey)));
|
"Temporary table dropped: %s",hkey)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tbl[i]);
|
free(tbl[i]);
|
||||||
free(hkey);
|
free(hkey);
|
||||||
}
|
}
|
||||||
free(tbl);
|
|
||||||
|
free(tbl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1468,7 +1470,7 @@ skygw_query_type_t is_read_tmp_table(
|
|||||||
|
|
||||||
bool target_tmp_table = false;
|
bool target_tmp_table = false;
|
||||||
int tsize = 0, klen = 0,i;
|
int tsize = 0, klen = 0,i;
|
||||||
char** tbl;
|
char** tbl = NULL;
|
||||||
char *hkey,*dbname;
|
char *hkey,*dbname;
|
||||||
MYSQL_session* data;
|
MYSQL_session* data;
|
||||||
|
|
||||||
@ -1493,7 +1495,7 @@ skygw_query_type_t is_read_tmp_table(
|
|||||||
{
|
{
|
||||||
tbl = skygw_get_table_names(querybuf,&tsize,false);
|
tbl = skygw_get_table_names(querybuf,&tsize,false);
|
||||||
|
|
||||||
if (tsize > 0)
|
if (tbl != NULL && tsize > 0)
|
||||||
{
|
{
|
||||||
/** Query targets at least one table */
|
/** Query targets at least one table */
|
||||||
for(i = 0; i<tsize && !target_tmp_table && tbl[i]; i++)
|
for(i = 0; i<tsize && !target_tmp_table && tbl[i]; i++)
|
||||||
@ -1529,7 +1531,10 @@ skygw_query_type_t is_read_tmp_table(
|
|||||||
{
|
{
|
||||||
free(tbl[i]);
|
free(tbl[i]);
|
||||||
}
|
}
|
||||||
free(tbl);
|
|
||||||
|
if(tbl != NULL){
|
||||||
|
free(tbl);
|
||||||
|
}
|
||||||
|
|
||||||
return qtype;
|
return qtype;
|
||||||
}
|
}
|
||||||
@ -1714,27 +1719,41 @@ static int routeQuery(
|
|||||||
LOGIF(LE,
|
LOGIF(LE,
|
||||||
(skygw_log_write_flush(
|
(skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error: Failed to route %s:%s:\"%s\" to "
|
"Error: Can't route %s:%s:\"%s\" to "
|
||||||
"backend server. %s.",
|
"backend server. Router is closed.",
|
||||||
STRPACKETTYPE(packet_type),
|
STRPACKETTYPE(packet_type),
|
||||||
STRQTYPE(qtype),
|
STRQTYPE(qtype),
|
||||||
(query_str == NULL ? "(empty)" : query_str),
|
(query_str == NULL ? "(empty)" : query_str))));
|
||||||
(rses_is_closed ? "Router was closed" :
|
free(query_str);
|
||||||
"Router has no backend servers where to "
|
|
||||||
"route to"))));
|
|
||||||
}
|
}
|
||||||
|
ret = 0;
|
||||||
goto retblock;
|
goto retblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Read stored master DCB pointer */
|
||||||
|
if ((master_dcb = router_cli_ses->rses_master_ref->bref_dcb) == NULL)
|
||||||
|
{
|
||||||
|
char* query_str = modutil_get_query(querybuf);
|
||||||
|
CHK_DCB(master_dcb);
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Error: Can't route %s:%s:\"%s\" to "
|
||||||
|
"backend server. Session doesn't have a Master "
|
||||||
|
"node",
|
||||||
|
STRPACKETTYPE(packet_type),
|
||||||
|
STRQTYPE(qtype),
|
||||||
|
(query_str == NULL ? "(empty)" : query_str))));
|
||||||
|
free(query_str);
|
||||||
|
ret = 0;
|
||||||
|
goto retblock;
|
||||||
|
}
|
||||||
|
|
||||||
/** If buffer is not contiguous, make it such */
|
/** If buffer is not contiguous, make it such */
|
||||||
if (querybuf->next != NULL)
|
if (querybuf->next != NULL)
|
||||||
{
|
{
|
||||||
querybuf = gwbuf_make_contiguous(querybuf);
|
querybuf = gwbuf_make_contiguous(querybuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read stored master DCB pointer */
|
|
||||||
master_dcb = router_cli_ses->rses_master_ref->bref_dcb;
|
|
||||||
CHK_DCB(master_dcb);
|
|
||||||
|
|
||||||
switch(packet_type) {
|
switch(packet_type) {
|
||||||
case MYSQL_COM_QUIT: /*< 1 QUIT will close all sessions */
|
case MYSQL_COM_QUIT: /*< 1 QUIT will close all sessions */
|
||||||
case MYSQL_COM_INIT_DB: /*< 2 DDL must go to the master */
|
case MYSQL_COM_INIT_DB: /*< 2 DDL must go to the master */
|
||||||
@ -2030,13 +2049,13 @@ static int routeQuery(
|
|||||||
NULL,
|
NULL,
|
||||||
MAX_RLAG_UNDEFINED);
|
MAX_RLAG_UNDEFINED);
|
||||||
|
|
||||||
if (succp && (master_dcb == NULL || master_dcb == curr_master_dcb))
|
if (succp && master_dcb == curr_master_dcb)
|
||||||
{
|
{
|
||||||
atomic_add(&inst->stats.n_master, 1);
|
atomic_add(&inst->stats.n_master, 1);
|
||||||
target_dcb = master_dcb;
|
target_dcb = master_dcb;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (succp && master_dcb != curr_master_dcb)
|
if (succp && master_dcb != curr_master_dcb)
|
||||||
{
|
{
|
||||||
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
|
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
|
||||||
@ -4077,6 +4096,22 @@ static void handleError (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rses->rses_master_ref->bref_dcb == backend_dcb)
|
||||||
|
{
|
||||||
|
/** Master failed, can't recover */
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Error : Master node have failed. "
|
||||||
|
"Session will be closed.")));
|
||||||
|
|
||||||
|
*succp = false;
|
||||||
|
rses_end_locked_router_action(rses);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This is called in hope of getting replacement for
|
||||||
|
* failed slave(s).
|
||||||
|
*/
|
||||||
*succp = handle_error_new_connection(inst,
|
*succp = handle_error_new_connection(inst,
|
||||||
rses,
|
rses,
|
||||||
backend_dcb,
|
backend_dcb,
|
||||||
@ -4119,7 +4154,18 @@ static void handle_error_reply_client(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This must be called with router lock
|
* 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).
|
||||||
|
*
|
||||||
|
* This must be called with router lock.
|
||||||
|
*
|
||||||
|
* @param inst router instance
|
||||||
|
* @param rses router client session
|
||||||
|
* @param dcb failed DCB
|
||||||
|
* @param errmsg error message which is sent to client if it is waiting
|
||||||
|
*
|
||||||
|
* @return true if there are enough backend connections to continue, false if not
|
||||||
*/
|
*/
|
||||||
static bool handle_error_new_connection(
|
static bool handle_error_new_connection(
|
||||||
ROUTER_INSTANCE* inst,
|
ROUTER_INSTANCE* inst,
|
||||||
@ -4139,25 +4185,14 @@ static bool handle_error_new_connection(
|
|||||||
ses = backend_dcb->session;
|
ses = backend_dcb->session;
|
||||||
CHK_SESSION(ses);
|
CHK_SESSION(ses);
|
||||||
|
|
||||||
bref = get_bref_from_dcb(rses, backend_dcb);
|
/**
|
||||||
|
* If bref == NULL it has been replaced already with another one.
|
||||||
/** failed DCB has already been replaced */
|
|
||||||
if (bref == NULL)
|
|
||||||
{
|
|
||||||
succp = true;
|
|
||||||
goto return_succp;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Error handler is already called for this DCB because
|
|
||||||
* it's not polling anymore. It can be assumed that
|
|
||||||
* it succeed because rses isn't closed.
|
|
||||||
*/
|
*/
|
||||||
if (backend_dcb->state != DCB_STATE_POLLING)
|
if ((bref = get_bref_from_dcb(rses, backend_dcb)) == NULL)
|
||||||
{
|
{
|
||||||
succp = true;
|
succp = true;
|
||||||
goto return_succp;
|
goto return_succp;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHK_BACKEND_REF(bref);
|
CHK_BACKEND_REF(bref);
|
||||||
|
|
||||||
if (BREF_IS_WAITING_RESULT(bref))
|
if (BREF_IS_WAITING_RESULT(bref))
|
||||||
@ -4169,6 +4204,17 @@ static bool handle_error_new_connection(
|
|||||||
}
|
}
|
||||||
bref_clear_state(bref, BREF_IN_USE);
|
bref_clear_state(bref, BREF_IN_USE);
|
||||||
bref_set_state(bref, BREF_CLOSED);
|
bref_set_state(bref, BREF_CLOSED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error handler is already called for this DCB because
|
||||||
|
* it's not polling anymore. It can be assumed that
|
||||||
|
* it succeed because rses isn't closed.
|
||||||
|
*/
|
||||||
|
if (backend_dcb->state != DCB_STATE_POLLING)
|
||||||
|
{
|
||||||
|
succp = true;
|
||||||
|
goto return_succp;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Remove callback because this DCB won't be used
|
* Remove callback because this DCB won't be used
|
||||||
* unless it is reconnected later, and then the callback
|
* unless it is reconnected later, and then the callback
|
||||||
@ -4293,8 +4339,8 @@ static bool have_enough_servers(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double pct = (*p_rses)->rses_config.rw_max_slave_conn_percent/100;
|
int pct = (*p_rses)->rses_config.rw_max_slave_conn_percent/100;
|
||||||
double nservers = (double)router_nsrv*pct;
|
int nservers = router_nsrv*pct;
|
||||||
|
|
||||||
if ((*p_rses)->rses_config.rw_max_slave_conn_count < min_nsrv)
|
if ((*p_rses)->rses_config.rw_max_slave_conn_count < min_nsrv)
|
||||||
{
|
{
|
||||||
@ -4313,11 +4359,11 @@ static bool have_enough_servers(
|
|||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Unable to start %s service. There are "
|
"Error : Unable to start %s service. There are "
|
||||||
"too few backend servers configured in "
|
"too few backend servers configured in "
|
||||||
"MaxScale.cnf. Found %d%% when at least %.0f%% "
|
"MaxScale.cnf. Found %d%% when at least %d%% "
|
||||||
"would be required.",
|
"would be required.",
|
||||||
router->service->name,
|
router->service->name,
|
||||||
(*p_rses)->rses_config.rw_max_slave_conn_percent,
|
(*p_rses)->rses_config.rw_max_slave_conn_percent,
|
||||||
min_nsrv/(((double)router_nsrv)/100))));
|
min_nsrv/(router_nsrv/100))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(*p_rses);
|
free(*p_rses);
|
||||||
@ -4380,7 +4426,14 @@ static int rses_get_max_replication_lag(
|
|||||||
return conf_max_rlag;
|
return conf_max_rlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds out if there is a backend reference pointing at the DCB given as
|
||||||
|
* parameter.
|
||||||
|
* @param rses router client session
|
||||||
|
* @param dcb DCB
|
||||||
|
*
|
||||||
|
* @return backend reference pointer if succeed or NULL
|
||||||
|
*/
|
||||||
static backend_ref_t* get_bref_from_dcb(
|
static backend_ref_t* get_bref_from_dcb(
|
||||||
ROUTER_CLIENT_SES* rses,
|
ROUTER_CLIENT_SES* rses,
|
||||||
DCB* dcb)
|
DCB* dcb)
|
||||||
|
Reference in New Issue
Block a user