Skip to content

Commit b4fb43d

Browse files
author
andrey@whirlpool.hristov.com
committed
Fix for bug#22738 Events: After stop and start disabled events could reside in the queue
Disabled events weren't removed from the memory queue after the scheduler has been re-enabled. After recalculation of next execution time of an event, it might get disabled.
1 parent 301ab0d commit b4fb43d

2 files changed

Lines changed: 42 additions & 3 deletions

File tree

sql/event_queue.cc

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,16 @@ extern "C" int event_queue_element_compare_q(void *, uchar *, uchar *);
6060

6161
int event_queue_element_compare_q(void *vptr, uchar* a, uchar *b)
6262
{
63-
my_time_t lhs = ((Event_queue_element *)a)->execute_at;
64-
my_time_t rhs = ((Event_queue_element *)b)->execute_at;
63+
Event_queue_element *left = (Event_queue_element *)a;
64+
Event_queue_element *right = (Event_queue_element *)b;
65+
my_time_t lhs = left->execute_at;
66+
my_time_t rhs = right->execute_at;
67+
68+
if (left->status == Event_queue_element::DISABLED)
69+
return right->status != Event_queue_element::DISABLED;
70+
71+
if (right->status == Event_queue_element::DISABLED)
72+
return 1;
6573

6674
return (lhs < rhs ? -1 : (lhs > rhs ? 1 : 0));
6775
}
@@ -434,8 +442,34 @@ Event_queue::recalculate_activation_times(THD *thd)
434442
((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd);
435443
}
436444
queue_fix(&queue);
445+
/*
446+
The disabled elements are moved to the end during the `fix`.
447+
Start from the end and remove all of the elements which are
448+
disabled. When we find the first non-disabled one we break, as we
449+
have removed all. The queue has been ordered in a way the disabled
450+
events are at the end.
451+
*/
452+
for (i= queue.elements; i > 0; i--)
453+
{
454+
Event_queue_element *element = (Event_queue_element*)queue_element(&queue, i - 1);
455+
if (element->status != Event_queue_element::DISABLED)
456+
break;
457+
/*
458+
This won't cause queue re-order, because we remove
459+
always the last element.
460+
*/
461+
queue_remove(&queue, i - 1);
462+
delete element;
463+
}
437464
UNLOCK_QUEUE_DATA();
438465

466+
/*
467+
XXX: The events are dropped only from memory and not from disk
468+
even if `drop_list[j]->dropped` is TRUE. There will be still on the
469+
disk till next server restart.
470+
Please add code here to do it.
471+
*/
472+
439473
DBUG_VOID_RETURN;
440474
}
441475

sql/events.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,12 @@ Events::load_events_from_db(THD *thd)
11851185
{
11861186
/*
11871187
If not created, a stale event - drop if immediately if
1188-
ON COMPLETION NOT PRESERVE
1188+
ON COMPLETION NOT PRESERVE.
1189+
XXX: This won't be replicated, thus the drop won't appear in
1190+
in the slave. When the slave is restarted it will drop events.
1191+
However, as the slave will be "out of sync", it might happen that
1192+
an event created on the master, after master restart, won't be
1193+
replicated to the slave correctly, as the create will fail there.
11891194
*/
11901195
int rc= table->file->ha_delete_row(table->record[0]);
11911196
if (rc)

0 commit comments

Comments
 (0)