diff options
author | unknown <andrey@whirlpool.hristov.com> | 2008-02-22 16:18:31 +0100 |
---|---|---|
committer | unknown <andrey@whirlpool.hristov.com> | 2008-02-22 16:18:31 +0100 |
commit | 5d6ca9c2a33cf3e1496e83a746f07e81f02b5a86 (patch) | |
tree | 3b43ae5c19e58834f54aac1104692f0891d63f47 /sql/event_queue.cc | |
parent | a0d88ebb0b5f77b30c65152f87aa73363ce93d71 (diff) | |
download | mariadb-git-5d6ca9c2a33cf3e1496e83a746f07e81f02b5a86.tar.gz |
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.
sql/event_queue.cc:
Sort the event queue in a way that the disabled events will always be
at the end. We will use this for cleaning it, starting from the end.
After recalculating times in the queue, after the scheduler has been enabled
after disabled state, the queue should be cleaned from DISABLED events.
The queue is sorted in a way such that the disabled events are at the end.
Thus, we can start from the end of the queue and remove all DISABLED till we
find the first with different state.
sql/events.cc:
Add a comment about possible problem with replication of events,
disabled events and server restarts.
Diffstat (limited to 'sql/event_queue.cc')
-rw-r--r-- | sql/event_queue.cc | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 898fc206c34..719a837cbfb 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -60,8 +60,16 @@ extern "C" int event_queue_element_compare_q(void *, uchar *, uchar *); int event_queue_element_compare_q(void *vptr, uchar* a, uchar *b) { - my_time_t lhs = ((Event_queue_element *)a)->execute_at; - my_time_t rhs = ((Event_queue_element *)b)->execute_at; + Event_queue_element *left = (Event_queue_element *)a; + Event_queue_element *right = (Event_queue_element *)b; + my_time_t lhs = left->execute_at; + my_time_t rhs = right->execute_at; + + if (left->status == Event_queue_element::DISABLED) + return right->status != Event_queue_element::DISABLED; + + if (right->status == Event_queue_element::DISABLED) + return 1; return (lhs < rhs ? -1 : (lhs > rhs ? 1 : 0)); } @@ -434,8 +442,34 @@ Event_queue::recalculate_activation_times(THD *thd) ((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd); } queue_fix(&queue); + /* + The disabled elements are moved to the end during the `fix`. + Start from the end and remove all of the elements which are + disabled. When we find the first non-disabled one we break, as we + have removed all. The queue has been ordered in a way the disabled + events are at the end. + */ + for (i= queue.elements; i > 0; i--) + { + Event_queue_element *element = (Event_queue_element*)queue_element(&queue, i - 1); + if (element->status != Event_queue_element::DISABLED) + break; + /* + This won't cause queue re-order, because we remove + always the last element. + */ + queue_remove(&queue, i - 1); + delete element; + } UNLOCK_QUEUE_DATA(); + /* + XXX: The events are dropped only from memory and not from disk + even if `drop_list[j]->dropped` is TRUE. There will be still on the + disk till next server restart. + Please add code here to do it. + */ + DBUG_VOID_RETURN; } |