diff --git a/server/core/monitor.c b/server/core/monitor.c index a8401e6bb..70f3f9efa 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -80,7 +80,13 @@ MONITOR *mon; } mon->handle = NULL; - + mon->databases = NULL; + mon->name = NULL; + mon->password = NULL; + mon->read_timeout = DEFAULT_READ_TIMEOUT; + mon->write_timeout = DEFAULT_WRITE_TIMEOUT; + mon->connect_timeout = DEFAULT_CONNECT_TIMEOUT; + spinlock_init(&mon->lock); spinlock_acquire(&monLock); mon->next = allMonitors; allMonitors = mon; @@ -100,7 +106,7 @@ monitor_free(MONITOR *mon) { MONITOR *ptr; - mon->module->stopMonitor(mon->handle); + mon->module->stopMonitor(mon); mon->state = MONITOR_STATE_FREED; spinlock_acquire(&monLock); if (allMonitors == mon) @@ -127,7 +133,7 @@ MONITOR *ptr; void monitorStart(MONITOR *monitor, void* params) { - monitor->handle = (*monitor->module->startMonitor)(monitor->handle,params); + monitor->handle = (*monitor->module->startMonitor)(monitor,params); monitor->state = MONITOR_STATE_RUNNING; } @@ -142,7 +148,7 @@ monitorStop(MONITOR *monitor) if(monitor->state != MONITOR_STATE_STOPPED) { monitor->state = MONITOR_STATE_STOPPING; - monitor->module->stopMonitor(monitor->handle); + monitor->module->stopMonitor(monitor); monitor->state = MONITOR_STATE_STOPPED; } } @@ -175,7 +181,30 @@ MONITOR *ptr; void monitorAddServer(MONITOR *mon, SERVER *server) { - mon->module->registerServer(mon->handle, server); + MONITOR_SERVERS *ptr, *db; + + if ((db = (MONITOR_SERVERS *)malloc(sizeof(MONITOR_SERVERS))) == NULL) + return; + db->server = server; + db->con = NULL; + db->next = NULL; + db->mon_err_count = 0; + db->mon_prev_status = 0; + /* pending status is updated by get_replication_tree */ + db->pending_status = 0; + + spinlock_acquire(&mon->lock); + + if (mon->databases == NULL) + mon->databases = db; + else + { + ptr = mon->databases; + while (ptr->next != NULL) + ptr = ptr->next; + ptr->next = db; + } + spinlock_release(&mon->lock); } /** @@ -189,7 +218,9 @@ monitorAddServer(MONITOR *mon, SERVER *server) void monitorAddUser(MONITOR *mon, char *user, char *passwd) { - mon->module->defaultUser(mon->handle, user, passwd); + mon->user = strdup(user); + mon->password = strdup(passwd); + //mon->module->defaultUser(mon->handle, user, passwd); } /** @@ -288,10 +319,7 @@ MONITOR *ptr; void monitorSetInterval (MONITOR *mon, unsigned long interval) { - if (mon->module->setInterval != NULL) { - mon->interval = interval; - mon->module->setInterval(mon->handle, interval); - } + mon->interval = interval; } /** @@ -303,9 +331,55 @@ monitorSetInterval (MONITOR *mon, unsigned long interval) */ void monitorSetNetworkTimeout(MONITOR *mon, int type, int value) { - if (mon->module->setNetworkTimeout != NULL) { - mon->module->setNetworkTimeout(mon->handle, type, value); + + int max_timeout = (int)(mon->interval/1000); + int new_timeout = max_timeout -1; + + if (new_timeout <= 0) + new_timeout = DEFAULT_CONNECT_TIMEOUT; + + switch(type) { + case MONITOR_CONNECT_TIMEOUT: + if (value < max_timeout) { + memcpy(&mon->connect_timeout, &value, sizeof(int)); + } else { + memcpy(&mon->connect_timeout, &new_timeout, sizeof(int)); + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "warning : Monitor Connect Timeout %i is greater than monitor interval ~%i seconds" + ", lowering to %i seconds", value, max_timeout, new_timeout))); } + break; + + case MONITOR_READ_TIMEOUT: + if (value < max_timeout) { + memcpy(&mon->read_timeout, &value, sizeof(int)); + } else { + memcpy(&mon->read_timeout, &new_timeout, sizeof(int)); + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "warning : Monitor Read Timeout %i is greater than monitor interval ~%i seconds" + ", lowering to %i seconds", value, max_timeout, new_timeout))); + } + break; + + case MONITOR_WRITE_TIMEOUT: + if (value < max_timeout) { + memcpy(&mon->write_timeout, &value, sizeof(int)); + } else { + memcpy(&mon->write_timeout, &new_timeout, sizeof(int)); + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "warning : Monitor Write Timeout %i is greater than monitor interval ~%i seconds" + ", lowering to %i seconds", value, max_timeout, new_timeout))); + } + break; + default: + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Monitor setNetworkTimeout received an unsupported action type %i", type))); + break; + } } /** diff --git a/server/include/monitor.h b/server/include/monitor.h index e114f3424..681f34bac 100644 --- a/server/include/monitor.h +++ b/server/include/monitor.h @@ -17,6 +17,7 @@ * * Copyright MariaDB Corporation Ab 2013-2014 */ +#include #include #include #include @@ -69,19 +70,14 @@ typedef struct { void *(*startMonitor)(void *, void*); void (*stopMonitor)(void *); - void (*registerServer)(void *, SERVER *); - void (*unregisterServer)(void *, SERVER *); - void (*defaultUser)(void *, char *, char *); void (*diagnostics)(DCB *, void *); - void (*setInterval)(void *, size_t); - void (*setNetworkTimeout)(void *, int, int); } MONITOR_OBJECT; /** * The monitor API version number. Any change to the monitor module API * must change these versions usign the rules defined in modinfo.h */ -#define MONITOR_VERSION {2, 0, 0} +#define MONITOR_VERSION {3, 0, 0} /** Monitor's poll frequency */ #define MON_BASE_INTERVAL_MS 100 @@ -112,12 +108,46 @@ typedef enum #define DEFAULT_READ_TIMEOUT 1 #define DEFAULT_WRITE_TIMEOUT 2 + +#define MONITOR_RUNNING 1 +#define MONITOR_STOPPING 2 +#define MONITOR_STOPPED 3 + +#define MONITOR_INTERVAL 10000 // in milliseconds +#define MONITOR_DEFAULT_ID 1UL // unsigned long value +#define MONITOR_MAX_NUM_SLAVES 20 //number of MySQL slave servers associated to a MySQL master server + + +/** + * The linked list of servers that are being monitored by the monitor module. + */ +typedef struct monitor_servers { + SERVER *server; /**< The server being monitored */ + MYSQL *con; /**< The MySQL connection */ + int mon_err_count; + unsigned int mon_prev_status; + unsigned int pending_status; /**< Pending Status flag bitmap */ + struct monitor_servers + *next; /**< The next server in the list */ +} MONITOR_SERVERS; + /** * Representation of the running monitor. */ typedef struct monitor { char *name; /**< The name of the monitor module */ + char* user; /*< Monitor username */ + char* password; /*< Monitor password */ + SPINLOCK lock; + MONITOR_SERVERS* databases; /*< List of databases the monitor monitors */ monitor_state_t state; /**< The state of the monitor */ + int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */ + int read_timeout; /**< Timeout in seconds to read from the server. + * There are retries and the total effective timeout value is three times the option value. + */ + int write_timeout; /**< Timeout in seconds for each attempt to write to the server. + * There are retries and the total effective timeout value is two times the option value. + */ MONITOR_OBJECT *module; /**< The "monitor object" */ void *handle; /**< Handle returned from startMonitor */ size_t interval; /**< The monitor interval */ diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index 0991e72bb..fae50ef4e 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -60,7 +60,7 @@ extern __thread log_info_t tls_log_info; static void monitorMain(void *); -static char *version_str = "V1.5.0"; +static char *version_str = "V2.0.0"; MODULE_INFO info = { MODULE_API_MONITOR, @@ -85,13 +85,8 @@ static bool mon_print_fail_status(MONITOR_SERVERS* mon_srv); static MONITOR_OBJECT MyObject = { startMonitor, - stopMonitor, - registerServer, - unregisterServer, - defaultUsers, - diagnostics, - setInterval, - setNetworkTimeout + stopMonitor, + diagnostics }; /** @@ -142,30 +137,23 @@ GetModuleObject() static void * startMonitor(void *arg,void* opt) { -GALERA_MONITOR *handle; + MONITOR* mon = arg; +GALERA_MONITOR *handle = mon->handle; CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - if (arg != NULL) + if (handle != NULL) { - handle = (GALERA_MONITOR *)arg; handle->shutdown = 0; } else { if ((handle = (GALERA_MONITOR *)malloc(sizeof(GALERA_MONITOR))) == NULL) return NULL; - handle->databases = NULL; handle->shutdown = 0; - handle->defaultUser = NULL; - handle->defaultPasswd = NULL; handle->id = MONITOR_DEFAULT_ID; - handle->interval = MONITOR_INTERVAL; handle->disableMasterFailback = 0; handle->availableWhenDonor = 0; - handle->disableMasterRoleSetting = 0; + handle->disableMasterRoleSetting = 0; handle->master = NULL; - handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT; - handle->read_timeout=DEFAULT_READ_TIMEOUT; - handle->write_timeout=DEFAULT_WRITE_TIMEOUT; handle->master_down_script = NULL; spinlock_init(&handle->lock); } @@ -200,82 +188,13 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; static void stopMonitor(void *arg) { -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; +GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle; handle->shutdown = 1; thread_wait((void *)handle->tid); } -/** - * Register a server that must be added to the monitored servers for - * a monitoring module. - * - * @param arg A handle on the running monitor module - * @param server The server to add - */ -static void -registerServer(void *arg, SERVER *server) -{ -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; -MONITOR_SERVERS *ptr, *db; - - if ((db = (MONITOR_SERVERS *)malloc(sizeof(MONITOR_SERVERS))) == NULL) - return; - db->server = server; - db->con = NULL; - db->next = NULL; - spinlock_acquire(&handle->lock); - if (handle->databases == NULL) - handle->databases = db; - else - { - ptr = handle->databases; - while (ptr->next != NULL) - ptr = ptr->next; - ptr->next = db; - } - spinlock_release(&handle->lock); -} - -/** - * Remove a server from those being monitored by a monitoring module - * - * @param arg A handle on the running monitor module - * @param server The server to remove - */ -static void -unregisterServer(void *arg, SERVER *server) -{ -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; -MONITOR_SERVERS *ptr, *lptr; - - spinlock_acquire(&handle->lock); - if (handle->databases == NULL) - { - spinlock_release(&handle->lock); - return; - } - if (handle->databases->server == server) - { - ptr = handle->databases; - handle->databases = handle->databases->next; - free(ptr); - } - else - { - ptr = handle->databases; - while (ptr->next != NULL && ptr->next->server != server) - ptr = ptr->next; - if (ptr->next) - { - lptr = ptr->next; - ptr->next = ptr->next->next; - free(lptr); - } - } - spinlock_release(&handle->lock); -} - /** * Diagnostic interface * @@ -285,7 +204,8 @@ MONITOR_SERVERS *ptr, *lptr; static void diagnostics(DCB *dcb, void *arg) { -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; +GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle; MONITOR_SERVERS *db; char *sep; @@ -302,16 +222,16 @@ char *sep; break; } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", handle->interval); + dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); dcb_printf(dcb,"\tMaster Failback:\t%s\n", (handle->disableMasterFailback == 1) ? "off" : "on"); dcb_printf(dcb,"\tAvailable when Donor:\t%s\n", (handle->availableWhenDonor == 1) ? "on" : "off"); dcb_printf(dcb,"\tMaster Role Setting Disabled:\t%s\n", (handle->disableMasterRoleSetting == 1) ? "on" : "off"); - dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", handle->connect_timeout); - dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout); - dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout); + dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); + dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); + dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); dcb_printf(dcb, "\tMonitored servers: "); - db = handle->databases; + db = mon->databases; sep = ""; while (db) { @@ -322,27 +242,6 @@ char *sep; dcb_printf(dcb, "\n"); } -/** - * Set the default username and password to use to monitor if the server does not - * override this. - * - * @param arg The handle allocated by startMonitor - * @param uname The default user name - * @param passwd The default password - */ -static void -defaultUsers(void *arg, char *uname, char *passwd) -{ -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; - - if (handle->defaultUser) - free(handle->defaultUser); - if (handle->defaultPasswd) - free(handle->defaultPasswd); - handle->defaultUser = strdup(uname); - handle->defaultPasswd = strdup(passwd); -} - /** * Monitor an individual server * @@ -350,14 +249,14 @@ GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; * @param database The database to probe */ static void -monitorDatabase(GALERA_MONITOR *handle, MONITOR_SERVERS *database) +monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database) { + GALERA_MONITOR* handle = (GALERA_MONITOR*)mon->handle; MYSQL_ROW row; MYSQL_RES *result; -int num_fields; int isjoined = 0; -char *uname = handle->defaultUser; -char *passwd = handle->defaultPasswd; +char *uname = mon->user; +char *passwd = mon->password; unsigned long int server_version = 0; char *server_string; @@ -379,16 +278,15 @@ char *server_string; if (database->con == NULL || mysql_ping(database->con) != 0) { char *dpwd = decryptPassword(passwd); - int rc; - int connect_timeout = handle->connect_timeout; - int read_timeout = handle->read_timeout; - int write_timeout = handle->write_timeout; + int connect_timeout = mon->connect_timeout; + int read_timeout = mon->read_timeout; + int write_timeout = mon->write_timeout; database->con = mysql_init(NULL); - rc = mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout); - rc = mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); - rc = mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout); + mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout); + mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); + mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout); if (mysql_real_connect(database->con, database->server->name, uname, dpwd, NULL, database->server->port, NULL, 0) == NULL) @@ -433,9 +331,6 @@ char *server_string; /* 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) { @@ -448,7 +343,6 @@ char *server_string; if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_state'") == 0 && (result = mysql_store_result(database->con)) != NULL) { - num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { if (strcmp(row[1], "4") == 0) @@ -459,7 +353,6 @@ char *server_string; if (mysql_query(database->con, "SHOW VARIABLES LIKE 'wsrep_sst_method'") == 0 && (result = mysql_store_result(database->con)) != NULL) { - num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { if (strncmp(row[1], "xtrabackup", 10) == 0) @@ -476,7 +369,6 @@ char *server_string; && (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); @@ -504,7 +396,8 @@ char *server_string; static void monitorMain(void *arg) { -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; +GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle; MONITOR_SERVERS *ptr; size_t nrounds = 0; MONITOR_SERVERS *candidate_master = NULL; @@ -540,7 +433,7 @@ int log_no_members = 1; * round. */ - if (nrounds != 0 && ((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >= MON_BASE_INTERVAL_MS) + if (nrounds != 0 && ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= MON_BASE_INTERVAL_MS) { nrounds += 1; continue; @@ -551,11 +444,11 @@ int log_no_members = 1; /* reset cluster members counter */ is_cluster=0; - ptr = handle->databases; + ptr = mon->databases; while (ptr) { - monitorDatabase(handle, ptr); + monitorDatabase(mon, ptr); if(ptr->mon_prev_status & SERVER_MASTER && SERVER_IS_DOWN(ptr->server)) @@ -619,7 +512,7 @@ int log_no_members = 1; */ /* get the candidate master, following MIN(node_id) rule */ - candidate_master = get_candidate_master(handle->databases); + candidate_master = get_candidate_master(mon->databases); /* Select the master, based on master_stickiness */ if (1 == handle->disableMasterRoleSetting) { @@ -629,7 +522,7 @@ int log_no_members = 1; handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness); } - ptr = handle->databases; + ptr = mon->databases; while (ptr) { if (!SERVER_IS_JOINED(ptr->server) || SERVER_IN_MAINT(ptr->server)) { @@ -681,19 +574,6 @@ int log_no_members = 1; } } -/** - * Set the monitor sampling interval. - * - * @param arg The handle allocated by startMonitor - * @param interval The interval to set in monitor struct, in milliseconds - */ -static void -setInterval(void *arg, size_t interval) -{ -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; - memcpy(&handle->interval, &interval, sizeof(unsigned long)); -} - /** * get candidate master from all nodes * @@ -796,67 +676,6 @@ GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; memcpy(&handle->availableWhenDonor, &disable, sizeof(int)); } -/** - * Set the timeouts to use in the monitor. - * - * @param arg The handle allocated by startMonitor - * @param type The connect timeout type - * @param value The timeout value to set - */ -static void -setNetworkTimeout(void *arg, int type, int value) -{ -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; -int max_timeout = (int)(handle->interval/1000); -int new_timeout = max_timeout -1; - - if (new_timeout <= 0) - new_timeout = DEFAULT_CONNECT_TIMEOUT; - - switch(type) { - case MONITOR_CONNECT_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->connect_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->connect_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Connect Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - - case MONITOR_READ_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->read_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->read_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Read Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - - case MONITOR_WRITE_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->write_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->write_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Write Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - default: - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Monitor setNetworkTimeout received an unsupported action type %i", type))); - break; - } -} - /** * Check if current monitored server status has changed * @@ -890,10 +709,7 @@ static bool mon_print_fail_status( { bool succp; int errcount = mon_srv->mon_err_count; - uint8_t modval; - - modval = 1<<(MIN(errcount/10, 7)); - + if (SERVER_IS_DOWN(mon_srv->server) && errcount == 0) { succp = true; diff --git a/server/modules/monitor/galeramon.h b/server/modules/monitor/galeramon.h index 2b804965d..956be528f 100644 --- a/server/modules/monitor/galeramon.h +++ b/server/modules/monitor/galeramon.h @@ -42,24 +42,13 @@ typedef struct { pthread_t tid; /**< id of monitor thread */ int shutdown; /**< Flag to shutdown the monitor thread */ int status; /**< Monitor status */ - char *defaultUser; /**< Default username for monitoring */ - char *defaultPasswd; /**< Default password for monitoring */ - unsigned long interval; /**< Monitor sampling interval */ unsigned long id; /**< Monitor ID */ int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */ int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ - MONITOR_SERVERS *databases; /**< Linked list of servers to monitor */ - int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */ - int read_timeout; /**< Timeout in seconds to read from the server. - * There are retries and the total effective timeout value is three times the option value. - */ - int write_timeout; /**< Timeout in seconds for each attempt to write to the server. - * There are retries and the total effective timeout value is two times the option value. - */ - EXTERNCMD* master_down_script; + EXTERNCMD* master_down_script; } GALERA_MONITOR; #endif diff --git a/server/modules/monitor/mm_mon.c b/server/modules/monitor/mm_mon.c index 60acea825..705583f6c 100644 --- a/server/modules/monitor/mm_mon.c +++ b/server/modules/monitor/mm_mon.c @@ -49,7 +49,7 @@ extern __thread log_info_t tls_log_info; static void monitorMain(void *); -static char *version_str = "V1.0.1"; +static char *version_str = "V1.1.1"; MODULE_INFO info = { MODULE_API_MONITOR, @@ -60,26 +60,18 @@ MODULE_INFO info = { static void *startMonitor(void *,void*); static void stopMonitor(void *); -static void registerServer(void *, SERVER *); -static void unregisterServer(void *, SERVER *); -static void defaultUser(void *, char *, char *); static void diagnostics(DCB *, void *); -static void setInterval(void *, size_t); static void detectStaleMaster(void *, int); static bool mon_status_changed(MONITOR_SERVERS* mon_srv); static bool mon_print_fail_status(MONITOR_SERVERS* mon_srv); -static MONITOR_SERVERS *get_current_master(MYSQL_MONITOR *); +static MONITOR_SERVERS *get_current_master(MONITOR *); static void monitor_set_pending_status(MONITOR_SERVERS *, int); static void monitor_clear_pending_status(MONITOR_SERVERS *, int); static MONITOR_OBJECT MyObject = { startMonitor, stopMonitor, - registerServer, - unregisterServer, - defaultUser, - diagnostics, - setInterval + diagnostics }; /** @@ -131,23 +123,19 @@ GetModuleObject() static void * startMonitor(void *arg,void* opt) { -MYSQL_MONITOR *handle; + MONITOR* mon = (MONITOR*)arg; +MYSQL_MONITOR *handle = mon->handle; CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - if (arg) + if (handle) { - handle = arg; /* Must be a restart */ handle->shutdown = 0; } else { if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL) return NULL; - handle->databases = NULL; handle->shutdown = 0; - handle->defaultUser = NULL; - handle->defaultPasswd = NULL; handle->id = MONITOR_DEFAULT_ID; - handle->interval = MONITOR_INTERVAL; handle->replicationHeartbeat = 0; handle->detectStaleMaster = 0; handle->master = NULL; @@ -179,103 +167,6 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; thread_wait((void *)handle->tid); } -/** - * Register a server that must be added to the monitored servers for - * a monitoring module. - * - * @param arg A handle on the running monitor module - * @param server The server to add - */ -static void -registerServer(void *arg, SERVER *server) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -MONITOR_SERVERS *ptr, *db; - - if ((db = (MONITOR_SERVERS *)malloc(sizeof(MONITOR_SERVERS))) == NULL) - return; - db->server = server; - db->con = NULL; - db->next = NULL; - db->mon_err_count = 0; - db->mon_prev_status = 0; - /* pending status is updated by monitorMain */ - db->pending_status = 0; - - spinlock_acquire(&handle->lock); - - if (handle->databases == NULL) - handle->databases = db; - else - { - ptr = handle->databases; - while (ptr->next != NULL) - ptr = ptr->next; - ptr->next = db; - } - spinlock_release(&handle->lock); -} - -/** - * Remove a server from those being monitored by a monitoring module - * - * @param arg A handle on the running monitor module - * @param server The server to remove - */ -static void -unregisterServer(void *arg, SERVER *server) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -MONITOR_SERVERS *ptr, *lptr; - - spinlock_acquire(&handle->lock); - if (handle->databases == NULL) - { - spinlock_release(&handle->lock); - return; - } - if (handle->databases->server == server) - { - ptr = handle->databases; - handle->databases = handle->databases->next; - free(ptr); - } - else - { - ptr = handle->databases; - while (ptr->next != NULL && ptr->next->server != server) - ptr = ptr->next; - if (ptr->next) - { - lptr = ptr->next; - ptr->next = ptr->next->next; - free(lptr); - } - } - spinlock_release(&handle->lock); -} - -/** - * Set the default username and password to use to monitor if the server does not - * override this. - * - * @param arg The handle allocated by startMonitor - * @param uname The default user name - * @param passwd The default password - */ -static void -defaultUser(void *arg, char *uname, char *passwd) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - - if (handle->defaultUser) - free(handle->defaultUser); - if (handle->defaultPasswd) - free(handle->defaultPasswd); - handle->defaultUser = strdup(uname); - handle->defaultPasswd = strdup(passwd); -} - /** * Daignostic interface * @@ -284,7 +175,8 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; */ static void diagnostics(DCB *dcb, void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; +MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; MONITOR_SERVERS *db; char *sep; @@ -301,11 +193,11 @@ char *sep; break; } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", handle->interval); + dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); dcb_printf(dcb,"\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled"); dcb_printf(dcb, "\tMonitored servers: "); - db = handle->databases; + db = mon->databases; sep = ""; while (db) { @@ -327,15 +219,16 @@ char *sep; * @param database The database to probe */ static void -monitorDatabase(MYSQL_MONITOR *handle, MONITOR_SERVERS *database) +monitorDatabase(MONITOR* mon, MONITOR_SERVERS *database) { + MYSQL_MONITOR *handle = mon->handle; MYSQL_ROW row; MYSQL_RES *result; int num_fields; int isslave = 0; int ismaster = 0; -char *uname = handle->defaultUser; -char *passwd = handle->defaultPasswd; +char *uname = mon->user; +char *passwd = mon->password; unsigned long int server_version = 0; char *server_string; @@ -358,12 +251,11 @@ char *server_string; if (database->con == NULL || mysql_ping(database->con) != 0) { char *dpwd = decryptPassword(passwd); - int rc; int read_timeout = 1; database->con = mysql_init(NULL); - rc = mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); + mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); if (mysql_real_connect(database->con, database->server->name, @@ -437,7 +329,7 @@ char *server_string; && (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); @@ -463,7 +355,7 @@ char *server_string; { int i = 0; long master_id = -1; - num_fields = mysql_num_fields(result); + while ((row = mysql_fetch_row(result))) { /* get Slave_IO_Running and Slave_SQL_Running values*/ @@ -502,7 +394,7 @@ char *server_string; && (result = mysql_store_result(database->con)) != NULL) { long master_id = -1; - num_fields = mysql_num_fields(result); + while ((row = mysql_fetch_row(result))) { /* get Slave_IO_Running and Slave_SQL_Running values*/ @@ -534,7 +426,7 @@ char *server_string; if (mysql_query(database->con, "SHOW GLOBAL VARIABLES LIKE 'read_only'") == 0 && (result = mysql_store_result(database->con)) != NULL) { - num_fields = mysql_num_fields(result); + while ((row = mysql_fetch_row(result))) { if (strncasecmp(row[1], "OFF", 3) == 0) { @@ -584,7 +476,8 @@ char *server_string; static void monitorMain(void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; +MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; MONITOR_SERVERS *ptr; int detect_stale_master = handle->detectStaleMaster; MONITOR_SERVERS *root_master; @@ -619,7 +512,7 @@ size_t nrounds = 0; * round. */ if (nrounds != 0 && - ((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >= + ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= MON_BASE_INTERVAL_MS) { nrounds += 1; @@ -628,7 +521,7 @@ size_t nrounds = 0; nrounds += 1; /* start from the first server in the list */ - ptr = handle->databases; + ptr = mon->databases; while (ptr) { @@ -636,7 +529,7 @@ size_t nrounds = 0; ptr->pending_status = ptr->server->status; /* monitor current node */ - monitorDatabase(handle, ptr); + monitorDatabase(mon, ptr); if (mon_status_changed(ptr)) { @@ -668,11 +561,11 @@ size_t nrounds = 0; } /* Get Master server pointer */ - root_master = get_current_master(handle); + root_master = get_current_master(mon); /* Update server status from monitor pending status on that server*/ - ptr = handle->databases; + ptr = mon->databases; while (ptr) { if (! SERVER_IN_MAINT(ptr->server)) { @@ -691,19 +584,6 @@ size_t nrounds = 0; } } } - -/** - * Set the monitor sampling interval. - * - * @param arg The handle allocated by startMonitor - * @param interval The interval to set in monitor struct, in milliseconds - */ -static void -setInterval(void *arg, size_t interval) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - memcpy(&handle->interval, &interval, sizeof(unsigned long)); -} /** * Enable/Disable the MySQL Replication Stale Master dectection, allowing a previouvsly detected master to still act as a Master. @@ -716,7 +596,8 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; static void detectStaleMaster(void *arg, int enable) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; +MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; memcpy(&handle->detectStaleMaster, &enable, sizeof(int)); } @@ -790,10 +671,11 @@ monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit) * @return The server at root level with SERVER_MASTER bit */ -static MONITOR_SERVERS *get_current_master(MYSQL_MONITOR *handle) { +static MONITOR_SERVERS *get_current_master(MONITOR *mon) { + MYSQL_MONITOR* handle = mon->handle; MONITOR_SERVERS *ptr; - ptr = handle->databases; + ptr = mon->databases; while (ptr) { diff --git a/server/modules/monitor/monitor_common.h b/server/modules/monitor/monitor_common.h index 1efbf1dbc..e3ba513e4 100644 --- a/server/modules/monitor/monitor_common.h +++ b/server/modules/monitor/monitor_common.h @@ -31,27 +31,4 @@ * @endverbatim */ -#define MONITOR_RUNNING 1 -#define MONITOR_STOPPING 2 -#define MONITOR_STOPPED 3 - -#define MONITOR_INTERVAL 10000 // in milliseconds -#define MONITOR_DEFAULT_ID 1UL // unsigned long value -#define MONITOR_MAX_NUM_SLAVES 20 //number of MySQL slave servers associated to a MySQL master server - - -/** - * The linked list of servers that are being monitored by the MySQL - * Monitor module. - */ -typedef struct monitor_servers { - SERVER *server; /**< The server being monitored */ - MYSQL *con; /**< The MySQL connection */ - int mon_err_count; - unsigned int mon_prev_status; - unsigned int pending_status; /**< Pending Status flag bitmap */ - struct monitor_servers - *next; /**< The next server in the list */ -} MONITOR_SERVERS; - #endif \ No newline at end of file diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index aced27a13..19eb91b96 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -84,20 +84,15 @@ MODULE_INFO info = { static void *startMonitor(void *,void*); static void stopMonitor(void *); -static void registerServer(void *, SERVER *); -static void unregisterServer(void *, SERVER *); -static void defaultUser(void *, char *, char *); static void diagnostics(DCB *, void *); -static void setInterval(void *, size_t); static void defaultId(void *, unsigned long); -static void setNetworkTimeout(void *, int, int); static bool mon_status_changed(MONITOR_SERVERS* mon_srv); static bool mon_print_fail_status(MONITOR_SERVERS* mon_srv); static MONITOR_SERVERS *getServerByNodeId(MONITOR_SERVERS *, long); static MONITOR_SERVERS *getSlaveOfNodeId(MONITOR_SERVERS *, long); -static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *, int); +static MONITOR_SERVERS *get_replication_tree(MONITOR *, int); static void set_master_heartbeat(MYSQL_MONITOR *, MONITOR_SERVERS *); -static void set_slave_heartbeat(MYSQL_MONITOR *, MONITOR_SERVERS *); +static void set_slave_heartbeat(MONITOR *, MONITOR_SERVERS *); static int add_slave_to_master(long *, int, long); static void monitor_set_pending_status(MONITOR_SERVERS *, int); static void monitor_clear_pending_status(MONITOR_SERVERS *, int); @@ -105,12 +100,7 @@ static void monitor_clear_pending_status(MONITOR_SERVERS *, int); static MONITOR_OBJECT MyObject = { startMonitor, stopMonitor, - registerServer, - unregisterServer, - defaultUser, - diagnostics, - setInterval, - setNetworkTimeout + diagnostics }; /** @@ -157,55 +147,50 @@ GetModuleObject() * This function creates a thread to execute the actual monitoring. * * @param arg The current handle - NULL if first start + * @param opt Configuration parameters * @return A handle to use when interacting with the monitor */ static void * startMonitor(void *arg, void* opt) { -MYSQL_MONITOR *handle; -CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - if (arg) - { - handle = arg; /* Must be a restart */ - handle->shutdown = 0; - } - else - { - if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL) - return NULL; - handle->databases = NULL; - handle->shutdown = 0; - handle->defaultUser = NULL; - handle->defaultPasswd = NULL; - handle->id = config_get_gateway_id(); - handle->interval = MONITOR_INTERVAL; - handle->replicationHeartbeat = 0; - handle->detectStaleMaster = 0; - handle->master = NULL; - handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT; - handle->read_timeout=DEFAULT_READ_TIMEOUT; - handle->write_timeout=DEFAULT_WRITE_TIMEOUT; - handle->master_down_script = NULL; - spinlock_init(&handle->lock); - } + MONITOR* monitor = (MONITOR*)arg; + MYSQL_MONITOR *handle = (MYSQL_MONITOR*)monitor->handle; + CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; + if (arg) + { + handle = arg; /* Must be a restart */ + handle->shutdown = 0; + } + else + { + if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL) + return NULL; + handle->shutdown = 0; + handle->id = config_get_gateway_id(); + handle->replicationHeartbeat = 0; + handle->detectStaleMaster = 0; + handle->master = NULL; + handle->master_down_script = NULL; + spinlock_init(&handle->lock); + } - while(params) + while(params) + { + if(!strcmp(params->name,"detect_stale_master")) + handle->detectStaleMaster = config_truth_value(params->value); + else if(!strcmp(params->name,"detect_replication_lag")) + handle->replicationHeartbeat = config_truth_value(params->value); + else if(!strcmp(params->name,"master_down_script")) { - if(!strcmp(params->name,"detect_stale_master")) - handle->detectStaleMaster = config_truth_value(params->value); - else if(!strcmp(params->name,"detect_replication_lag")) - handle->replicationHeartbeat = config_truth_value(params->value); - else if(!strcmp(params->name,"master_down_script")) - { - if(handle->master_down_script) - externcmd_free(handle->master_down_script); - handle->master_down_script = externcmd_allocate(params->value); - } - params = params->next; + if(handle->master_down_script) + externcmd_free(handle->master_down_script); + handle->master_down_script = externcmd_allocate(params->value); } + params = params->next; + } - handle->tid = (THREAD)thread_start(monitorMain, handle); - return handle; + handle->tid = (THREAD)thread_start(monitorMain, handle); + return handle; } /** @@ -216,107 +201,11 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; static void stopMonitor(void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; + MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; - handle->shutdown = 1; - thread_wait((void *)handle->tid); -} - -/** - * Register a server that must be added to the monitored servers for - * a monitoring module. - * - * @param arg A handle on the running monitor module - * @param server The server to add - */ -static void -registerServer(void *arg, SERVER *server) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -MONITOR_SERVERS *ptr, *db; - - if ((db = (MONITOR_SERVERS *)malloc(sizeof(MONITOR_SERVERS))) == NULL) - return; - db->server = server; - db->con = NULL; - db->next = NULL; - db->mon_err_count = 0; - db->mon_prev_status = 0; - /* pending status is updated by get_replication_tree */ - db->pending_status = 0; - - spinlock_acquire(&handle->lock); - - if (handle->databases == NULL) - handle->databases = db; - else - { - ptr = handle->databases; - while (ptr->next != NULL) - ptr = ptr->next; - ptr->next = db; - } - spinlock_release(&handle->lock); -} - -/** - * Remove a server from those being monitored by a monitoring module - * - * @param arg A handle on the running monitor module - * @param server The server to remove - */ -static void -unregisterServer(void *arg, SERVER *server) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -MONITOR_SERVERS *ptr, *lptr; - - spinlock_acquire(&handle->lock); - if (handle->databases == NULL) - { - spinlock_release(&handle->lock); - return; - } - if (handle->databases->server == server) - { - ptr = handle->databases; - handle->databases = handle->databases->next; - free(ptr); - } - else - { - ptr = handle->databases; - while (ptr->next != NULL && ptr->next->server != server) - ptr = ptr->next; - if (ptr->next) - { - lptr = ptr->next; - ptr->next = ptr->next->next; - free(lptr); - } - } - spinlock_release(&handle->lock); -} - -/** - * Set the default username and password to use to monitor if the server does not - * override this. - * - * @param arg The handle allocated by startMonitor - * @param uname The default user name - * @param passwd The default password - */ -static void -defaultUser(void *arg, char *uname, char *passwd) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - - if (handle->defaultUser) - free(handle->defaultUser); - if (handle->defaultPasswd) - free(handle->defaultPasswd); - handle->defaultUser = strdup(uname); - handle->defaultPasswd = strdup(passwd); + handle->shutdown = 1; + thread_wait((void *)handle->tid); } /** @@ -327,45 +216,46 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; */ static void diagnostics(DCB *dcb, void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -MONITOR_SERVERS *db; -char *sep; + MONITOR* mon = (MONITOR*)arg; + MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; + MONITOR_SERVERS *db; + char *sep; - switch (handle->status) - { - case MONITOR_RUNNING: - dcb_printf(dcb, "\tMonitor running\n"); - break; - case MONITOR_STOPPING: - dcb_printf(dcb, "\tMonitor stopping\n"); - break; - case MONITOR_STOPPED: - dcb_printf(dcb, "\tMonitor stopped\n"); - break; - } + switch (handle->status) + { + case MONITOR_RUNNING: + dcb_printf(dcb, "\tMonitor running\n"); + break; + case MONITOR_STOPPING: + dcb_printf(dcb, "\tMonitor stopping\n"); + break; + case MONITOR_STOPPED: + dcb_printf(dcb, "\tMonitor stopped\n"); + break; + } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", handle->interval); - dcb_printf(dcb,"\tMaxScale MonitorId:\t%lu\n", handle->id); - dcb_printf(dcb,"\tReplication lag:\t%s\n", (handle->replicationHeartbeat == 1) ? "enabled" : "disabled"); - dcb_printf(dcb,"\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled"); - dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", handle->connect_timeout); - dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout); - dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout); - dcb_printf(dcb, "\tMonitored servers: "); - - db = handle->databases; - sep = ""; - while (db) - { - dcb_printf(dcb, - "%s%s:%d", - sep, - db->server->name, - db->server->port); - sep = ", "; - db = db->next; - } - dcb_printf(dcb, "\n"); + dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); + dcb_printf(dcb,"\tMaxScale MonitorId:\t%lu\n", handle->id); + dcb_printf(dcb,"\tReplication lag:\t%s\n", (handle->replicationHeartbeat == 1) ? "enabled" : "disabled"); + dcb_printf(dcb,"\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled"); + dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); + dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); + dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); + dcb_printf(dcb, "\tMonitored servers: "); + + db = mon->databases; + sep = ""; + while (db) + { + dcb_printf(dcb, + "%s%s:%d", + sep, + db->server->name, + db->server->port); + sep = ", "; + db = db->next; + } + dcb_printf(dcb, "\n"); } /** @@ -375,14 +265,14 @@ char *sep; * @param database The database to probe */ static void -monitorDatabase(MYSQL_MONITOR *handle, MONITOR_SERVERS *database) +monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database) { + MYSQL_MONITOR* handle = mon->handle; MYSQL_ROW row; MYSQL_RES *result; -int num_fields; int isslave = 0; -char *uname = handle->defaultUser; -char *passwd = handle->defaultPasswd; +char *uname = mon->user; +char *passwd = mon->password; unsigned long int server_version = 0; char *server_string; @@ -405,16 +295,15 @@ char *server_string; if (database->con == NULL || mysql_ping(database->con) != 0) { char *dpwd = decryptPassword(passwd); - int rc; - int connect_timeout = handle->connect_timeout; - int read_timeout = handle->read_timeout; - int write_timeout = handle->write_timeout; + int connect_timeout = mon->connect_timeout; + int read_timeout = mon->read_timeout; + int write_timeout = mon->write_timeout; database->con = mysql_init(NULL); - rc = mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout); - rc = mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); - rc = mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout); + mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout); + mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout); + mysql_options(database->con, MYSQL_OPT_WRITE_TIMEOUT, (void *)&write_timeout); if (mysql_real_connect(database->con, database->server->name, @@ -493,7 +382,6 @@ char *server_string; && (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); @@ -519,7 +407,6 @@ char *server_string; { int i = 0; long master_id = -1; - num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { /* get Slave_IO_Running and Slave_SQL_Running values*/ @@ -558,7 +445,6 @@ char *server_string; && (result = mysql_store_result(database->con)) != NULL) { long master_id = -1; - num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { /* get Slave_IO_Running and Slave_SQL_Running values*/ @@ -615,7 +501,8 @@ char *server_string; static void monitorMain(void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = (MONITOR*) arg; +MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; MONITOR_SERVERS *ptr; int replication_heartbeat = handle->replicationHeartbeat; int detect_stale_master = handle->detectStaleMaster; @@ -652,7 +539,7 @@ int log_no_master = 1; * round. */ if (nrounds != 0 && - ((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >= + ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= MON_BASE_INTERVAL_MS) { nrounds += 1; @@ -663,7 +550,7 @@ int log_no_master = 1; num_servers = 0; /* start from the first server in the list */ - ptr = handle->databases; + ptr = mon->databases; while (ptr) { @@ -671,7 +558,7 @@ int log_no_master = 1; ptr->pending_status = ptr->server->status; /* monitor current node */ - monitorDatabase(handle, ptr); + monitorDatabase(mon, ptr); /* reset the slave list of current node */ if (ptr->server->slaves) { @@ -753,7 +640,7 @@ int log_no_master = 1; ptr = ptr->next; } - ptr = handle->databases; + ptr = mon->databases; /* if only one server is configured, that's is Master */ if (num_servers == 1) { if (SERVER_IS_RUNNING(ptr->server)) { @@ -770,12 +657,12 @@ int log_no_master = 1; } } else { /* Compute the replication tree */ - root_master = get_replication_tree(handle, num_servers); + root_master = get_replication_tree(mon, num_servers); } /* Update server status from monitor pending status on that server*/ - ptr = handle->databases; + ptr = mon->databases; while (ptr) { if (! SERVER_IN_MAINT(ptr->server)) { @@ -852,7 +739,7 @@ int log_no_master = 1; SERVER_IS_RELAY_SERVER(root_master->server))) { set_master_heartbeat(handle, root_master); - ptr = handle->databases; + ptr = mon->databases; while (ptr) { if( (! SERVER_IN_MAINT(ptr->server)) && SERVER_IS_RUNNING(ptr->server)) @@ -861,7 +748,7 @@ int log_no_master = 1; (SERVER_IS_SLAVE(ptr->server) || SERVER_IS_RELAY_SERVER(ptr->server))) { - set_slave_heartbeat(handle, ptr); + set_slave_heartbeat(mon, ptr); } } ptr = ptr->next; @@ -883,19 +770,6 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; memcpy(&handle->id, &id, sizeof(unsigned long)); } -/** - * Set the monitor sampling interval. - * - * @param arg The handle allocated by startMonitor - * @param interval The interval to set in monitor struct, in milliseconds - */ -static void -setInterval(void *arg, size_t interval) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - memcpy(&handle->interval, &interval, sizeof(unsigned long)); -} - /** * Enable/Disable the MySQL Replication hearbeat, detecting slave lag behind master. * @@ -957,9 +831,6 @@ static bool mon_print_fail_status( { bool succp; int errcount = mon_srv->mon_err_count; - uint8_t modval; - - modval = 1<<(MIN(errcount/10, 7)); if (SERVER_IS_DOWN(mon_srv->server) && errcount == 0) { @@ -1133,13 +1004,13 @@ static void set_master_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *databas * @param handle The monitor handle * @param database The number database server */ -static void set_slave_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database) { +static void set_slave_heartbeat(MONITOR* mon, MONITOR_SERVERS *database) { + MYSQL_MONITOR *handle = (MYSQL_MONITOR*)mon->handle; unsigned long id = handle->id; time_t heartbeat; char select_heartbeat_query[256] = ""; MYSQL_ROW row; MYSQL_RES *result; - int num_fields; if (handle->master == NULL) { LOGIF(LE, (skygw_log_write_flush( @@ -1159,7 +1030,6 @@ static void set_slave_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database if (handle->master !=NULL && (mysql_query(database->con, select_heartbeat_query) == 0 && (result = mysql_store_result(database->con)) != NULL)) { int rows_found = 0; - num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { int rlag = -1; @@ -1184,7 +1054,7 @@ static void set_slave_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database if (rlag >= 0) { /* store rlag only if greater than monitor sampling interval */ - database->server->rlag = (rlag > (handle->interval / 1000)) ? rlag : 0; + database->server->rlag = (rlag > (mon->interval / 1000)) ? rlag : 0; } else { database->server->rlag = -1; } @@ -1238,7 +1108,8 @@ static void set_slave_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database * @return The server at root level with SERVER_MASTER bit */ -static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_servers) { +static MONITOR_SERVERS *get_replication_tree(MONITOR *mon, int num_servers) { + MYSQL_MONITOR* handle = (MYSQL_MONITOR*)mon->handle; MONITOR_SERVERS *ptr; MONITOR_SERVERS *backend; SERVER *current; @@ -1246,7 +1117,7 @@ static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_serv long node_id; int root_level; - ptr = handle->databases; + ptr = mon->databases; root_level = num_servers; while (ptr) @@ -1265,7 +1136,7 @@ static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_serv node_id = current->master_id; if (node_id < 1) { MONITOR_SERVERS *find_slave; - find_slave = getSlaveOfNodeId(handle->databases, current->node_id); + find_slave = getSlaveOfNodeId(mon->databases, current->node_id); if (find_slave == NULL) { current->depth = -1; @@ -1285,7 +1156,7 @@ static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_serv root_level = current->depth; handle->master = ptr; } - backend = getServerByNodeId(handle->databases, node_id); + backend = getServerByNodeId(mon->databases, node_id); if (backend) { node_id = backend->server->master_id; @@ -1301,7 +1172,7 @@ static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_serv MONITOR_SERVERS *master; current->depth = depth; - master = getServerByNodeId(handle->databases, current->master_id); + master = getServerByNodeId(mon->databases, current->master_id); if (master && master->server && master->server->node_id > 0) { add_slave_to_master(master->server->slaves, MONITOR_MAX_NUM_SLAVES, current->node_id); master->server->depth = current->depth -1; @@ -1383,65 +1254,3 @@ monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit) { ptr->pending_status &= ~bit; } - -/** - * Set the default id to use in the monitor. - * - * @param arg The handle allocated by startMonitor - * @param type The connect timeout type - * @param value The timeout value to set - */ -static void -setNetworkTimeout(void *arg, int type, int value) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -int max_timeout = (int)(handle->interval/1000); -int new_timeout = max_timeout -1; - - if (new_timeout <= 0) - new_timeout = DEFAULT_CONNECT_TIMEOUT; - - switch(type) { - case MONITOR_CONNECT_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->connect_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->connect_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Connect Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - - case MONITOR_READ_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->read_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->read_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Read Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - - case MONITOR_WRITE_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->write_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->write_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Write Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - default: - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Monitor setNetworkTimeout received an unsupported action type %i", type))); - break; - } -} - diff --git a/server/modules/monitor/mysqlmon.h b/server/modules/monitor/mysqlmon.h index 93ba2093e..ff2bf0d3e 100644 --- a/server/modules/monitor/mysqlmon.h +++ b/server/modules/monitor/mysqlmon.h @@ -49,9 +49,6 @@ typedef struct { pthread_t tid; /**< id of monitor thread */ int shutdown; /**< Flag to shutdown the monitor thread */ int status; /**< Monitor status */ - char *defaultUser; /**< Default username for monitoring */ - char *defaultPasswd; /**< Default password for monitoring */ - unsigned long interval; /**< Monitor sampling interval */ unsigned long id; /**< Monitor ID */ int replicationHeartbeat; /**< Monitor flag for MySQL replication heartbeat */ int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */ @@ -59,15 +56,7 @@ typedef struct { int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ - MONITOR_SERVERS *databases; /**< Linked list of servers to monitor */ - int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */ - int read_timeout; /**< Timeout in seconds to read from the server. - * There are retries and the total effective timeout value is three times the option value. - */ - int write_timeout; /**< Timeout in seconds for each attempt to write to the server. - * There are retries and the total effective timeout value is two times the option value. - */ - EXTERNCMD* master_down_script; + EXTERNCMD* master_down_script; } MYSQL_MONITOR; #endif diff --git a/server/modules/monitor/ndbcluster_mon.c b/server/modules/monitor/ndbcluster_mon.c index 8f7d00964..ca9ff4210 100644 --- a/server/modules/monitor/ndbcluster_mon.c +++ b/server/modules/monitor/ndbcluster_mon.c @@ -50,7 +50,7 @@ extern __thread log_info_t tls_log_info; static void monitorMain(void *); -static char *version_str = "V1.1.0"; +static char *version_str = "V2.1.0"; MODULE_INFO info = { MODULE_API_MONITOR, @@ -61,22 +61,12 @@ MODULE_INFO info = { static void *startMonitor(void *,void*); static void stopMonitor(void *); -static void registerServer(void *, SERVER *); -static void unregisterServer(void *, SERVER *); -static void defaultUsers(void *, char *, char *); static void diagnostics(DCB *, void *); -static void setInterval(void *, size_t); -static void setNetworkTimeout(void *arg, int type, int value); static MONITOR_OBJECT MyObject = { startMonitor, - stopMonitor, - registerServer, - unregisterServer, - defaultUsers, - diagnostics, - setInterval, - setNetworkTimeout + stopMonitor, + diagnostics }; /** @@ -127,26 +117,19 @@ GetModuleObject() static void * startMonitor(void *arg,void* opt) { -MYSQL_MONITOR *handle; + MONITOR* mon = (MONITOR*)arg; +MYSQL_MONITOR *handle = mon->handle; CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - if (arg != NULL) + if (handle != NULL) { - handle = (MYSQL_MONITOR *)arg; handle->shutdown = 0; } else { if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL) return NULL; - handle->databases = NULL; handle->shutdown = 0; - handle->defaultUser = NULL; - handle->defaultPasswd = NULL; handle->id = MONITOR_DEFAULT_ID; - handle->interval = MONITOR_INTERVAL; - handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT; - handle->read_timeout=DEFAULT_READ_TIMEOUT; - handle->write_timeout=DEFAULT_WRITE_TIMEOUT; spinlock_init(&handle->lock); } @@ -162,82 +145,13 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; static void stopMonitor(void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = (MONITOR*)arg; +MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; handle->shutdown = 1; thread_wait((void *)handle->tid); } -/** - * Register a server that must be added to the monitored servers for - * a monitoring module. - * - * @param arg A handle on the running monitor module - * @param server The server to add - */ -static void -registerServer(void *arg, SERVER *server) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -MONITOR_SERVERS *ptr, *db; - - if ((db = (MONITOR_SERVERS *)malloc(sizeof(MONITOR_SERVERS))) == NULL) - return; - db->server = server; - db->con = NULL; - db->next = NULL; - spinlock_acquire(&handle->lock); - if (handle->databases == NULL) - handle->databases = db; - else - { - ptr = handle->databases; - while (ptr->next != NULL) - ptr = ptr->next; - ptr->next = db; - } - spinlock_release(&handle->lock); -} - -/** - * Remove a server from those being monitored by a monitoring module - * - * @param arg A handle on the running monitor module - * @param server The server to remove - */ -static void -unregisterServer(void *arg, SERVER *server) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -MONITOR_SERVERS *ptr, *lptr; - - spinlock_acquire(&handle->lock); - if (handle->databases == NULL) - { - spinlock_release(&handle->lock); - return; - } - if (handle->databases->server == server) - { - ptr = handle->databases; - handle->databases = handle->databases->next; - free(ptr); - } - else - { - ptr = handle->databases; - while (ptr->next != NULL && ptr->next->server != server) - ptr = ptr->next; - if (ptr->next) - { - lptr = ptr->next; - ptr->next = ptr->next->next; - free(lptr); - } - } - spinlock_release(&handle->lock); -} - /** * Diagnostic interface * @@ -247,7 +161,8 @@ MONITOR_SERVERS *ptr, *lptr; static void diagnostics(DCB *dcb, void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = arg; +MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; MONITOR_SERVERS *db; char *sep; @@ -264,13 +179,13 @@ char *sep; break; } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", handle->interval); - dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", handle->connect_timeout); - dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout); - dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout); + dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); + dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); + dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); + dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); dcb_printf(dcb, "\tMonitored servers: "); - db = handle->databases; + db = mon->databases; sep = ""; while (db) { @@ -281,35 +196,15 @@ char *sep; dcb_printf(dcb, "\n"); } -/** - * Set the default username and password to use to monitor if the server does not - * override this. - * - * @param arg The handle allocated by startMonitor - * @param uname The default user name - * @param passwd The default password - */ -static void -defaultUsers(void *arg, char *uname, char *passwd) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - - if (handle->defaultUser) - free(handle->defaultUser); - if (handle->defaultPasswd) - free(handle->defaultPasswd); - handle->defaultUser = strdup(uname); - handle->defaultPasswd = strdup(passwd); -} - /** * Monitor an individual server * * @param database The database to probe */ static void -monitorDatabase(MONITOR_SERVERS *database, char *defaultUser, char *defaultPasswd, MYSQL_MONITOR *handle) +monitorDatabase(MONITOR_SERVERS *database, char *defaultUser, char *defaultPasswd, MONITOR *mon) { + MYSQL_MONITOR* handle = mon->handle; MYSQL_ROW row; MYSQL_RES *result; int num_fields; @@ -334,9 +229,9 @@ char *server_string; { char *dpwd = decryptPassword(passwd); int rc; - int connect_timeout = handle->connect_timeout; - int read_timeout = handle->read_timeout; - int write_timeout = handle->write_timeout; + int connect_timeout = mon->connect_timeout; + int read_timeout = mon->read_timeout; + int write_timeout = mon->write_timeout; database->con = mysql_init(NULL); @@ -433,7 +328,8 @@ char *server_string; static void monitorMain(void *arg) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; + MONITOR* mon = arg; +MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; MONITOR_SERVERS *ptr; long master_id; size_t nrounds = 0; @@ -467,7 +363,7 @@ size_t nrounds = 0; * round. */ if (nrounds != 0 && - ((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >= + ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= MON_BASE_INTERVAL_MS) { nrounds += 1; @@ -475,12 +371,12 @@ size_t nrounds = 0; } nrounds += 1; master_id = -1; - ptr = handle->databases; + ptr = mon->databases; while (ptr) { unsigned int prev_status = ptr->server->status; - monitorDatabase(ptr, handle->defaultUser, handle->defaultPasswd,handle); + monitorDatabase(ptr, mon->user, mon->password,mon); if (ptr->server->status != prev_status || SERVER_IS_DOWN(ptr->server)) @@ -497,78 +393,3 @@ size_t nrounds = 0; } } } - -/** - * Set the monitor sampling interval. - * - * @param arg The handle allocated by startMonitor - * @param interval The interval to set in monitor struct, in milliseconds - */ -static void -setInterval(void *arg, size_t interval) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - memcpy(&handle->interval, &interval, sizeof(unsigned long)); -} - -/** - * Set the timeouts to use in the monitor. - * - * @param arg The handle allocated by startMonitor - * @param type The connect timeout type - * @param value The timeout value to set - */ -static void -setNetworkTimeout(void *arg, int type, int value) -{ -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; -int max_timeout = (int)(handle->interval/1000); -int new_timeout = max_timeout -1; - - if (new_timeout <= 0) - new_timeout = DEFAULT_CONNECT_TIMEOUT; - - switch(type) { - case MONITOR_CONNECT_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->connect_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->connect_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Connect Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - - case MONITOR_READ_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->read_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->read_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Read Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - - case MONITOR_WRITE_TIMEOUT: - if (value < max_timeout) { - memcpy(&handle->write_timeout, &value, sizeof(int)); - } else { - memcpy(&handle->write_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Write Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); - } - break; - default: - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Monitor setNetworkTimeout received an unsupported action type %i", type))); - break; - } -} -