#At file:///Users/shulga/projects/mysql/mysql-5.1-bug12546938/ based on revid:vinay.fisrekar@stripped
3622 Dmitry Shulga 2011-05-23
Fixed bug#12546938 (formerly known as 61005) - CREATE IF NOT EXIST EVENT will create
multiple running events.
A CREATE IF NOT EXIST on an event that currently exists and is enabled will
cause multiple instances of the event to run. Disabling the event does not
help. If the event is dropped, the event stops running, but when created
again, multile instances of the event are still running. The only way to get
out of this situation is to restart the server.
The probles was that Event_db_repository::create_event() didn' return information
that permits discriminate between situation when event wasn't exist and when made
attempt to create existed event with keyword IF NOT EXIST. In last case the call to
method Event_db_repository::create_event() returned OK and information about event
inserted to queue for executions. So after statement's execution is finished
there is two event objects corresponding the event that waiting for exectuion.
The solutuon is to add flag into Event_db_repository::create_event() definition
that signals that event isn't created because event already exist and
IF NOT EXISTS clause is specified.
@ sql/event_db_repository.cc
Event_db_repository::create_event was modified: set new added argument
event_already_exists in true value if event wasn't created because event
already exist and IF NOT EXIST clause was set.
@ sql/event_db_repository.h
Added OUT argument 'event_already_exists' into create_event() method.
@ sql/events.cc
Events::create_event was modified: insert new element into
event queue only if event was actually created.
modified:
sql/event_db_repository.cc
sql/event_db_repository.h
sql/events.cc
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2011-05-04 12:59:24 +0000
+++ b/sql/event_db_repository.cc 2011-05-23 15:16:04 +0000
@@ -615,7 +615,8 @@ Event_db_repository::open_event_table(TH
bool
Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
- my_bool create_if_not)
+ bool create_if_not,
+ bool *event_already_exists)
{
int ret= 1;
TABLE *table= NULL;
@@ -648,8 +649,11 @@ Event_db_repository::create_event(THD *t
}
else
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), parse_data->name.str);
+
+ *event_already_exists= true;
goto end;
- }
+ } else
+ *event_already_exists= false;
DBUG_PRINT("info", ("non-existent, go forward"));
=== modified file 'sql/event_db_repository.h'
--- a/sql/event_db_repository.h 2007-08-15 15:08:44 +0000
+++ b/sql/event_db_repository.h 2011-05-23 15:16:04 +0000
@@ -73,7 +73,8 @@ public:
Event_db_repository(){}
bool
- create_event(THD *thd, Event_parse_data *parse_data, my_bool create_if_not);
+ create_event(THD *thd, Event_parse_data *parse_data, bool create_if_not,
+ bool *event_already_exists);
bool
update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname,
=== modified file 'sql/events.cc'
--- a/sql/events.cc 2010-03-28 08:37:47 +0000
+++ b/sql/events.cc 2011-05-23 15:16:04 +0000
@@ -370,6 +370,7 @@ create_query_string(THD *thd, String *bu
return 0;
}
+
/**
Create a new event.
@@ -391,7 +392,7 @@ Events::create_event(THD *thd, Event_par
bool if_not_exists)
{
int ret;
- bool save_binlog_row_based;
+ bool save_binlog_row_based, event_already_exists;
DBUG_ENTER("Events::create_event");
/*
@@ -440,7 +441,8 @@ Events::create_event(THD *thd, Event_par
pthread_mutex_lock(&LOCK_event_metadata);
/* On error conditions my_error() is called so no need to handle here */
- if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists)))
+ if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists,
+ &event_already_exists)))
{
Event_queue_element *new_element;
bool dropped= 0;
@@ -460,8 +462,12 @@ Events::create_event(THD *thd, Event_par
{
/* TODO: do not ignore the out parameter and a possible OOM error! */
bool created;
- if (event_queue)
+
+ if (event_queue && !event_already_exists ||
+ (event_already_exists && !if_not_exists))
event_queue->create_event(thd, new_element, &created);
+ else
+ delete new_element;
}
/*
binlog the create event unless it's been successfully dropped
@@ -472,16 +478,14 @@ Events::create_event(THD *thd, Event_par
DBUG_ASSERT(thd->query() && thd->query_length());
String log_query;
if (create_query_string(thd, &log_query))
- {
sql_print_error("Event Error: An error occurred while creating query string, "
"before writing it into binary log.");
- /* Restore the state of binlog format */
- thd->current_stmt_binlog_row_based= save_binlog_row_based;
- DBUG_RETURN(TRUE);
- }
- /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
- will be written into the binary log as the definer for the SQL thread. */
- ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
+ else
+ /*
+ If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
+ will be written into the binary log as the definer for the SQL thread.
+ */
+ ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
}
}
pthread_mutex_unlock(&LOCK_event_metadata);
Attachment: [text/bzr-bundle] bzr/dmitry.shulga@oracle.com-20110523151604-h9skbeoia9axgme5.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (Dmitry.Shulga:3622) Bug#12546938 | Dmitry Shulga | 23 May |