Moved common monitor functionality to the MONITOR type
Common variables, like databases, timeouts and interval, and functionality was moved to the MONITOR type. This reduces the redundant functionality of the monitor API's functions like registerServer and setInterval.
This commit is contained in:
@ -80,7 +80,13 @@ MONITOR *mon;
|
|||||||
}
|
}
|
||||||
|
|
||||||
mon->handle = NULL;
|
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);
|
spinlock_acquire(&monLock);
|
||||||
mon->next = allMonitors;
|
mon->next = allMonitors;
|
||||||
allMonitors = mon;
|
allMonitors = mon;
|
||||||
@ -100,7 +106,7 @@ monitor_free(MONITOR *mon)
|
|||||||
{
|
{
|
||||||
MONITOR *ptr;
|
MONITOR *ptr;
|
||||||
|
|
||||||
mon->module->stopMonitor(mon->handle);
|
mon->module->stopMonitor(mon);
|
||||||
mon->state = MONITOR_STATE_FREED;
|
mon->state = MONITOR_STATE_FREED;
|
||||||
spinlock_acquire(&monLock);
|
spinlock_acquire(&monLock);
|
||||||
if (allMonitors == mon)
|
if (allMonitors == mon)
|
||||||
@ -127,7 +133,7 @@ MONITOR *ptr;
|
|||||||
void
|
void
|
||||||
monitorStart(MONITOR *monitor, void* params)
|
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;
|
monitor->state = MONITOR_STATE_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +148,7 @@ monitorStop(MONITOR *monitor)
|
|||||||
if(monitor->state != MONITOR_STATE_STOPPED)
|
if(monitor->state != MONITOR_STATE_STOPPED)
|
||||||
{
|
{
|
||||||
monitor->state = MONITOR_STATE_STOPPING;
|
monitor->state = MONITOR_STATE_STOPPING;
|
||||||
monitor->module->stopMonitor(monitor->handle);
|
monitor->module->stopMonitor(monitor);
|
||||||
monitor->state = MONITOR_STATE_STOPPED;
|
monitor->state = MONITOR_STATE_STOPPED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,7 +181,30 @@ MONITOR *ptr;
|
|||||||
void
|
void
|
||||||
monitorAddServer(MONITOR *mon, SERVER *server)
|
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
|
void
|
||||||
monitorAddUser(MONITOR *mon, char *user, char *passwd)
|
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
|
void
|
||||||
monitorSetInterval (MONITOR *mon, unsigned long interval)
|
monitorSetInterval (MONITOR *mon, unsigned long interval)
|
||||||
{
|
{
|
||||||
if (mon->module->setInterval != NULL) {
|
|
||||||
mon->interval = interval;
|
mon->interval = interval;
|
||||||
mon->module->setInterval(mon->handle, interval);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,8 +331,54 @@ monitorSetInterval (MONITOR *mon, unsigned long interval)
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
monitorSetNetworkTimeout(MONITOR *mon, int type, int value) {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright MariaDB Corporation Ab 2013-2014
|
* Copyright MariaDB Corporation Ab 2013-2014
|
||||||
*/
|
*/
|
||||||
|
#include <mysql.h>
|
||||||
#include <server.h>
|
#include <server.h>
|
||||||
#include <dcb.h>
|
#include <dcb.h>
|
||||||
#include <resultset.h>
|
#include <resultset.h>
|
||||||
@ -69,19 +70,14 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
void *(*startMonitor)(void *, void*);
|
void *(*startMonitor)(void *, void*);
|
||||||
void (*stopMonitor)(void *);
|
void (*stopMonitor)(void *);
|
||||||
void (*registerServer)(void *, SERVER *);
|
|
||||||
void (*unregisterServer)(void *, SERVER *);
|
|
||||||
void (*defaultUser)(void *, char *, char *);
|
|
||||||
void (*diagnostics)(DCB *, void *);
|
void (*diagnostics)(DCB *, void *);
|
||||||
void (*setInterval)(void *, size_t);
|
|
||||||
void (*setNetworkTimeout)(void *, int, int);
|
|
||||||
} MONITOR_OBJECT;
|
} MONITOR_OBJECT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The monitor API version number. Any change to the monitor module API
|
* The monitor API version number. Any change to the monitor module API
|
||||||
* must change these versions usign the rules defined in modinfo.h
|
* 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 */
|
/** Monitor's poll frequency */
|
||||||
#define MON_BASE_INTERVAL_MS 100
|
#define MON_BASE_INTERVAL_MS 100
|
||||||
@ -112,12 +108,46 @@ typedef enum
|
|||||||
#define DEFAULT_READ_TIMEOUT 1
|
#define DEFAULT_READ_TIMEOUT 1
|
||||||
#define DEFAULT_WRITE_TIMEOUT 2
|
#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.
|
* Representation of the running monitor.
|
||||||
*/
|
*/
|
||||||
typedef struct monitor {
|
typedef struct monitor {
|
||||||
char *name; /**< The name of the monitor module */
|
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 */
|
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" */
|
MONITOR_OBJECT *module; /**< The "monitor object" */
|
||||||
void *handle; /**< Handle returned from startMonitor */
|
void *handle; /**< Handle returned from startMonitor */
|
||||||
size_t interval; /**< The monitor interval */
|
size_t interval; /**< The monitor interval */
|
||||||
|
@ -60,7 +60,7 @@ extern __thread log_info_t tls_log_info;
|
|||||||
|
|
||||||
static void monitorMain(void *);
|
static void monitorMain(void *);
|
||||||
|
|
||||||
static char *version_str = "V1.5.0";
|
static char *version_str = "V2.0.0";
|
||||||
|
|
||||||
MODULE_INFO info = {
|
MODULE_INFO info = {
|
||||||
MODULE_API_MONITOR,
|
MODULE_API_MONITOR,
|
||||||
@ -86,12 +86,7 @@ static bool mon_print_fail_status(MONITOR_SERVERS* mon_srv);
|
|||||||
static MONITOR_OBJECT MyObject = {
|
static MONITOR_OBJECT MyObject = {
|
||||||
startMonitor,
|
startMonitor,
|
||||||
stopMonitor,
|
stopMonitor,
|
||||||
registerServer,
|
diagnostics
|
||||||
unregisterServer,
|
|
||||||
defaultUsers,
|
|
||||||
diagnostics,
|
|
||||||
setInterval,
|
|
||||||
setNetworkTimeout
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,30 +137,23 @@ GetModuleObject()
|
|||||||
static void *
|
static void *
|
||||||
startMonitor(void *arg,void* opt)
|
startMonitor(void *arg,void* opt)
|
||||||
{
|
{
|
||||||
GALERA_MONITOR *handle;
|
MONITOR* mon = arg;
|
||||||
|
GALERA_MONITOR *handle = mon->handle;
|
||||||
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
||||||
if (arg != NULL)
|
if (handle != NULL)
|
||||||
{
|
{
|
||||||
handle = (GALERA_MONITOR *)arg;
|
|
||||||
handle->shutdown = 0;
|
handle->shutdown = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((handle = (GALERA_MONITOR *)malloc(sizeof(GALERA_MONITOR))) == NULL)
|
if ((handle = (GALERA_MONITOR *)malloc(sizeof(GALERA_MONITOR))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
handle->databases = NULL;
|
|
||||||
handle->shutdown = 0;
|
handle->shutdown = 0;
|
||||||
handle->defaultUser = NULL;
|
|
||||||
handle->defaultPasswd = NULL;
|
|
||||||
handle->id = MONITOR_DEFAULT_ID;
|
handle->id = MONITOR_DEFAULT_ID;
|
||||||
handle->interval = MONITOR_INTERVAL;
|
|
||||||
handle->disableMasterFailback = 0;
|
handle->disableMasterFailback = 0;
|
||||||
handle->availableWhenDonor = 0;
|
handle->availableWhenDonor = 0;
|
||||||
handle->disableMasterRoleSetting = 0;
|
handle->disableMasterRoleSetting = 0;
|
||||||
handle->master = NULL;
|
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;
|
handle->master_down_script = NULL;
|
||||||
spinlock_init(&handle->lock);
|
spinlock_init(&handle->lock);
|
||||||
}
|
}
|
||||||
@ -200,82 +188,13 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
|||||||
static void
|
static void
|
||||||
stopMonitor(void *arg)
|
stopMonitor(void *arg)
|
||||||
{
|
{
|
||||||
GALERA_MONITOR *handle = (GALERA_MONITOR *)arg;
|
MONITOR* mon = (MONITOR*)arg;
|
||||||
|
GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle;
|
||||||
|
|
||||||
handle->shutdown = 1;
|
handle->shutdown = 1;
|
||||||
thread_wait((void *)handle->tid);
|
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
|
* Diagnostic interface
|
||||||
*
|
*
|
||||||
@ -285,7 +204,8 @@ MONITOR_SERVERS *ptr, *lptr;
|
|||||||
static void
|
static void
|
||||||
diagnostics(DCB *dcb, void *arg)
|
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;
|
MONITOR_SERVERS *db;
|
||||||
char *sep;
|
char *sep;
|
||||||
|
|
||||||
@ -302,16 +222,16 @@ char *sep;
|
|||||||
break;
|
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,"\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,"\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,"\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,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout);
|
||||||
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout);
|
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout);
|
||||||
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout);
|
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout);
|
||||||
dcb_printf(dcb, "\tMonitored servers: ");
|
dcb_printf(dcb, "\tMonitored servers: ");
|
||||||
|
|
||||||
db = handle->databases;
|
db = mon->databases;
|
||||||
sep = "";
|
sep = "";
|
||||||
while (db)
|
while (db)
|
||||||
{
|
{
|
||||||
@ -322,27 +242,6 @@ char *sep;
|
|||||||
dcb_printf(dcb, "\n");
|
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
|
* Monitor an individual server
|
||||||
*
|
*
|
||||||
@ -350,14 +249,14 @@ GALERA_MONITOR *handle = (GALERA_MONITOR *)arg;
|
|||||||
* @param database The database to probe
|
* @param database The database to probe
|
||||||
*/
|
*/
|
||||||
static void
|
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_ROW row;
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
int num_fields;
|
|
||||||
int isjoined = 0;
|
int isjoined = 0;
|
||||||
char *uname = handle->defaultUser;
|
char *uname = mon->user;
|
||||||
char *passwd = handle->defaultPasswd;
|
char *passwd = mon->password;
|
||||||
unsigned long int server_version = 0;
|
unsigned long int server_version = 0;
|
||||||
char *server_string;
|
char *server_string;
|
||||||
|
|
||||||
@ -379,16 +278,15 @@ char *server_string;
|
|||||||
if (database->con == NULL || mysql_ping(database->con) != 0)
|
if (database->con == NULL || mysql_ping(database->con) != 0)
|
||||||
{
|
{
|
||||||
char *dpwd = decryptPassword(passwd);
|
char *dpwd = decryptPassword(passwd);
|
||||||
int rc;
|
int connect_timeout = mon->connect_timeout;
|
||||||
int connect_timeout = handle->connect_timeout;
|
int read_timeout = mon->read_timeout;
|
||||||
int read_timeout = handle->read_timeout;
|
int write_timeout = mon->write_timeout;
|
||||||
int write_timeout = handle->write_timeout;
|
|
||||||
|
|
||||||
database->con = mysql_init(NULL);
|
database->con = mysql_init(NULL);
|
||||||
|
|
||||||
rc = mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout);
|
mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout);
|
||||||
rc = mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout);
|
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_WRITE_TIMEOUT, (void *)&write_timeout);
|
||||||
|
|
||||||
if (mysql_real_connect(database->con, database->server->name,
|
if (mysql_real_connect(database->con, database->server->name,
|
||||||
uname, dpwd, NULL, database->server->port, NULL, 0) == NULL)
|
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 */
|
/* If we get this far then we have a working connection */
|
||||||
server_set_status(database->server, SERVER_RUNNING);
|
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 */
|
/* get server version string */
|
||||||
server_string = (char *)mysql_get_server_info(database->con);
|
server_string = (char *)mysql_get_server_info(database->con);
|
||||||
if (server_string) {
|
if (server_string) {
|
||||||
@ -448,7 +343,6 @@ char *server_string;
|
|||||||
if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_state'") == 0
|
if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_state'") == 0
|
||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
if (strcmp(row[1], "4") == 0)
|
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
|
if (mysql_query(database->con, "SHOW VARIABLES LIKE 'wsrep_sst_method'") == 0
|
||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
if (strncmp(row[1], "xtrabackup", 10) == 0)
|
if (strncmp(row[1], "xtrabackup", 10) == 0)
|
||||||
@ -476,7 +369,6 @@ char *server_string;
|
|||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
long local_index = -1;
|
long local_index = -1;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
local_index = strtol(row[1], NULL, 10);
|
local_index = strtol(row[1], NULL, 10);
|
||||||
@ -504,7 +396,8 @@ char *server_string;
|
|||||||
static void
|
static void
|
||||||
monitorMain(void *arg)
|
monitorMain(void *arg)
|
||||||
{
|
{
|
||||||
GALERA_MONITOR *handle = (GALERA_MONITOR *)arg;
|
MONITOR* mon = (MONITOR*)arg;
|
||||||
|
GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle;
|
||||||
MONITOR_SERVERS *ptr;
|
MONITOR_SERVERS *ptr;
|
||||||
size_t nrounds = 0;
|
size_t nrounds = 0;
|
||||||
MONITOR_SERVERS *candidate_master = NULL;
|
MONITOR_SERVERS *candidate_master = NULL;
|
||||||
@ -540,7 +433,7 @@ int log_no_members = 1;
|
|||||||
* round.
|
* 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;
|
nrounds += 1;
|
||||||
continue;
|
continue;
|
||||||
@ -551,11 +444,11 @@ int log_no_members = 1;
|
|||||||
/* reset cluster members counter */
|
/* reset cluster members counter */
|
||||||
is_cluster=0;
|
is_cluster=0;
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
|
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
monitorDatabase(handle, ptr);
|
monitorDatabase(mon, ptr);
|
||||||
|
|
||||||
if(ptr->mon_prev_status & SERVER_MASTER &&
|
if(ptr->mon_prev_status & SERVER_MASTER &&
|
||||||
SERVER_IS_DOWN(ptr->server))
|
SERVER_IS_DOWN(ptr->server))
|
||||||
@ -619,7 +512,7 @@ int log_no_members = 1;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* get the candidate master, following MIN(node_id) rule */
|
/* 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 */
|
/* Select the master, based on master_stickiness */
|
||||||
if (1 == handle->disableMasterRoleSetting) {
|
if (1 == handle->disableMasterRoleSetting) {
|
||||||
@ -629,7 +522,7 @@ int log_no_members = 1;
|
|||||||
handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness);
|
handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
|
|
||||||
while (ptr) {
|
while (ptr) {
|
||||||
if (!SERVER_IS_JOINED(ptr->server) || SERVER_IN_MAINT(ptr->server)) {
|
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
|
* get candidate master from all nodes
|
||||||
*
|
*
|
||||||
@ -796,67 +676,6 @@ GALERA_MONITOR *handle = (GALERA_MONITOR *)arg;
|
|||||||
memcpy(&handle->availableWhenDonor, &disable, sizeof(int));
|
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
|
* Check if current monitored server status has changed
|
||||||
*
|
*
|
||||||
@ -890,9 +709,6 @@ static bool mon_print_fail_status(
|
|||||||
{
|
{
|
||||||
bool succp;
|
bool succp;
|
||||||
int errcount = mon_srv->mon_err_count;
|
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)
|
if (SERVER_IS_DOWN(mon_srv->server) && errcount == 0)
|
||||||
{
|
{
|
||||||
|
@ -42,23 +42,12 @@ typedef struct {
|
|||||||
pthread_t tid; /**< id of monitor thread */
|
pthread_t tid; /**< id of monitor thread */
|
||||||
int shutdown; /**< Flag to shutdown the monitor thread */
|
int shutdown; /**< Flag to shutdown the monitor thread */
|
||||||
int status; /**< Monitor status */
|
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 */
|
unsigned long id; /**< Monitor ID */
|
||||||
int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */
|
int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */
|
||||||
int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */
|
int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */
|
||||||
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
|
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
|
||||||
int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
|
int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
|
||||||
MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */
|
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;
|
} GALERA_MONITOR;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ extern __thread log_info_t tls_log_info;
|
|||||||
|
|
||||||
static void monitorMain(void *);
|
static void monitorMain(void *);
|
||||||
|
|
||||||
static char *version_str = "V1.0.1";
|
static char *version_str = "V1.1.1";
|
||||||
|
|
||||||
MODULE_INFO info = {
|
MODULE_INFO info = {
|
||||||
MODULE_API_MONITOR,
|
MODULE_API_MONITOR,
|
||||||
@ -60,26 +60,18 @@ MODULE_INFO info = {
|
|||||||
|
|
||||||
static void *startMonitor(void *,void*);
|
static void *startMonitor(void *,void*);
|
||||||
static void stopMonitor(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 diagnostics(DCB *, void *);
|
||||||
static void setInterval(void *, size_t);
|
|
||||||
static void detectStaleMaster(void *, int);
|
static void detectStaleMaster(void *, int);
|
||||||
static bool mon_status_changed(MONITOR_SERVERS* mon_srv);
|
static bool mon_status_changed(MONITOR_SERVERS* mon_srv);
|
||||||
static bool mon_print_fail_status(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_set_pending_status(MONITOR_SERVERS *, int);
|
||||||
static void monitor_clear_pending_status(MONITOR_SERVERS *, int);
|
static void monitor_clear_pending_status(MONITOR_SERVERS *, int);
|
||||||
|
|
||||||
static MONITOR_OBJECT MyObject = {
|
static MONITOR_OBJECT MyObject = {
|
||||||
startMonitor,
|
startMonitor,
|
||||||
stopMonitor,
|
stopMonitor,
|
||||||
registerServer,
|
diagnostics
|
||||||
unregisterServer,
|
|
||||||
defaultUser,
|
|
||||||
diagnostics,
|
|
||||||
setInterval
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,23 +123,19 @@ GetModuleObject()
|
|||||||
static void *
|
static void *
|
||||||
startMonitor(void *arg,void* opt)
|
startMonitor(void *arg,void* opt)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle;
|
MONITOR* mon = (MONITOR*)arg;
|
||||||
|
MYSQL_MONITOR *handle = mon->handle;
|
||||||
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
||||||
if (arg)
|
if (handle)
|
||||||
{
|
{
|
||||||
handle = arg; /* Must be a restart */
|
|
||||||
handle->shutdown = 0;
|
handle->shutdown = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL)
|
if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
handle->databases = NULL;
|
|
||||||
handle->shutdown = 0;
|
handle->shutdown = 0;
|
||||||
handle->defaultUser = NULL;
|
|
||||||
handle->defaultPasswd = NULL;
|
|
||||||
handle->id = MONITOR_DEFAULT_ID;
|
handle->id = MONITOR_DEFAULT_ID;
|
||||||
handle->interval = MONITOR_INTERVAL;
|
|
||||||
handle->replicationHeartbeat = 0;
|
handle->replicationHeartbeat = 0;
|
||||||
handle->detectStaleMaster = 0;
|
handle->detectStaleMaster = 0;
|
||||||
handle->master = NULL;
|
handle->master = NULL;
|
||||||
@ -179,103 +167,6 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
|||||||
thread_wait((void *)handle->tid);
|
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
|
* Daignostic interface
|
||||||
*
|
*
|
||||||
@ -284,7 +175,8 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
|||||||
*/
|
*/
|
||||||
static void diagnostics(DCB *dcb, void *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;
|
MONITOR_SERVERS *db;
|
||||||
char *sep;
|
char *sep;
|
||||||
|
|
||||||
@ -301,11 +193,11 @@ char *sep;
|
|||||||
break;
|
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,"\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled");
|
||||||
dcb_printf(dcb, "\tMonitored servers: ");
|
dcb_printf(dcb, "\tMonitored servers: ");
|
||||||
|
|
||||||
db = handle->databases;
|
db = mon->databases;
|
||||||
sep = "";
|
sep = "";
|
||||||
while (db)
|
while (db)
|
||||||
{
|
{
|
||||||
@ -327,15 +219,16 @@ char *sep;
|
|||||||
* @param database The database to probe
|
* @param database The database to probe
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
monitorDatabase(MYSQL_MONITOR *handle, MONITOR_SERVERS *database)
|
monitorDatabase(MONITOR* mon, MONITOR_SERVERS *database)
|
||||||
{
|
{
|
||||||
|
MYSQL_MONITOR *handle = mon->handle;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
int num_fields;
|
int num_fields;
|
||||||
int isslave = 0;
|
int isslave = 0;
|
||||||
int ismaster = 0;
|
int ismaster = 0;
|
||||||
char *uname = handle->defaultUser;
|
char *uname = mon->user;
|
||||||
char *passwd = handle->defaultPasswd;
|
char *passwd = mon->password;
|
||||||
unsigned long int server_version = 0;
|
unsigned long int server_version = 0;
|
||||||
char *server_string;
|
char *server_string;
|
||||||
|
|
||||||
@ -358,12 +251,11 @@ char *server_string;
|
|||||||
if (database->con == NULL || mysql_ping(database->con) != 0)
|
if (database->con == NULL || mysql_ping(database->con) != 0)
|
||||||
{
|
{
|
||||||
char *dpwd = decryptPassword(passwd);
|
char *dpwd = decryptPassword(passwd);
|
||||||
int rc;
|
|
||||||
int read_timeout = 1;
|
int read_timeout = 1;
|
||||||
|
|
||||||
database->con = mysql_init(NULL);
|
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,
|
if (mysql_real_connect(database->con,
|
||||||
database->server->name,
|
database->server->name,
|
||||||
@ -437,7 +329,7 @@ char *server_string;
|
|||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
long server_id = -1;
|
long server_id = -1;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
server_id = strtol(row[0], NULL, 10);
|
server_id = strtol(row[0], NULL, 10);
|
||||||
@ -463,7 +355,7 @@ char *server_string;
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
long master_id = -1;
|
long master_id = -1;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
||||||
@ -502,7 +394,7 @@ char *server_string;
|
|||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
long master_id = -1;
|
long master_id = -1;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
/* 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
|
if (mysql_query(database->con, "SHOW GLOBAL VARIABLES LIKE 'read_only'") == 0
|
||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
if (strncasecmp(row[1], "OFF", 3) == 0) {
|
if (strncasecmp(row[1], "OFF", 3) == 0) {
|
||||||
@ -584,7 +476,8 @@ char *server_string;
|
|||||||
static void
|
static void
|
||||||
monitorMain(void *arg)
|
monitorMain(void *arg)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
MONITOR* mon = (MONITOR*)arg;
|
||||||
|
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle;
|
||||||
MONITOR_SERVERS *ptr;
|
MONITOR_SERVERS *ptr;
|
||||||
int detect_stale_master = handle->detectStaleMaster;
|
int detect_stale_master = handle->detectStaleMaster;
|
||||||
MONITOR_SERVERS *root_master;
|
MONITOR_SERVERS *root_master;
|
||||||
@ -619,7 +512,7 @@ size_t nrounds = 0;
|
|||||||
* round.
|
* round.
|
||||||
*/
|
*/
|
||||||
if (nrounds != 0 &&
|
if (nrounds != 0 &&
|
||||||
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >=
|
((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >=
|
||||||
MON_BASE_INTERVAL_MS)
|
MON_BASE_INTERVAL_MS)
|
||||||
{
|
{
|
||||||
nrounds += 1;
|
nrounds += 1;
|
||||||
@ -628,7 +521,7 @@ size_t nrounds = 0;
|
|||||||
nrounds += 1;
|
nrounds += 1;
|
||||||
|
|
||||||
/* start from the first server in the list */
|
/* start from the first server in the list */
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
|
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
@ -636,7 +529,7 @@ size_t nrounds = 0;
|
|||||||
ptr->pending_status = ptr->server->status;
|
ptr->pending_status = ptr->server->status;
|
||||||
|
|
||||||
/* monitor current node */
|
/* monitor current node */
|
||||||
monitorDatabase(handle, ptr);
|
monitorDatabase(mon, ptr);
|
||||||
|
|
||||||
if (mon_status_changed(ptr))
|
if (mon_status_changed(ptr))
|
||||||
{
|
{
|
||||||
@ -668,11 +561,11 @@ size_t nrounds = 0;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get Master server pointer */
|
/* 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*/
|
/* Update server status from monitor pending status on that server*/
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
if (! SERVER_IN_MAINT(ptr->server)) {
|
if (! SERVER_IN_MAINT(ptr->server)) {
|
||||||
@ -692,19 +585,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.
|
* Enable/Disable the MySQL Replication Stale Master dectection, allowing a previouvsly detected master to still act as a Master.
|
||||||
* This option must be enabled in order to keep the Master when the replication is stopped or removed from slaves.
|
* This option must be enabled in order to keep the Master when the replication is stopped or removed from slaves.
|
||||||
@ -716,7 +596,8 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
|||||||
static void
|
static void
|
||||||
detectStaleMaster(void *arg, int enable)
|
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));
|
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
|
* @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;
|
MONITOR_SERVERS *ptr;
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
|
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
|
@ -31,27 +31,4 @@
|
|||||||
* @endverbatim
|
* @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
|
#endif
|
@ -84,20 +84,15 @@ MODULE_INFO info = {
|
|||||||
|
|
||||||
static void *startMonitor(void *,void*);
|
static void *startMonitor(void *,void*);
|
||||||
static void stopMonitor(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 diagnostics(DCB *, void *);
|
||||||
static void setInterval(void *, size_t);
|
|
||||||
static void defaultId(void *, unsigned long);
|
static void defaultId(void *, unsigned long);
|
||||||
static void setNetworkTimeout(void *, int, int);
|
|
||||||
static bool mon_status_changed(MONITOR_SERVERS* mon_srv);
|
static bool mon_status_changed(MONITOR_SERVERS* mon_srv);
|
||||||
static bool mon_print_fail_status(MONITOR_SERVERS* mon_srv);
|
static bool mon_print_fail_status(MONITOR_SERVERS* mon_srv);
|
||||||
static MONITOR_SERVERS *getServerByNodeId(MONITOR_SERVERS *, long);
|
static MONITOR_SERVERS *getServerByNodeId(MONITOR_SERVERS *, long);
|
||||||
static MONITOR_SERVERS *getSlaveOfNodeId(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_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 int add_slave_to_master(long *, int, long);
|
||||||
static void monitor_set_pending_status(MONITOR_SERVERS *, int);
|
static void monitor_set_pending_status(MONITOR_SERVERS *, int);
|
||||||
static void monitor_clear_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 = {
|
static MONITOR_OBJECT MyObject = {
|
||||||
startMonitor,
|
startMonitor,
|
||||||
stopMonitor,
|
stopMonitor,
|
||||||
registerServer,
|
diagnostics
|
||||||
unregisterServer,
|
|
||||||
defaultUser,
|
|
||||||
diagnostics,
|
|
||||||
setInterval,
|
|
||||||
setNetworkTimeout
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,12 +147,14 @@ GetModuleObject()
|
|||||||
* This function creates a thread to execute the actual monitoring.
|
* This function creates a thread to execute the actual monitoring.
|
||||||
*
|
*
|
||||||
* @param arg The current handle - NULL if first start
|
* @param arg The current handle - NULL if first start
|
||||||
|
* @param opt Configuration parameters
|
||||||
* @return A handle to use when interacting with the monitor
|
* @return A handle to use when interacting with the monitor
|
||||||
*/
|
*/
|
||||||
static void *
|
static void *
|
||||||
startMonitor(void *arg, void* opt)
|
startMonitor(void *arg, void* opt)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle;
|
MONITOR* monitor = (MONITOR*)arg;
|
||||||
|
MYSQL_MONITOR *handle = (MYSQL_MONITOR*)monitor->handle;
|
||||||
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
||||||
if (arg)
|
if (arg)
|
||||||
{
|
{
|
||||||
@ -173,18 +165,11 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
|||||||
{
|
{
|
||||||
if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL)
|
if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
handle->databases = NULL;
|
|
||||||
handle->shutdown = 0;
|
handle->shutdown = 0;
|
||||||
handle->defaultUser = NULL;
|
|
||||||
handle->defaultPasswd = NULL;
|
|
||||||
handle->id = config_get_gateway_id();
|
handle->id = config_get_gateway_id();
|
||||||
handle->interval = MONITOR_INTERVAL;
|
|
||||||
handle->replicationHeartbeat = 0;
|
handle->replicationHeartbeat = 0;
|
||||||
handle->detectStaleMaster = 0;
|
handle->detectStaleMaster = 0;
|
||||||
handle->master = NULL;
|
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;
|
handle->master_down_script = NULL;
|
||||||
spinlock_init(&handle->lock);
|
spinlock_init(&handle->lock);
|
||||||
}
|
}
|
||||||
@ -216,109 +201,13 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
|||||||
static void
|
static void
|
||||||
stopMonitor(void *arg)
|
stopMonitor(void *arg)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
MONITOR* mon = (MONITOR*)arg;
|
||||||
|
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle;
|
||||||
|
|
||||||
handle->shutdown = 1;
|
handle->shutdown = 1;
|
||||||
thread_wait((void *)handle->tid);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Daignostic interface
|
* Daignostic interface
|
||||||
*
|
*
|
||||||
@ -327,7 +216,8 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
|||||||
*/
|
*/
|
||||||
static void diagnostics(DCB *dcb, void *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;
|
MONITOR_SERVERS *db;
|
||||||
char *sep;
|
char *sep;
|
||||||
|
|
||||||
@ -344,16 +234,16 @@ char *sep;
|
|||||||
break;
|
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,"\tMaxScale MonitorId:\t%lu\n", handle->id);
|
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,"\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,"\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,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout);
|
||||||
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout);
|
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout);
|
||||||
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout);
|
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout);
|
||||||
dcb_printf(dcb, "\tMonitored servers: ");
|
dcb_printf(dcb, "\tMonitored servers: ");
|
||||||
|
|
||||||
db = handle->databases;
|
db = mon->databases;
|
||||||
sep = "";
|
sep = "";
|
||||||
while (db)
|
while (db)
|
||||||
{
|
{
|
||||||
@ -375,14 +265,14 @@ char *sep;
|
|||||||
* @param database The database to probe
|
* @param database The database to probe
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
monitorDatabase(MYSQL_MONITOR *handle, MONITOR_SERVERS *database)
|
monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database)
|
||||||
{
|
{
|
||||||
|
MYSQL_MONITOR* handle = mon->handle;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
int num_fields;
|
|
||||||
int isslave = 0;
|
int isslave = 0;
|
||||||
char *uname = handle->defaultUser;
|
char *uname = mon->user;
|
||||||
char *passwd = handle->defaultPasswd;
|
char *passwd = mon->password;
|
||||||
unsigned long int server_version = 0;
|
unsigned long int server_version = 0;
|
||||||
char *server_string;
|
char *server_string;
|
||||||
|
|
||||||
@ -405,16 +295,15 @@ char *server_string;
|
|||||||
if (database->con == NULL || mysql_ping(database->con) != 0)
|
if (database->con == NULL || mysql_ping(database->con) != 0)
|
||||||
{
|
{
|
||||||
char *dpwd = decryptPassword(passwd);
|
char *dpwd = decryptPassword(passwd);
|
||||||
int rc;
|
int connect_timeout = mon->connect_timeout;
|
||||||
int connect_timeout = handle->connect_timeout;
|
int read_timeout = mon->read_timeout;
|
||||||
int read_timeout = handle->read_timeout;
|
int write_timeout = mon->write_timeout;
|
||||||
int write_timeout = handle->write_timeout;
|
|
||||||
|
|
||||||
database->con = mysql_init(NULL);
|
database->con = mysql_init(NULL);
|
||||||
|
|
||||||
rc = mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout);
|
mysql_options(database->con, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&connect_timeout);
|
||||||
rc = mysql_options(database->con, MYSQL_OPT_READ_TIMEOUT, (void *)&read_timeout);
|
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_WRITE_TIMEOUT, (void *)&write_timeout);
|
||||||
|
|
||||||
if (mysql_real_connect(database->con,
|
if (mysql_real_connect(database->con,
|
||||||
database->server->name,
|
database->server->name,
|
||||||
@ -493,7 +382,6 @@ char *server_string;
|
|||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
long server_id = -1;
|
long server_id = -1;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
server_id = strtol(row[0], NULL, 10);
|
server_id = strtol(row[0], NULL, 10);
|
||||||
@ -519,7 +407,6 @@ char *server_string;
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
long master_id = -1;
|
long master_id = -1;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
||||||
@ -558,7 +445,6 @@ char *server_string;
|
|||||||
&& (result = mysql_store_result(database->con)) != NULL)
|
&& (result = mysql_store_result(database->con)) != NULL)
|
||||||
{
|
{
|
||||||
long master_id = -1;
|
long master_id = -1;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
while ((row = mysql_fetch_row(result)))
|
while ((row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
||||||
@ -615,7 +501,8 @@ char *server_string;
|
|||||||
static void
|
static void
|
||||||
monitorMain(void *arg)
|
monitorMain(void *arg)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
MONITOR* mon = (MONITOR*) arg;
|
||||||
|
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle;
|
||||||
MONITOR_SERVERS *ptr;
|
MONITOR_SERVERS *ptr;
|
||||||
int replication_heartbeat = handle->replicationHeartbeat;
|
int replication_heartbeat = handle->replicationHeartbeat;
|
||||||
int detect_stale_master = handle->detectStaleMaster;
|
int detect_stale_master = handle->detectStaleMaster;
|
||||||
@ -652,7 +539,7 @@ int log_no_master = 1;
|
|||||||
* round.
|
* round.
|
||||||
*/
|
*/
|
||||||
if (nrounds != 0 &&
|
if (nrounds != 0 &&
|
||||||
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >=
|
((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >=
|
||||||
MON_BASE_INTERVAL_MS)
|
MON_BASE_INTERVAL_MS)
|
||||||
{
|
{
|
||||||
nrounds += 1;
|
nrounds += 1;
|
||||||
@ -663,7 +550,7 @@ int log_no_master = 1;
|
|||||||
num_servers = 0;
|
num_servers = 0;
|
||||||
|
|
||||||
/* start from the first server in the list */
|
/* start from the first server in the list */
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
|
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
@ -671,7 +558,7 @@ int log_no_master = 1;
|
|||||||
ptr->pending_status = ptr->server->status;
|
ptr->pending_status = ptr->server->status;
|
||||||
|
|
||||||
/* monitor current node */
|
/* monitor current node */
|
||||||
monitorDatabase(handle, ptr);
|
monitorDatabase(mon, ptr);
|
||||||
|
|
||||||
/* reset the slave list of current node */
|
/* reset the slave list of current node */
|
||||||
if (ptr->server->slaves) {
|
if (ptr->server->slaves) {
|
||||||
@ -753,7 +640,7 @@ int log_no_master = 1;
|
|||||||
ptr = ptr->next;
|
ptr = ptr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
/* if only one server is configured, that's is Master */
|
/* if only one server is configured, that's is Master */
|
||||||
if (num_servers == 1) {
|
if (num_servers == 1) {
|
||||||
if (SERVER_IS_RUNNING(ptr->server)) {
|
if (SERVER_IS_RUNNING(ptr->server)) {
|
||||||
@ -770,12 +657,12 @@ int log_no_master = 1;
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Compute the replication tree */
|
/* 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*/
|
/* Update server status from monitor pending status on that server*/
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
if (! SERVER_IN_MAINT(ptr->server)) {
|
if (! SERVER_IN_MAINT(ptr->server)) {
|
||||||
@ -852,7 +739,7 @@ int log_no_master = 1;
|
|||||||
SERVER_IS_RELAY_SERVER(root_master->server)))
|
SERVER_IS_RELAY_SERVER(root_master->server)))
|
||||||
{
|
{
|
||||||
set_master_heartbeat(handle, root_master);
|
set_master_heartbeat(handle, root_master);
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
|
|
||||||
while (ptr) {
|
while (ptr) {
|
||||||
if( (! SERVER_IN_MAINT(ptr->server)) && SERVER_IS_RUNNING(ptr->server))
|
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_SLAVE(ptr->server) ||
|
||||||
SERVER_IS_RELAY_SERVER(ptr->server)))
|
SERVER_IS_RELAY_SERVER(ptr->server)))
|
||||||
{
|
{
|
||||||
set_slave_heartbeat(handle, ptr);
|
set_slave_heartbeat(mon, ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr = ptr->next;
|
ptr = ptr->next;
|
||||||
@ -883,19 +770,6 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
|||||||
memcpy(&handle->id, &id, sizeof(unsigned long));
|
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.
|
* Enable/Disable the MySQL Replication hearbeat, detecting slave lag behind master.
|
||||||
*
|
*
|
||||||
@ -957,9 +831,6 @@ static bool mon_print_fail_status(
|
|||||||
{
|
{
|
||||||
bool succp;
|
bool succp;
|
||||||
int errcount = mon_srv->mon_err_count;
|
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)
|
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 handle The monitor handle
|
||||||
* @param database The number database server
|
* @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;
|
unsigned long id = handle->id;
|
||||||
time_t heartbeat;
|
time_t heartbeat;
|
||||||
char select_heartbeat_query[256] = "";
|
char select_heartbeat_query[256] = "";
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
int num_fields;
|
|
||||||
|
|
||||||
if (handle->master == NULL) {
|
if (handle->master == NULL) {
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
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
|
if (handle->master !=NULL && (mysql_query(database->con, select_heartbeat_query) == 0
|
||||||
&& (result = mysql_store_result(database->con)) != NULL)) {
|
&& (result = mysql_store_result(database->con)) != NULL)) {
|
||||||
int rows_found = 0;
|
int rows_found = 0;
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
|
|
||||||
while ((row = mysql_fetch_row(result))) {
|
while ((row = mysql_fetch_row(result))) {
|
||||||
int rlag = -1;
|
int rlag = -1;
|
||||||
@ -1184,7 +1054,7 @@ static void set_slave_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database
|
|||||||
|
|
||||||
if (rlag >= 0) {
|
if (rlag >= 0) {
|
||||||
/* store rlag only if greater than monitor sampling interval */
|
/* 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 {
|
} else {
|
||||||
database->server->rlag = -1;
|
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
|
* @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 *ptr;
|
||||||
MONITOR_SERVERS *backend;
|
MONITOR_SERVERS *backend;
|
||||||
SERVER *current;
|
SERVER *current;
|
||||||
@ -1246,7 +1117,7 @@ static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_serv
|
|||||||
long node_id;
|
long node_id;
|
||||||
int root_level;
|
int root_level;
|
||||||
|
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
root_level = num_servers;
|
root_level = num_servers;
|
||||||
|
|
||||||
while (ptr)
|
while (ptr)
|
||||||
@ -1265,7 +1136,7 @@ static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_serv
|
|||||||
node_id = current->master_id;
|
node_id = current->master_id;
|
||||||
if (node_id < 1) {
|
if (node_id < 1) {
|
||||||
MONITOR_SERVERS *find_slave;
|
MONITOR_SERVERS *find_slave;
|
||||||
find_slave = getSlaveOfNodeId(handle->databases, current->node_id);
|
find_slave = getSlaveOfNodeId(mon->databases, current->node_id);
|
||||||
|
|
||||||
if (find_slave == NULL) {
|
if (find_slave == NULL) {
|
||||||
current->depth = -1;
|
current->depth = -1;
|
||||||
@ -1285,7 +1156,7 @@ static MONITOR_SERVERS *get_replication_tree(MYSQL_MONITOR *handle, int num_serv
|
|||||||
root_level = current->depth;
|
root_level = current->depth;
|
||||||
handle->master = ptr;
|
handle->master = ptr;
|
||||||
}
|
}
|
||||||
backend = getServerByNodeId(handle->databases, node_id);
|
backend = getServerByNodeId(mon->databases, node_id);
|
||||||
|
|
||||||
if (backend) {
|
if (backend) {
|
||||||
node_id = backend->server->master_id;
|
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;
|
MONITOR_SERVERS *master;
|
||||||
current->depth = depth;
|
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) {
|
if (master && master->server && master->server->node_id > 0) {
|
||||||
add_slave_to_master(master->server->slaves, MONITOR_MAX_NUM_SLAVES, current->node_id);
|
add_slave_to_master(master->server->slaves, MONITOR_MAX_NUM_SLAVES, current->node_id);
|
||||||
master->server->depth = current->depth -1;
|
master->server->depth = current->depth -1;
|
||||||
@ -1383,65 +1254,3 @@ monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit)
|
|||||||
{
|
{
|
||||||
ptr->pending_status &= ~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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -49,9 +49,6 @@ typedef struct {
|
|||||||
pthread_t tid; /**< id of monitor thread */
|
pthread_t tid; /**< id of monitor thread */
|
||||||
int shutdown; /**< Flag to shutdown the monitor thread */
|
int shutdown; /**< Flag to shutdown the monitor thread */
|
||||||
int status; /**< Monitor status */
|
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 */
|
unsigned long id; /**< Monitor ID */
|
||||||
int replicationHeartbeat; /**< Monitor flag for MySQL replication heartbeat */
|
int replicationHeartbeat; /**< Monitor flag for MySQL replication heartbeat */
|
||||||
int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */
|
int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */
|
||||||
@ -59,14 +56,6 @@ typedef struct {
|
|||||||
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
|
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
|
||||||
int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
|
int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
|
||||||
MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */
|
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;
|
} MYSQL_MONITOR;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ extern __thread log_info_t tls_log_info;
|
|||||||
|
|
||||||
static void monitorMain(void *);
|
static void monitorMain(void *);
|
||||||
|
|
||||||
static char *version_str = "V1.1.0";
|
static char *version_str = "V2.1.0";
|
||||||
|
|
||||||
MODULE_INFO info = {
|
MODULE_INFO info = {
|
||||||
MODULE_API_MONITOR,
|
MODULE_API_MONITOR,
|
||||||
@ -61,22 +61,12 @@ MODULE_INFO info = {
|
|||||||
|
|
||||||
static void *startMonitor(void *,void*);
|
static void *startMonitor(void *,void*);
|
||||||
static void stopMonitor(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 diagnostics(DCB *, void *);
|
||||||
static void setInterval(void *, size_t);
|
|
||||||
static void setNetworkTimeout(void *arg, int type, int value);
|
|
||||||
|
|
||||||
static MONITOR_OBJECT MyObject = {
|
static MONITOR_OBJECT MyObject = {
|
||||||
startMonitor,
|
startMonitor,
|
||||||
stopMonitor,
|
stopMonitor,
|
||||||
registerServer,
|
diagnostics
|
||||||
unregisterServer,
|
|
||||||
defaultUsers,
|
|
||||||
diagnostics,
|
|
||||||
setInterval,
|
|
||||||
setNetworkTimeout
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,26 +117,19 @@ GetModuleObject()
|
|||||||
static void *
|
static void *
|
||||||
startMonitor(void *arg,void* opt)
|
startMonitor(void *arg,void* opt)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle;
|
MONITOR* mon = (MONITOR*)arg;
|
||||||
|
MYSQL_MONITOR *handle = mon->handle;
|
||||||
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
||||||
if (arg != NULL)
|
if (handle != NULL)
|
||||||
{
|
{
|
||||||
handle = (MYSQL_MONITOR *)arg;
|
|
||||||
handle->shutdown = 0;
|
handle->shutdown = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL)
|
if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
handle->databases = NULL;
|
|
||||||
handle->shutdown = 0;
|
handle->shutdown = 0;
|
||||||
handle->defaultUser = NULL;
|
|
||||||
handle->defaultPasswd = NULL;
|
|
||||||
handle->id = MONITOR_DEFAULT_ID;
|
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);
|
spinlock_init(&handle->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,82 +145,13 @@ CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt;
|
|||||||
static void
|
static void
|
||||||
stopMonitor(void *arg)
|
stopMonitor(void *arg)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
MONITOR* mon = (MONITOR*)arg;
|
||||||
|
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle;
|
||||||
|
|
||||||
handle->shutdown = 1;
|
handle->shutdown = 1;
|
||||||
thread_wait((void *)handle->tid);
|
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
|
* Diagnostic interface
|
||||||
*
|
*
|
||||||
@ -247,7 +161,8 @@ MONITOR_SERVERS *ptr, *lptr;
|
|||||||
static void
|
static void
|
||||||
diagnostics(DCB *dcb, void *arg)
|
diagnostics(DCB *dcb, void *arg)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
MONITOR* mon = arg;
|
||||||
|
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle;
|
||||||
MONITOR_SERVERS *db;
|
MONITOR_SERVERS *db;
|
||||||
char *sep;
|
char *sep;
|
||||||
|
|
||||||
@ -264,13 +179,13 @@ char *sep;
|
|||||||
break;
|
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,"\tConnect Timeout:\t%i seconds\n", handle->connect_timeout);
|
dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout);
|
||||||
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", handle->read_timeout);
|
dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout);
|
||||||
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", handle->write_timeout);
|
dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout);
|
||||||
dcb_printf(dcb, "\tMonitored servers: ");
|
dcb_printf(dcb, "\tMonitored servers: ");
|
||||||
|
|
||||||
db = handle->databases;
|
db = mon->databases;
|
||||||
sep = "";
|
sep = "";
|
||||||
while (db)
|
while (db)
|
||||||
{
|
{
|
||||||
@ -281,35 +196,15 @@ char *sep;
|
|||||||
dcb_printf(dcb, "\n");
|
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
|
* Monitor an individual server
|
||||||
*
|
*
|
||||||
* @param database The database to probe
|
* @param database The database to probe
|
||||||
*/
|
*/
|
||||||
static void
|
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_ROW row;
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
int num_fields;
|
int num_fields;
|
||||||
@ -334,9 +229,9 @@ char *server_string;
|
|||||||
{
|
{
|
||||||
char *dpwd = decryptPassword(passwd);
|
char *dpwd = decryptPassword(passwd);
|
||||||
int rc;
|
int rc;
|
||||||
int connect_timeout = handle->connect_timeout;
|
int connect_timeout = mon->connect_timeout;
|
||||||
int read_timeout = handle->read_timeout;
|
int read_timeout = mon->read_timeout;
|
||||||
int write_timeout = handle->write_timeout;
|
int write_timeout = mon->write_timeout;
|
||||||
|
|
||||||
database->con = mysql_init(NULL);
|
database->con = mysql_init(NULL);
|
||||||
|
|
||||||
@ -433,7 +328,8 @@ char *server_string;
|
|||||||
static void
|
static void
|
||||||
monitorMain(void *arg)
|
monitorMain(void *arg)
|
||||||
{
|
{
|
||||||
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
MONITOR* mon = arg;
|
||||||
|
MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle;
|
||||||
MONITOR_SERVERS *ptr;
|
MONITOR_SERVERS *ptr;
|
||||||
long master_id;
|
long master_id;
|
||||||
size_t nrounds = 0;
|
size_t nrounds = 0;
|
||||||
@ -467,7 +363,7 @@ size_t nrounds = 0;
|
|||||||
* round.
|
* round.
|
||||||
*/
|
*/
|
||||||
if (nrounds != 0 &&
|
if (nrounds != 0 &&
|
||||||
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >=
|
((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >=
|
||||||
MON_BASE_INTERVAL_MS)
|
MON_BASE_INTERVAL_MS)
|
||||||
{
|
{
|
||||||
nrounds += 1;
|
nrounds += 1;
|
||||||
@ -475,12 +371,12 @@ size_t nrounds = 0;
|
|||||||
}
|
}
|
||||||
nrounds += 1;
|
nrounds += 1;
|
||||||
master_id = -1;
|
master_id = -1;
|
||||||
ptr = handle->databases;
|
ptr = mon->databases;
|
||||||
|
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
unsigned int prev_status = ptr->server->status;
|
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 ||
|
if (ptr->server->status != prev_status ||
|
||||||
SERVER_IS_DOWN(ptr->server))
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user