diff options
author | Venkata Sidagam <venkata.sidagam@oracle.com> | 2013-01-24 14:02:54 +0530 |
---|---|---|
committer | Venkata Sidagam <venkata.sidagam@oracle.com> | 2013-01-24 14:02:54 +0530 |
commit | 776df0a3660ebc724754b56a007345b3961e8a36 (patch) | |
tree | d16896141d9689b8c8b59960037ba07cf1fa15df | |
parent | 65cb30b3b94d1a0cca207623519f711d7ff11d17 (diff) | |
download | mariadb-git-776df0a3660ebc724754b56a007345b3961e8a36.tar.gz |
Bug #11752803 SERVER CRASHES IF MAX_CONNECTIONS DECREASED BELOW
CERTAIN LEVEL
Problem description: mysqld crashes when we update the max_connections
variable to lesser value than the number of currently open connections.
Analysis: The "alarm_queue.max_elements" size will be decided at the
server start time and it will get modified if we change max_connections
value. In the current scenario the value of "alarm_queue.max_elements"
is decremented when the max_connections is set to 2. When updating the
"alarm_queue.max_elements" value we are not updating "max_used_alarms"
value. Hence, instead of getting the warning "thr_alarm queue is full"
it is ending up in asserting the server at the time of inserting new
elements in the queue.
Fix: the fix is to dynamically increase the size of the alarm_queue.
In order to do that, queue_insert_safe() should be used instead if
queue_insert().
-rw-r--r-- | mysys/thr_alarm.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 6541fab138b..e2fc54c487e 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -52,6 +52,8 @@ static QUEUE alarm_queue; static uint max_used_alarms=0; pthread_t alarm_thread; +#define MY_THR_ALARM_QUEUE_EXTENT 10 + #ifdef USE_ALARM_THREAD static void *alarm_handler(void *arg); #define reschedule_alarms() pthread_cond_signal(&COND_alarm) @@ -74,8 +76,8 @@ void init_thr_alarm(uint max_alarms) DBUG_ENTER("init_thr_alarm"); alarm_aborted=0; next_alarm_expire_time= ~ (time_t) 0; - init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0, - compare_ulong,NullS); + init_queue_ex(&alarm_queue, max_alarms + 1, offsetof(ALARM,expire_time), 0, + compare_ulong, NullS, MY_THR_ALARM_QUEUE_EXTENT); sigfillset(&full_signal_set); /* Neaded to block signals */ pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_alarm,NULL); @@ -127,7 +129,10 @@ void resize_thr_alarm(uint max_alarms) than max_alarms */ if (alarm_queue.elements < max_alarms) + { resize_queue(&alarm_queue,max_alarms+1); + max_used_alarms= alarm_queue.elements; + } pthread_mutex_unlock(&LOCK_alarm); } @@ -182,17 +187,6 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) if (alarm_queue.elements >= max_used_alarms) { - if (alarm_queue.elements == alarm_queue.max_elements) - { - DBUG_PRINT("info", ("alarm queue full")); - fprintf(stderr,"Warning: thr_alarm queue is full\n"); - *alrm= 0; /* No alarm */ - pthread_mutex_unlock(&LOCK_alarm); -#ifndef USE_ONE_SIGNAL_HAND - pthread_sigmask(SIG_SETMASK,&old_mask,NULL); -#endif - DBUG_RETURN(1); - } max_used_alarms=alarm_queue.elements+1; } reschedule= (ulong) next_alarm_expire_time > (ulong) now + sec; @@ -216,7 +210,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) alarm_data->alarmed=0; alarm_data->thread= current_my_thread_var->pthread_self; alarm_data->thread_id= current_my_thread_var->id; - queue_insert(&alarm_queue,(uchar*) alarm_data); + queue_insert_safe(&alarm_queue, (uchar*) alarm_data); /* Reschedule alarm if the current one has more than sec left */ if (reschedule) |