Commit fix to bug #418 http://bugs.skysql.com/show_bug.cgi?id=418
This commit is contained in:
@ -253,6 +253,7 @@ static int logmanager_write_log(
|
||||
va_list valist);
|
||||
|
||||
static blockbuf_t* blockbuf_init(logfile_id_t id);
|
||||
static void blockbuf_node_done(void* bb_data);
|
||||
static char* blockbuf_get_writepos(
|
||||
#if 0
|
||||
int** refcount,
|
||||
@ -997,7 +998,12 @@ static char* blockbuf_get_writepos(
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
static void blockbuf_node_done(
|
||||
void* bb_data)
|
||||
{
|
||||
blockbuf_t* bb = (blockbuf_t *)bb_data;
|
||||
simple_mutex_done(&bb->bb_mutex);
|
||||
}
|
||||
|
||||
|
||||
static blockbuf_t* blockbuf_init(
|
||||
@ -2059,7 +2065,7 @@ static bool logfile_init(
|
||||
if (mlist_init(&logfile->lf_blockbuf_list,
|
||||
NULL,
|
||||
strdup("logfile block buffer list"),
|
||||
NULL,
|
||||
blockbuf_node_done,
|
||||
MAXNBLOCKBUFS) == NULL)
|
||||
{
|
||||
ss_dfprintf(stderr,
|
||||
|
||||
@ -706,6 +706,10 @@ static bool skygw_stmt_causes_implicit_commit(
|
||||
{
|
||||
succp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
succp =false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
succp = true;
|
||||
|
||||
@ -203,6 +203,19 @@ int error_count = 0;
|
||||
char *enable_root_user =
|
||||
config_get_value(obj->parameters, "enable_root_user");
|
||||
|
||||
if (obj->element == NULL) /*< if module load failed */
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Reading configuration "
|
||||
"for router service '%s' failed. "
|
||||
"Router %s is not loaded.",
|
||||
obj->object,
|
||||
obj->object)));
|
||||
obj = obj->next;
|
||||
continue; /*< process next obj */
|
||||
}
|
||||
|
||||
if (enable_root_user)
|
||||
serviceEnableRootUser(obj->element, atoi(enable_root_user));
|
||||
|
||||
|
||||
@ -53,6 +53,17 @@ static void register_module(const char *module,
|
||||
void *modobj);
|
||||
static void unregister_module(const char *module);
|
||||
|
||||
char* get_maxscale_home(void)
|
||||
{
|
||||
char* home = getenv("MAXSCALE_HOME");
|
||||
if (home == NULL)
|
||||
{
|
||||
home = "/usr/local/skysql/MaxScale";
|
||||
}
|
||||
return home;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load the dynamic library related to a gateway module. The routine
|
||||
* will look for library files in the current directory,
|
||||
@ -82,9 +93,9 @@ MODULES *mod;
|
||||
sprintf(fname, "./lib%s.so", module);
|
||||
if (access(fname, F_OK) == -1)
|
||||
{
|
||||
if ((home = getenv("MAXSCALE_HOME")) == NULL)
|
||||
home = "/usr/local/skysql/MaxScale";
|
||||
home = get_maxscale_home ();
|
||||
sprintf(fname, "%s/modules/lib%s.so", home, module);
|
||||
|
||||
if (access(fname, F_OK) == -1)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
@ -100,7 +111,7 @@ MODULES *mod;
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Unable to load library for module: "
|
||||
"%s, %s.",
|
||||
"%s\n\t\t\t %s.",
|
||||
module,
|
||||
dlerror())));
|
||||
return NULL;
|
||||
@ -111,7 +122,7 @@ MODULES *mod;
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Version interface not supported by "
|
||||
"module: %s, %s.",
|
||||
"module: %s\n\t\t\t %s.",
|
||||
module,
|
||||
dlerror())));
|
||||
dlclose(dlhandle);
|
||||
@ -134,7 +145,7 @@ MODULES *mod;
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Expected entry point interface missing "
|
||||
"from module: %s, %s.",
|
||||
"from module: %s\n\t\t\t %s.",
|
||||
module,
|
||||
dlerror())));
|
||||
dlclose(dlhandle);
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <session.h>
|
||||
#include <service.h>
|
||||
#include <server.h>
|
||||
@ -70,6 +72,20 @@ SERVICE *service;
|
||||
return NULL;
|
||||
if ((service->router = load_module(router, MODULE_ROUTER)) == NULL)
|
||||
{
|
||||
char* home = get_maxscale_home();
|
||||
char* ldpath = getenv("LD_LIBRARY_PATH");
|
||||
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Unable to load %s module \"%s\".\n\t\t\t"
|
||||
" Ensure that lib%s.so exists in one of the "
|
||||
"following directories :\n\t\t\t "
|
||||
"- %s/modules\n\t\t\t - %s",
|
||||
MODULE_ROUTER,
|
||||
router,
|
||||
router,
|
||||
home,
|
||||
ldpath)));
|
||||
free(service);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -55,4 +55,6 @@ extern void *load_module(const char *module, const char *type);
|
||||
extern void unload_module(const char *module);
|
||||
extern void printModules();
|
||||
extern void dprintAllModules(DCB *);
|
||||
char* get_maxscale_home(void);
|
||||
|
||||
#endif
|
||||
|
||||
@ -122,6 +122,8 @@ struct router_client_session {
|
||||
/*< cursor is pointer and status variable to current session command */
|
||||
sescmd_cursor_t rses_cursor[BE_COUNT];
|
||||
int rses_capabilities; /*< input type, for example */
|
||||
bool rses_autocommit_enabled;
|
||||
bool rses_transaction_active;
|
||||
struct router_client_session* next;
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t rses_chk_tail;
|
||||
@ -155,4 +157,8 @@ typedef struct router_instance {
|
||||
struct router_instance* next; /*< Next router on the list */
|
||||
} ROUTER_INSTANCE;
|
||||
|
||||
#define BACKEND_TYPE(b) (SERVER_IS_MASTER((b)->backend_server) ? BE_MASTER : \
|
||||
(SERVER_IS_SLAVE((b)->backend_server) ? BE_SLAVE : \
|
||||
(SERVER_IS_JOINED((b)->backend_server) ? BE_JOINED : BE_UNDEFINED)));
|
||||
|
||||
#endif /*< _RWSPLITROUTER_H */
|
||||
|
||||
@ -251,7 +251,6 @@ static ROUTER* createInstance(
|
||||
"module but none are supported. The options will be "
|
||||
"ignored.")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an array of the backend servers in the router structure to
|
||||
* maintain a count of the number of connections to each
|
||||
@ -439,6 +438,8 @@ static void* newSession(
|
||||
return (void *)client_rses;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Close a session with the router, this is the mechanism
|
||||
* by which a router may cleanup data structure etc.
|
||||
@ -683,86 +684,92 @@ static int routeQuery(
|
||||
* transaction becomes active and master gets all statements until
|
||||
* transaction is committed and autocommit is enabled again.
|
||||
*/
|
||||
if (autocommit_enabled &&
|
||||
if (router_cli_ses->rses_autocommit_enabled &&
|
||||
QUERY_IS_TYPE(qtype, QUERY_TYPE_DISABLE_AUTOCOMMIT))
|
||||
{
|
||||
autocommit_enabled = false;
|
||||
router_cli_ses->rses_autocommit_enabled = false;
|
||||
|
||||
if (!transaction_active)
|
||||
if (!router_cli_ses->rses_transaction_active)
|
||||
{
|
||||
transaction_active = true;
|
||||
router_cli_ses->rses_transaction_active = true;
|
||||
}
|
||||
}
|
||||
else if (!transaction_active &&
|
||||
else if (!router_cli_ses->rses_transaction_active &&
|
||||
QUERY_IS_TYPE(qtype, QUERY_TYPE_BEGIN_TRX))
|
||||
{
|
||||
transaction_active = true;
|
||||
router_cli_ses->rses_transaction_active = true;
|
||||
}
|
||||
/**
|
||||
* Explicit COMMIT and ROLLBACK, implicit COMMIT.
|
||||
*/
|
||||
if (autocommit_enabled &&
|
||||
transaction_active &&
|
||||
if (router_cli_ses->rses_autocommit_enabled &&
|
||||
router_cli_ses->rses_transaction_active &&
|
||||
(QUERY_IS_TYPE(qtype,QUERY_TYPE_COMMIT) ||
|
||||
QUERY_IS_TYPE(qtype,QUERY_TYPE_ROLLBACK)))
|
||||
{
|
||||
transaction_active = false;
|
||||
router_cli_ses->rses_transaction_active = false;
|
||||
}
|
||||
else if (!autocommit_enabled &&
|
||||
else if (!router_cli_ses->rses_autocommit_enabled &&
|
||||
QUERY_IS_TYPE(qtype, QUERY_TYPE_ENABLE_AUTOCOMMIT))
|
||||
{
|
||||
autocommit_enabled = true;
|
||||
transaction_active = false;
|
||||
router_cli_ses->rses_autocommit_enabled = true;
|
||||
router_cli_ses->rses_transaction_active = false;
|
||||
}
|
||||
/**
|
||||
* Session update is always routed in the same way.
|
||||
*/
|
||||
if (QUERY_IS_TYPE(qtype, QUERY_TYPE_SESSION_WRITE))
|
||||
{
|
||||
if (route_session_write(
|
||||
bool succp = route_session_write(
|
||||
router_cli_ses,
|
||||
querybuf,
|
||||
inst,
|
||||
packet_type,
|
||||
qtype))
|
||||
qtype);
|
||||
|
||||
if (succp)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
ss_dassert(succp);
|
||||
ss_dassert(ret == 1);
|
||||
goto return_ret;
|
||||
}
|
||||
else if (transaction_active) /*< all to master */
|
||||
else if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) &&
|
||||
!router_cli_ses->rses_transaction_active)
|
||||
{
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"Transaction is active, routing to Master.")));
|
||||
bool succp;
|
||||
|
||||
ret = master_dcb->func.write(master_dcb, querybuf);
|
||||
atomic_add(&inst->stats.n_master, 1);
|
||||
|
||||
goto return_ret;
|
||||
}
|
||||
else if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ))
|
||||
{
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"Read-only query, routing to Slave.")));
|
||||
|
||||
ss_dassert(QUERY_IS_TYPE(qtype, QUERY_TYPE_READ));
|
||||
|
||||
ret = slave_dcb->func.write(slave_dcb, querybuf);
|
||||
atomic_add(&inst->stats.n_slave, 1);
|
||||
|
||||
goto return_ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool succp = true;
|
||||
|
||||
if (LOG_IS_ENABLED(LOGFILE_TRACE))
|
||||
{
|
||||
if (router_cli_ses->rses_transaction_active) /*< all to master */
|
||||
{
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"Transaction is active, routing to Master.")));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGIF(LT, (skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"Begin transaction, write or unspecified type, "
|
||||
"routing to Master.")));
|
||||
}
|
||||
}
|
||||
ret = master_dcb->func.write(master_dcb, querybuf);
|
||||
atomic_add(&inst->stats.n_master, 1);
|
||||
|
||||
@ -935,7 +942,6 @@ static void clientReply(
|
||||
|
||||
/** Unlock */
|
||||
rses_end_locked_router_action(router_cli_ses);
|
||||
|
||||
/**
|
||||
* 1. Check if backend received reply to sescmd.
|
||||
* 2. Check sescmd's state whether OK_PACKET has been
|
||||
@ -984,7 +990,6 @@ static void clientReply(
|
||||
writebuf = sescmd_cursor_process_replies(client_dcb,
|
||||
writebuf,
|
||||
scur);
|
||||
|
||||
}
|
||||
/** Unlock router session */
|
||||
rses_end_locked_router_action(router_cli_ses);
|
||||
@ -1588,6 +1593,7 @@ return_succp:
|
||||
return succp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves cursor to next property and copied address of its sescmd to cursor.
|
||||
* Current propery must be non-null.
|
||||
@ -1665,7 +1671,6 @@ static rses_property_t* mysql_sescmd_get_property(
|
||||
return scmd->my_sescmd_prop;
|
||||
}
|
||||
|
||||
|
||||
static void tracelog_routed_query(
|
||||
ROUTER_CLIENT_SES* rses,
|
||||
char* funcname,
|
||||
@ -1722,11 +1727,13 @@ static void tracelog_routed_query(
|
||||
-1)),
|
||||
STRBETYPE(be_type),
|
||||
dcb)));
|
||||
free(querystr);
|
||||
}
|
||||
}
|
||||
gwbuf_free(buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return rc, rc < 0 if router session is closed. rc == 0 if there are no
|
||||
* capabilities specified, rc > 0 when there are capabilities.
|
||||
@ -1848,3 +1855,4 @@ static bool route_session_write(
|
||||
return_succp:
|
||||
return succp;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user