diff --git a/server/core/server.c b/server/core/server.c index 058db7460..7358897fd 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/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..a00a61253 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 *); @@ -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);