Fix crash when multiple MySQL monitors monitor same servers
The monitors always freed and reallocated the memory for the slaves. It was always of the same size so a static array of that size should also work.
This commit is contained in:
@ -81,7 +81,6 @@ server_alloc(char *servname, char *protocol, unsigned short port)
|
|||||||
server->rlag = -2;
|
server->rlag = -2;
|
||||||
server->master_id = -1;
|
server->master_id = -1;
|
||||||
server->depth = -1;
|
server->depth = -1;
|
||||||
server->slaves = NULL;
|
|
||||||
server->parameters = NULL;
|
server->parameters = NULL;
|
||||||
server->server_string = NULL;
|
server->server_string = NULL;
|
||||||
spinlock_init(&server->lock);
|
spinlock_init(&server->lock);
|
||||||
|
@ -129,7 +129,6 @@ typedef enum
|
|||||||
|
|
||||||
#define MONITOR_INTERVAL 10000 // in milliseconds
|
#define MONITOR_INTERVAL 10000 // in milliseconds
|
||||||
#define MONITOR_DEFAULT_ID 1UL // unsigned long value
|
#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
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create declarations of the enum for monitor events and also the array of
|
* Create declarations of the enum for monitor events and also the array of
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_SERVER_NAME_LEN 1024
|
#define MAX_SERVER_NAME_LEN 1024
|
||||||
|
#define MAX_NUM_SLAVES 128 /**< Maximum number of slaves under a single server*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server parameters used for weighting routing decissions
|
* The server parameters used for weighting routing decissions
|
||||||
@ -99,7 +100,7 @@ typedef struct server
|
|||||||
SERVER_PARAM *parameters; /**< Parameters of a server that may be used to weight routing decisions */
|
SERVER_PARAM *parameters; /**< Parameters of a server that may be used to weight routing decisions */
|
||||||
long master_id; /**< Master server id of this node */
|
long master_id; /**< Master server id of this node */
|
||||||
int depth; /**< Replication level in the tree */
|
int depth; /**< Replication level in the tree */
|
||||||
long *slaves; /**< Slaves of this node */
|
long slaves[MAX_NUM_SLAVES]; /**< Slaves of this node */
|
||||||
bool master_err_is_logged; /*< If node failed, this indicates whether it is logged */
|
bool master_err_is_logged; /*< If node failed, this indicates whether it is logged */
|
||||||
DCB *persistent; /**< List of unused persistent connections to the server */
|
DCB *persistent; /**< List of unused persistent connections to the server */
|
||||||
SPINLOCK persistlock; /**< Lock for adjusting the persistent connections list */
|
SPINLOCK persistlock; /**< Lock for adjusting the persistent connections list */
|
||||||
|
@ -550,7 +550,7 @@ static MONITOR_SERVERS *build_mysql51_replication_tree(MONITOR *mon)
|
|||||||
if (mysql_num_rows(result) > 0)
|
if (mysql_num_rows(result) > 0)
|
||||||
{
|
{
|
||||||
ismaster = true;
|
ismaster = true;
|
||||||
while (nslaves < MONITOR_MAX_NUM_SLAVES && (row = mysql_fetch_row(result)))
|
while (nslaves < MAX_NUM_SLAVES && (row = mysql_fetch_row(result)))
|
||||||
{
|
{
|
||||||
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
/* get Slave_IO_Running and Slave_SQL_Running values*/
|
||||||
database->server->slaves[nslaves] = atol(row[0]);
|
database->server->slaves[nslaves] = atol(row[0]);
|
||||||
@ -838,12 +838,7 @@ monitorMain(void *arg)
|
|||||||
monitorDatabase(mon, ptr);
|
monitorDatabase(mon, ptr);
|
||||||
|
|
||||||
/* reset the slave list of current node */
|
/* reset the slave list of current node */
|
||||||
if (ptr->server->slaves)
|
memset(&ptr->server->slaves, 0, sizeof(ptr->server->slaves));
|
||||||
{
|
|
||||||
free(ptr->server->slaves);
|
|
||||||
}
|
|
||||||
/* create a new slave list */
|
|
||||||
ptr->server->slaves = (long *) calloc(MONITOR_MAX_NUM_SLAVES, sizeof(long));
|
|
||||||
|
|
||||||
num_servers++;
|
num_servers++;
|
||||||
|
|
||||||
@ -1450,7 +1445,8 @@ static MONITOR_SERVERS *get_replication_tree(MONITOR *mon, int num_servers)
|
|||||||
master = getServerByNodeId(mon->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, sizeof(master->server->slaves),
|
||||||
|
current->node_id);
|
||||||
master->server->depth = current->depth - 1;
|
master->server->depth = current->depth - 1;
|
||||||
monitor_set_pending_status(master, SERVER_MASTER);
|
monitor_set_pending_status(master, SERVER_MASTER);
|
||||||
handle->master = master;
|
handle->master = master;
|
||||||
@ -1511,7 +1507,7 @@ static int add_slave_to_master(long *slaves_list, int list_size, long node_id)
|
|||||||
{
|
{
|
||||||
if (slaves_list[i] == 0)
|
if (slaves_list[i] == 0)
|
||||||
{
|
{
|
||||||
memcpy(&slaves_list[i], &node_id, sizeof(long));
|
slaves_list[i] = node_id;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user