Have server status updates applied during monitor loop

Previously, server status changes from MaxAdmin would be set immediately
as long as the server lock could be acquired. This meant that it might take
several seconds until the next monitor pass is executed. Usually, this was
fine but in some situations we would want the monitor to run immediately
after the change (MXS-740 and Galera). This patch changes the logic of
setting and clearing status bits to a delayed mode: changes are first applied
to a "status_pending"-variable, and only once the monitor runs will the
setting be applied. To reduce the delay, the monitor now has a flag
which is checked during sleep (between short 0.1s naps). If set, the
sleep is cut short.

If a server is not monitored, the status bits are set directly.

There is a small possibility of a race condition: If a monitor is stopped or
destroyed before the pending change is applied, the change is forgotten.
This commit is contained in:
Esa Korhonen
2016-12-14 17:50:17 +02:00
parent ac36f04f93
commit 7e9db7ed0c
9 changed files with 112 additions and 18 deletions

View File

@ -200,6 +200,9 @@ struct monitor
void *handle; /**< Handle returned from startMonitor */
size_t interval; /**< The monitor interval */
bool created_online; /**< Whether this monitor was created at runtime */
volatile bool server_pending_changes;
/**< Are there any pending changes to a server?
* If yes, the next monitor loop starts early. */
struct monitor *next; /**< Next monitor in the linked list */
};
@ -237,7 +240,8 @@ void mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval);
void mon_log_state_change(MONITOR_SERVERS *ptr);
void lock_monitor_servers(MONITOR *monitor);
void release_monitor_servers(MONITOR *monitor);
void servers_status_pending_to_current(MONITOR *monitor);
void servers_status_current_to_pending(MONITOR *monitor);
/**
* @brief Hangup connections to failed servers
*
@ -274,10 +278,10 @@ bool monitor_serialize_servers(const MONITOR *monitor);
bool monitor_serialize(const MONITOR *monitor);
/**
* Check if a monitor uses @c servers
* Check if a server is being monitored and return the monitor.
* @param server Server that is queried
* @return True if server is used by at least one monitor
* @return The monitor watching this server, or NULL if not monitored
*/
bool monitor_server_in_use(const SERVER *server);
MONITOR* monitor_server_in_use(const SERVER *server);
MXS_END_DECLS

View File

@ -96,6 +96,7 @@ typedef struct server
char *auth_options; /**< Authenticator options */
SSL_LISTENER *server_ssl; /**< SSL data structure for server, if any */
unsigned int status; /**< Status flag bitmap for the server */
unsigned int status_pending; /**< Pending status flag bitmap for the server */
char monuser[MAX_SERVER_MONUSER_LEN]; /**< User name to use to monitor the db */
char monpw[MAX_SERVER_MONPW_LEN]; /**< Password to use to monitor the db */
SERVER_STATS stats; /**< The server statistics */