3191 Dmitry Lenev 2010-11-09
More changes to draft patch refactoring global read
lock implementation. Makes GRL yet another type of
metadata lock and thus exposes it to deadlock detector
in MDL subsystem.
Solves bugs #54673 "It takes too long to get readlock for
'FLUSH TABLES WITH READ LOCK'" and #57006 "Deadlock between
HANDLER and FLUSH TABLES WITH READ LOCK".
Work-in-progress. Solve problems with deadlocks within
events subsystem. Move opening and updating of event table
out of critical section protecting in-memory queue.
modified:
sql/event_data_objects.cc
sql/event_data_objects.h
sql/event_db_repository.cc
sql/event_db_repository.h
sql/event_queue.cc
3190 Dmitry Lenev 2010-11-08
More changes to draft patch refactoring global read
lock implementation. Makes GRL yet another type of
metadata lock and thus exposes it to deadlock detector
in MDL subsystem.
Solves bugs #54673 "It takes too long to get readlock for
'FLUSH TABLES WITH READ LOCK'" and #57006 "Deadlock between
HANDLER and FLUSH TABLES WITH READ LOCK".
Work-in-progress. Minor after review fixes.
modified:
sql/sql_base.cc
sql/sql_parse.cc
=== modified file 'sql/event_data_objects.cc'
--- a/sql/event_data_objects.cc 2010-07-27 10:25:53 +0000
+++ b/sql/event_data_objects.cc 2010-11-09 12:06:27 +0000
@@ -290,7 +290,6 @@ Event_basic::load_time_zone(THD *thd, co
*/
Event_queue_element::Event_queue_element():
- status_changed(FALSE), last_executed_changed(FALSE),
on_completion(Event_parse_data::ON_COMPLETION_DROP),
status(Event_parse_data::ENABLED), expression(0), dropped(FALSE),
execution_count(0)
@@ -539,7 +538,6 @@ Event_queue_element::load_from_row(THD *
TIME_NO_ZERO_DATE);
last_executed= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
}
- last_executed_changed= FALSE;
if ((ptr= get_field(&mem_root, table->field[ET_FIELD_STATUS])) == NullS)
DBUG_RETURN(TRUE);
@@ -935,7 +933,6 @@ Event_queue_element::compute_next_execut
DBUG_PRINT("info",("One-time event will be dropped: %d.", dropped));
status= Event_parse_data::DISABLED;
- status_changed= TRUE;
}
goto ret;
}
@@ -955,7 +952,6 @@ Event_queue_element::compute_next_execut
dropped= TRUE;
DBUG_PRINT("info", ("Dropped: %d", dropped));
status= Event_parse_data::DISABLED;
- status_changed= TRUE;
goto ret;
}
@@ -1018,7 +1014,6 @@ Event_queue_element::compute_next_execut
if (on_completion == Event_parse_data::ON_COMPLETION_DROP)
dropped= TRUE;
status= Event_parse_data::DISABLED;
- status_changed= TRUE;
}
else
{
@@ -1108,7 +1103,6 @@ Event_queue_element::compute_next_execut
execute_at= 0;
execute_at_null= TRUE;
status= Event_parse_data::DISABLED;
- status_changed= TRUE;
if (on_completion == Event_parse_data::ON_COMPLETION_DROP)
dropped= TRUE;
}
@@ -1144,50 +1138,11 @@ void
Event_queue_element::mark_last_executed(THD *thd)
{
last_executed= (my_time_t) thd->query_start();
- last_executed_changed= TRUE;
execution_count++;
}
-/*
- Saves status and last_executed_at to the disk if changed.
-
- SYNOPSIS
- Event_queue_element::update_timing_fields()
- thd - thread context
-
- RETURN VALUE
- FALSE OK
- TRUE Error while opening mysql.event for writing or during
- write on disk
-*/
-
-bool
-Event_queue_element::update_timing_fields(THD *thd)
-{
- Event_db_repository *db_repository= Events::get_db_repository();
- int ret;
-
- DBUG_ENTER("Event_queue_element::update_timing_fields");
-
- DBUG_PRINT("enter", ("name: %*s", (int) name.length, name.str));
-
- /* No need to update if nothing has changed */
- if (!(status_changed || last_executed_changed))
- DBUG_RETURN(0);
-
- ret= db_repository->update_timing_fields_for_event(thd,
- dbname, name,
- last_executed_changed,
- last_executed,
- status_changed,
- (ulonglong) status);
- last_executed_changed= status_changed= FALSE;
- DBUG_RETURN(ret);
-}
-
-
static
void
append_datetime(String *buf, Time_zone *time_zone, my_time_t secs,
=== modified file 'sql/event_data_objects.h'
--- a/sql/event_data_objects.h 2010-03-31 14:05:33 +0000
+++ b/sql/event_data_objects.h 2010-11-09 12:06:27 +0000
@@ -82,10 +82,6 @@ protected:
class Event_queue_element : public Event_basic
{
-protected:
- bool status_changed;
- bool last_executed_changed;
-
public:
int on_completion;
int status;
@@ -117,9 +113,6 @@ public:
void
mark_last_executed(THD *thd);
-
- bool
- update_timing_fields(THD *thd);
};
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2010-11-03 14:30:33 +0000
+++ b/sql/event_db_repository.cc 2010-11-09 12:06:27 +0000
@@ -1060,15 +1060,14 @@ Event_db_repository::
update_timing_fields_for_event(THD *thd,
LEX_STRING event_db_name,
LEX_STRING event_name,
- bool update_last_executed,
my_time_t last_executed,
- bool update_status,
ulonglong status)
{
TABLE *table= NULL;
Field **fields;
int ret= 1;
bool save_binlog_row_based;
+ MYSQL_TIME time;
DBUG_ENTER("Event_db_repository::update_timing_fields_for_event");
@@ -1093,20 +1092,12 @@ update_timing_fields_for_event(THD *thd,
/* Don't update create on row update. */
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
- if (update_last_executed)
- {
- MYSQL_TIME time;
- my_tz_OFFSET0->gmt_sec_to_TIME(&time, last_executed);
+ my_tz_OFFSET0->gmt_sec_to_TIME(&time, last_executed);
+ fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
+ fields[ET_FIELD_LAST_EXECUTED]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
- fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
- fields[ET_FIELD_LAST_EXECUTED]->store_time(&time,
- MYSQL_TIMESTAMP_DATETIME);
- }
- if (update_status)
- {
- fields[ET_FIELD_STATUS]->set_notnull();
- fields[ET_FIELD_STATUS]->store(status, TRUE);
- }
+ fields[ET_FIELD_STATUS]->set_notnull();
+ fields[ET_FIELD_STATUS]->store(status, TRUE);
if ((ret= table->file->ha_update_row(table->record[1], table->record[0])))
{
=== modified file 'sql/event_db_repository.h'
--- a/sql/event_db_repository.h 2010-07-27 10:25:53 +0000
+++ b/sql/event_db_repository.h 2010-11-09 12:06:27 +0000
@@ -101,9 +101,7 @@ public:
update_timing_fields_for_event(THD *thd,
LEX_STRING event_db_name,
LEX_STRING event_name,
- bool update_last_executed,
my_time_t last_executed,
- bool update_status,
ulonglong status);
public:
static bool
=== modified file 'sql/event_queue.cc'
--- a/sql/event_queue.cc 2010-10-22 11:58:09 +0000
+++ b/sql/event_queue.cc 2010-11-09 12:06:27 +0000
@@ -17,6 +17,8 @@
#include "unireg.h"
#include "event_queue.h"
#include "event_data_objects.h"
+#include "event_db_repository.h"
+#include "events.h"
#include "sql_audit.h"
#include "tztime.h" // my_tz_find, my_tz_OFFSET0, struct Time_zone
#include "log.h" // sql_print_error
@@ -444,7 +446,6 @@ Event_queue::recalculate_activation_time
for (i= 0; i < queue.elements; i++)
{
((Event_queue_element*)queue_element(&queue, i))->compute_next_execution_time();
- ((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd);
}
queue_fix(&queue);
/*
@@ -567,6 +568,8 @@ Event_queue::get_top_for_execution_if_ti
{
bool ret= FALSE;
*event_name= NULL;
+ my_time_t last_executed;
+ int status;
DBUG_ENTER("Event_queue::get_top_for_execution_if_time");
LOCK_QUEUE_DATA();
@@ -632,8 +635,14 @@ Event_queue::get_top_for_execution_if_ti
top->execution_count++;
(*event_name)->dropped= top->dropped;
+ /*
+ Save new values of last_executed timestamp and event status on stack
+ in order to be able to update event description in system table once
+ QUEUE_DATA lock is released.
+ */
+ last_executed= top->last_executed;
+ status= top->status;
- top->update_timing_fields(thd);
if (top->status == Event_parse_data::DISABLED)
{
DBUG_PRINT("info", ("removing from the queue"));
@@ -656,9 +665,16 @@ end:
ret, (long) *event_name));
if (*event_name)
+ {
DBUG_PRINT("info", ("db: %s name: %s",
(*event_name)->dbname.str, (*event_name)->name.str));
+ Event_db_repository *db_repository= Events::get_db_repository();
+ (void) db_repository->update_timing_fields_for_event(thd,
+ (*event_name)->dbname, (*event_name)->name,
+ last_executed, (ulonglong) status);
+ }
+
DBUG_RETURN(ret);
}
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.5-runtime branch (Dmitry.Lenev:3190 to 3191) | Dmitry Lenev | 9 Nov |