diff --git a/server/core/Makefile b/server/core/Makefile index 3f862a475..bd29fbae8 100644 --- a/server/core/Makefile +++ b/server/core/Makefile @@ -41,7 +41,7 @@ UTILSPATH := $(ROOT_PATH)/utils CC=cc -CFLAGS=-c -I/usr/include -I../include -I../inih \ +CFLAGS=-c -I/usr/include -I../include -I../modules/include -I../inih \ $(MYSQL_HEADERS) \ -I$(LOGPATH) -I$(UTILSPATH) \ -Wall -g @@ -59,7 +59,7 @@ SRCS= atomic.c buffer.c spinlock.c gateway.c \ monitor.c adminusers.c secrets.c HDRS= ../include/atomic.h ../include/buffer.h ../include/dcb.h \ - ../include/gw.h ../include/mysql_protocol.h \ + ../include/gw.h ../modules/include/mysql_client_server_protocol.h \ ../include/session.h ../include/spinlock.h ../include/thread.h \ ../include/modules.h ../include/poll.h ../include/config.h \ ../include/users.h ../include/hashtable.h ../include/gwbitmask.h \ diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 4847c4c8b..41dda5a92 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -42,6 +42,7 @@ #include #include #include +#include #define USERS_QUERY_NO_ROOT " AND user NOT IN ('root')" #define LOAD_MYSQL_USERS_QUERY "SELECT user, host, password, concat(user,host,password) AS userdata FROM mysql.user WHERE user IS NOT NULL AND user <> ''" diff --git a/server/core/dcb.c b/server/core/dcb.c index 3e7a50674..16ca964ac 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -68,6 +68,7 @@ #include #include #include +#include extern int lm_enabled_logfiles_bitmask; diff --git a/server/core/poll.c b/server/core/poll.c index f1c65ebea..0b23a6b05 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -27,6 +27,7 @@ #include #include #include +#include extern int lm_enabled_logfiles_bitmask; diff --git a/server/core/secrets.c b/server/core/secrets.c index a11b0276d..c4d1822f5 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -21,6 +21,7 @@ #include #include #include +#include extern int lm_enabled_logfiles_bitmask; /** diff --git a/server/core/server.c b/server/core/server.c index 058db7460..eff77c937 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -26,6 +26,7 @@ * 18/06/13 Mark Riddoch Initial implementation * 17/05/14 Mark Riddoch Addition of unique_name * 20/05/14 Massimiliano Pinto Addition of server_string + * 21/05/14 Massimiliano Pinto Addition of node_id * * @endverbatim */ @@ -71,6 +72,7 @@ SERVER *server; server->monpw = NULL; server->unique_name = NULL; server->server_string = NULL; + server->node_id = -1; spinlock_acquire(&server_spin); server->next = allServers; @@ -244,8 +246,9 @@ char *stat; dcb_printf(dcb, "\tPort: %d\n", ptr->port); if (ptr->server_string) dcb_printf(dcb, "\tServer Version:\t\t%s\n", ptr->server_string); + dcb_printf(dcb, "\tNode Id: %d\n", ptr->node_id); dcb_printf(dcb, "\tNumber of connections: %d\n", ptr->stats.n_connections); - dcb_printf(dcb, "\tCurrent no. of connections: %d\n", ptr->stats.n_current); + dcb_printf(dcb, "\tCurrent no. of conns: %d\n", ptr->stats.n_current); ptr = ptr->next; } spinlock_release(&server_spin); @@ -271,8 +274,9 @@ char *stat; dcb_printf(dcb, "\tPort: %d\n", server->port); if (server->server_string) dcb_printf(dcb, "\tServer Version:\t\t%s\n", server->server_string); + dcb_printf(dcb, "\tNode Id: %d\n", server->node_id); dcb_printf(dcb, "\tNumber of connections: %d\n", server->stats.n_connections); - dcb_printf(dcb, "\tCurrent No. of connections: %d\n", server->stats.n_current); + dcb_printf(dcb, "\tCurrent No. of conns: %d\n", server->stats.n_current); } /** diff --git a/server/core/service.c b/server/core/service.c index 79522513c..efc441173 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -702,7 +702,7 @@ SERVICE *ptr; * @param dcb DCB to print data to * @param service The service to print */ -dprintService(DCB *dcb, SERVICE *service) +void dprintService(DCB *dcb, SERVICE *service) { SERVER *server = service->databases; diff --git a/server/include/server.h b/server/include/server.h index 19ca798ae..dfd439852 100644 --- a/server/include/server.h +++ b/server/include/server.h @@ -33,6 +33,7 @@ * 22/07/13 Mark Riddoch Addition of JOINED status for Galera * 18/05/14 Mark Riddoch Addition of unique_name field * 20/05/14 Massimiliano Pinto Addition of server_string field + * 20/05/14 Massimiliano Pinto Addition of node_id field * * @endverbatim */ @@ -64,6 +65,7 @@ typedef struct server { struct server *next; /**< Next server */ struct server *nextdb; /**< Next server in list attached to a service */ char *server_string; /**< Server version string, i.e. MySQL server version */ + long node_id; /**< Node id, server_id for M/S or local_index for Galera */ } SERVER; /** @@ -103,7 +105,7 @@ typedef struct server { * Is the server joined Galera node? The server must be running and joined. */ #define SERVER_IS_JOINED(server) \ - (((server)->status & (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE|SERVER_JOINED)) == (SERVER_RUNNING|SERVER_JOINED)) + (((server)->status & (SERVER_RUNNING|SERVER_JOINED)) == (SERVER_RUNNING|SERVER_JOINED)) extern SERVER *server_alloc(char *, char *, unsigned short); extern int server_free(SERVER *); diff --git a/server/modules/monitor/galera_mon.c b/server/modules/monitor/galera_mon.c index ecdfa44a3..96b891d58 100644 --- a/server/modules/monitor/galera_mon.c +++ b/server/modules/monitor/galera_mon.c @@ -22,8 +22,10 @@ * @verbatim * Revision History * - * Date Who Description - * 22/07/13 Mark Riddoch Initial implementation + * Date Who Description + * 22/07/13 Mark Riddoch Initial implementation + * 21/05/14 Massimiliano Pinto Monitor sets a master server + * that has the lowest value of wsrep_local_index * * @endverbatim */ @@ -45,7 +47,7 @@ extern int lm_enabled_logfiles_bitmask; static void monitorMain(void *); -static char *version_str = "V1.0.0"; +static char *version_str = "V1.1.0"; static void *startMonitor(void *); static void stopMonitor(void *); @@ -121,7 +123,7 @@ MYSQL_MONITOR *handle; handle->defaultPasswd = NULL; spinlock_init(&handle->lock); } - handle->tid = thread_start(monitorMain, handle); + handle->tid = (THREAD)thread_start(monitorMain, handle); return handle; } @@ -136,7 +138,7 @@ stopMonitor(void *arg) MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; handle->shutdown = 1; - thread_wait(handle->tid); + thread_wait((void *)handle->tid); } /** @@ -280,6 +282,8 @@ MYSQL_RES *result; int num_fields; int isjoined = 0; char *uname = defaultUser, *passwd = defaultPasswd; +unsigned long int server_version = 0; +char *server_string; if (database->server->monuser != NULL) { @@ -297,6 +301,7 @@ char *uname = defaultUser, *passwd = defaultPasswd; uname, dpwd, NULL, database->server->port, NULL, 0) == NULL) { server_clear_status(database->server, SERVER_RUNNING); + database->server->node_id = -1; free(dpwd); return; } @@ -306,6 +311,15 @@ char *uname = defaultUser, *passwd = defaultPasswd; /* If we get this far then we have a working connection */ server_set_status(database->server, SERVER_RUNNING); + /* get server version from current server */ + server_version = mysql_get_server_version(database->con); + + /* get server version string */ + server_string = (char *)mysql_get_server_info(database->con); + if (server_string) { + database->server->server_string = strdup(server_string); + } + /* Check if the the Galera FSM shows this node is joined to the cluster */ if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_state_comment'") == 0 && (result = mysql_store_result(database->con)) != NULL) @@ -319,6 +333,25 @@ char *uname = defaultUser, *passwd = defaultPasswd; mysql_free_result(result); } + /* Check the the Galera node index in the cluster */ + if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_index'") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + long local_index = -1; + num_fields = mysql_num_fields(result); + while ((row = mysql_fetch_row(result))) + { + local_index = strtol(row[1], NULL, 10); + if ((errno == ERANGE && (local_index == LONG_MAX + || local_index == LONG_MIN)) || (errno != 0 && local_index == 0)) + { + local_index = -1; + } + database->server->node_id = local_index; + } + mysql_free_result(result); + } + if (isjoined) server_set_status(database->server, SERVER_JOINED); else @@ -335,6 +368,7 @@ monitorMain(void *arg) { MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; MONITOR_SERVERS *ptr; +long master_id; if (mysql_thread_init()) { @@ -347,6 +381,8 @@ MONITOR_SERVERS *ptr; handle->status = MONITOR_RUNNING; while (1) { + master_id = -1; + if (handle->shutdown) { handle->status = MONITOR_STOPPING; @@ -354,10 +390,48 @@ MONITOR_SERVERS *ptr; handle->status = MONITOR_STOPPED; return; } + ptr = handle->databases; + while (ptr) { monitorDatabase(ptr, handle->defaultUser, handle->defaultPasswd); + + /* set master_id to the lowest value of ptr->server->node_id */ + + if (ptr->server->node_id >= 0 && SERVER_IS_JOINED(ptr->server)) { + if (ptr->server->node_id < master_id && master_id >= 0) { + master_id = ptr->server->node_id; + } else { + if (master_id < 0) { + master_id = ptr->server->node_id; + } + } + } else { + /* clear M/S status */ + server_clear_status(ptr->server, SERVER_SLAVE); + server_clear_status(ptr->server, SERVER_MASTER); + } + ptr = ptr->next; + } + + ptr = handle->databases; + + /* this server loop sets Master and Slave roles */ + while (ptr) + { + if (ptr->server->node_id >= 0 && master_id >= 0) { + /* set the Master role */ + if (SERVER_IS_JOINED(ptr->server) && (ptr->server->node_id == master_id)) { + server_set_status(ptr->server, SERVER_MASTER); + server_clear_status(ptr->server, SERVER_SLAVE); + } else if (SERVER_IS_JOINED(ptr->server) && (ptr->server->node_id > master_id)) { + /* set the Slave role */ + server_set_status(ptr->server, SERVER_SLAVE); + server_clear_status(ptr->server, SERVER_MASTER); + } + } + ptr = ptr->next; } thread_millisleep(MONITOR_INTERVAL); diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index 4cf7e6938..ddf1f7cbc 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -128,7 +128,7 @@ MYSQL_MONITOR *handle; handle->defaultPasswd = NULL; spinlock_init(&handle->lock); } - handle->tid = thread_start(monitorMain, handle); + handle->tid = (THREAD)thread_start(monitorMain, handle); return handle; } @@ -143,7 +143,7 @@ stopMonitor(void *arg) MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; handle->shutdown = 1; - thread_wait(handle->tid); + thread_wait((void *)handle->tid); } /** @@ -334,6 +334,25 @@ char *server_string; database->server->server_string = strdup(server_string); } + /* get server_id form current node */ + if (mysql_query(database->con, "SELECT @@server_id") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + long server_id = -1; + num_fields = mysql_num_fields(result); + while ((row = mysql_fetch_row(result))) + { + server_id = strtol(row[0], NULL, 10); + if ((errno == ERANGE && (server_id == LONG_MAX + || server_id == LONG_MIN)) || (errno != 0 && server_id == 0)) + { + server_id = -1; + } + database->server->node_id = server_id; + } + mysql_free_result(result); + } + /* Check SHOW SLAVE HOSTS - if we get rows then we are a master */ if (mysql_query(database->con, "SHOW SLAVE HOSTS")) { diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 2ba8402b8..e4b461dad 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -283,6 +283,11 @@ static int gw_read_backend_event(DCB *dcb) { } if (backend_protocol->state == MYSQL_AUTH_FAILED) { + /** + * protocol state won't change anymore, + * lock can be freed + */ + spinlock_release(&dcb->authlock); spinlock_acquire(&dcb->delayqlock); /*< * vraa : errorHandle @@ -351,7 +356,7 @@ static int gw_read_backend_event(DCB *dcb) { /* close router_session */ router->closeSession(router_instance, rsession); rc = 1; - goto return_with_lock; + goto return_rc; } else {