Merge branch 'release-1.2' into develop
Conflicts: server/core/adminusers.c server/modules/protocol/mysql_client.c
This commit is contained in:
@ -19,6 +19,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 700
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <crypt.h>
|
||||
#include <users.h>
|
||||
|
||||
@ -197,6 +197,7 @@ GWBUF *rval;
|
||||
rval->gwbuf_info = buf->gwbuf_info;
|
||||
rval->gwbuf_bufobj = buf->gwbuf_bufobj;
|
||||
rval->tail = rval;
|
||||
rval->next = NULL;
|
||||
CHK_GWBUF(rval);
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -128,6 +128,10 @@ module=regexfilter
|
||||
match=fetch
|
||||
replace=select
|
||||
|
||||
[hint]
|
||||
type=filter
|
||||
module=hintfilter
|
||||
|
||||
|
||||
## A series of service definition
|
||||
#
|
||||
@ -218,11 +222,21 @@ router=readwritesplit
|
||||
servers=server1,server2,server3
|
||||
user=myuser
|
||||
passwd=mypwd
|
||||
#use_sql_variables_in=
|
||||
#max_slave_connections=100%
|
||||
max_slave_connections=100%
|
||||
#use_sql_variables_in=master
|
||||
#max_slave_replication_lag=21
|
||||
#router_options=slave_selection_criteria=
|
||||
#filters=fetch|qla
|
||||
#filters=hint|fetch|qla
|
||||
#router_options=slave_selection_criteria=LEAST_CURRENT_OPERATIONS
|
||||
|
||||
# Uncomment this to disable the saving of session modifying comments. Some scripting
|
||||
# languages use connection pooling and will use the same session. MaxScale sees them
|
||||
# as the same session and stores them for the slave recovery process.
|
||||
#router_options=disable_sescmd_history=true,disable_slave_recovery=true
|
||||
|
||||
# This will allow the master server to be used for read queries. By default
|
||||
# MaxScale will only use the master for write queries.
|
||||
#router_options=master_accept_reads=true
|
||||
|
||||
|
||||
[Debug Interface]
|
||||
type=service
|
||||
@ -265,27 +279,26 @@ service=Read Connection Router
|
||||
protocol=MySQLClient
|
||||
address=192.168.100.102
|
||||
port=4008
|
||||
#socket=/tmp/readconn.sock
|
||||
socket=/var/lib/maxscale/readconn.sock
|
||||
|
||||
[RW Split Listener]
|
||||
type=listener
|
||||
service=RW Split Router
|
||||
protocol=MySQLClient
|
||||
port=4006
|
||||
#socket=/tmp/rwsplit.sock
|
||||
#socket=/var/lib/maxscale/rwsplit.sock
|
||||
|
||||
[Debug Listener]
|
||||
type=listener
|
||||
service=Debug Interface
|
||||
protocol=telnetd
|
||||
#address=127.0.0.1
|
||||
address=127.0.0.1
|
||||
port=4442
|
||||
|
||||
[CLI Listener]
|
||||
type=listener
|
||||
service=CLI
|
||||
protocol=maxscaled
|
||||
#address=localhost
|
||||
port=6603
|
||||
|
||||
## Definition of the servers
|
||||
@ -314,18 +327,18 @@ port=6603
|
||||
|
||||
[server1]
|
||||
type=server
|
||||
address=192.168.100.101
|
||||
port=3000
|
||||
address=127.0.0.1
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server2]
|
||||
type=server
|
||||
address=192.168.100.102
|
||||
port=3000
|
||||
address=127.0.0.1
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
||||
|
||||
[server3]
|
||||
type=server
|
||||
address=192.168.100.103
|
||||
port=3000
|
||||
address=127.0.0.1
|
||||
port=3306
|
||||
protocol=MySQLBackend
|
||||
|
||||
@ -35,7 +35,7 @@ extern __thread log_info_t tls_log_info;
|
||||
* that routes to a named server if a regular expression match is found.
|
||||
* @verbatim
|
||||
*
|
||||
* A simple regular expression query rewrite filter.
|
||||
* A simple regular expression based query routing filter.
|
||||
* Two parameters should be defined in the filter configuration
|
||||
* match=<regular expression>
|
||||
* server=<server to route statement to>
|
||||
|
||||
@ -1091,7 +1091,7 @@ gw_backend_hangup(DCB *dcb)
|
||||
len = sizeof(error);
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0)
|
||||
{
|
||||
if (error != 0)
|
||||
if (error != 0 && ses_state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
strerror_r(error, buf, 100);
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
@ -1105,9 +1105,12 @@ gw_backend_hangup(DCB *dcb)
|
||||
goto retblock;
|
||||
}
|
||||
#if defined(SS_DEBUG)
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Backend hangup error handling.")));
|
||||
if(ses_state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Backend hangup error handling.")));
|
||||
}
|
||||
#endif
|
||||
|
||||
router->handleError(router_instance,
|
||||
|
||||
@ -1093,7 +1093,8 @@ int gw_read_client_event(
|
||||
case MYSQL_IDLE:
|
||||
{
|
||||
uint8_t* payload = NULL;
|
||||
|
||||
session_state_t ses_state;
|
||||
|
||||
session = dcb->session;
|
||||
ss_dassert(session!= NULL);
|
||||
|
||||
@ -1101,13 +1102,18 @@ int gw_read_client_event(
|
||||
{
|
||||
CHK_SESSION(session);
|
||||
}
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
ses_state = session->state;
|
||||
spinlock_release(&session->ses_lock);
|
||||
/* Now, we are assuming in the first buffer there is
|
||||
* the information form mysql command */
|
||||
payload = GWBUF_DATA(read_buffer);
|
||||
|
||||
/** Route COM_QUIT to backend */
|
||||
if (MYSQL_IS_COM_QUIT(payload))
|
||||
{
|
||||
if(ses_state == SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
/** Route COM_QUIT to backend */
|
||||
if (MYSQL_IS_COM_QUIT(payload))
|
||||
{
|
||||
/**
|
||||
* Sends COM_QUIT packets since buffer is already
|
||||
* created. A BREF_CLOSED flag is set so dcb_close won't
|
||||
@ -1115,79 +1121,87 @@ int gw_read_client_event(
|
||||
*/
|
||||
/* Temporarily suppressed: SESSION_ROUTE_QUERY(session, read_buffer); */
|
||||
/**
|
||||
* Close router session which causes closing of backends.
|
||||
*/
|
||||
* Close router session which causes closing of backends.
|
||||
*/
|
||||
dcb_close(dcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Reset error handler when routing of the new query begins */
|
||||
router->handleError(NULL, NULL, NULL, dcb, ERRACT_RESET, NULL);
|
||||
|
||||
if (stmt_input)
|
||||
{
|
||||
/**
|
||||
* Feed each statement completely and separately
|
||||
* to router.
|
||||
*/
|
||||
rc = route_by_statement(session, &read_buffer);
|
||||
|
||||
if (read_buffer != NULL)
|
||||
{
|
||||
/** add incomplete mysql packet to read queue */
|
||||
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
}
|
||||
/**
|
||||
* Feed each statement completely and separately
|
||||
* to router.
|
||||
*/
|
||||
rc = route_by_statement(session, &read_buffer);
|
||||
|
||||
if (read_buffer != NULL)
|
||||
{
|
||||
/** add incomplete mysql packet to read queue */
|
||||
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Feed whole packet to router */
|
||||
rc = SESSION_ROUTE_QUERY(session, read_buffer);
|
||||
/** Feed whole packet to router */
|
||||
rc = SESSION_ROUTE_QUERY(session, read_buffer);
|
||||
}
|
||||
|
||||
|
||||
/** Routing succeed */
|
||||
if (rc)
|
||||
{
|
||||
rc = 0; /**< here '0' means success */
|
||||
rc = 0; /**< here '0' means success */
|
||||
}
|
||||
else
|
||||
{
|
||||
bool succp;
|
||||
GWBUF* errbuf;
|
||||
/**
|
||||
* Create error to be sent to client if session
|
||||
* can't be continued.
|
||||
*/
|
||||
errbuf = mysql_create_custom_error(
|
||||
1,
|
||||
0,
|
||||
"Routing failed. Session is closed.");
|
||||
/**
|
||||
* Ensure that there are enough backends
|
||||
* available.
|
||||
*/
|
||||
router->handleError(
|
||||
router_instance,
|
||||
session->router_session,
|
||||
errbuf,
|
||||
dcb,
|
||||
ERRACT_NEW_CONNECTION,
|
||||
&succp);
|
||||
gwbuf_free(errbuf);
|
||||
/**
|
||||
* If there are not enough backends close
|
||||
* session
|
||||
*/
|
||||
if (!succp)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Routing the query failed. "
|
||||
"Session will be closed.")));
|
||||
bool succp;
|
||||
GWBUF* errbuf;
|
||||
/**
|
||||
* Create error to be sent to client if session
|
||||
* can't be continued.
|
||||
*/
|
||||
errbuf = mysql_create_custom_error(
|
||||
1,
|
||||
0,
|
||||
"Routing failed. Session is closed.");
|
||||
/**
|
||||
* Ensure that there are enough backends
|
||||
* available.
|
||||
*/
|
||||
router->handleError(
|
||||
router_instance,
|
||||
session->router_session,
|
||||
errbuf,
|
||||
dcb,
|
||||
ERRACT_NEW_CONNECTION,
|
||||
&succp);
|
||||
gwbuf_free(errbuf);
|
||||
/**
|
||||
* If there are not enough backends close
|
||||
* session
|
||||
*/
|
||||
if (!succp)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Routing the query failed. "
|
||||
"Session will be closed.")));
|
||||
|
||||
dcb_close(dcb);
|
||||
}
|
||||
dcb_close(dcb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skygw_log_write_flush(LT,"Session received a query in state %s",
|
||||
STRSESSIONSTATE(ses_state));
|
||||
while((read_buffer = GWBUF_CONSUME_ALL(read_buffer)) != NULL);
|
||||
goto return_rc;
|
||||
}
|
||||
goto return_rc;
|
||||
} /* MYSQL_IDLE */
|
||||
break;
|
||||
|
||||
@ -723,16 +723,10 @@ routeQuery(ROUTER *instance, void *router_session, GWBUF *queue)
|
||||
SERVER_IS_DOWN(router_cli_ses->backend->server))
|
||||
{
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
LOGFILE_TRACE|LOGFILE_ERROR,
|
||||
"Error : Failed to route MySQL command %d to backend "
|
||||
"server.",
|
||||
mysql_command)));
|
||||
skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Failed to route MySQL command %d to backend "
|
||||
"server %s.",
|
||||
mysql_command,
|
||||
router_cli_ses->backend->server->unique_name);
|
||||
"server.%s",
|
||||
mysql_command,rses_is_closed ? " Session is closed." : "")));
|
||||
rc = 0;
|
||||
goto return_rc;
|
||||
|
||||
|
||||
@ -3913,7 +3913,7 @@ static GWBUF* sescmd_cursor_clone_querybuf(
|
||||
}
|
||||
ss_dassert(scur->scmd_cur_cmd != NULL);
|
||||
|
||||
buf = gwbuf_clone(scur->scmd_cur_cmd->my_sescmd_buf);
|
||||
buf = gwbuf_clone_all(scur->scmd_cur_cmd->my_sescmd_buf);
|
||||
|
||||
CHK_GWBUF(buf);
|
||||
return buf;
|
||||
|
||||
@ -1701,7 +1701,7 @@ routeQuery(ROUTER* instance,
|
||||
querybuf)))
|
||||
{
|
||||
extract_database(querybuf,db);
|
||||
snprintf(errbuf,"Unknown database: %s",db);
|
||||
snprintf(errbuf,25+MYSQL_DATABASE_MAXLEN,"Unknown database: %s",db);
|
||||
create_error_reply(errbuf,router_cli_ses->replydcb);
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
|
||||
Reference in New Issue
Block a user