summaryrefslogtreecommitdiff
path: root/sql/set_var.cc
diff options
context:
space:
mode:
authorunknown <andrey@lmy004.>2006-05-22 20:46:13 +0200
committerunknown <andrey@lmy004.>2006-05-22 20:46:13 +0200
commit6b6a9b76d06355e3e16e65099485418e93b811b9 (patch)
tree3d492384ce369edfba63a049dc688265d9d27a21 /sql/set_var.cc
parent18e11fe5b85944000a92f2b789b571eda21f5082 (diff)
downloadmariadb-git-6b6a9b76d06355e3e16e65099485418e93b811b9.tar.gz
fix for bug #17619 Scheduler race conditions
- Scheduler is either initialized at server start or never. Starting & stopping is now suspending & resuming. - The scheduler has clear OO interface - Now all calls to the scheduler are synchronous - GLOBAL event_scheduler uses thd::sys_var_tmp (see set_var.cc) - External API is encapsulated into class Events - Includes fixes for all comments of Kostja's review of 19.05.2005 Starting to merge into 5.1-release (5.1.10) and push BitKeeper/etc/ignore: Added libmysqld/event_scheduler.cc to the ignore list libmysqld/Makefile.am: executor -> scheduler mysql-test/r/events.result: update result mysql-test/r/events_bugs.result: update result mysql-test/r/events_logs_tests.result: update result mysql-test/r/events_microsec.result: update result mysql-test/r/events_scheduling.result: update result mysql-test/r/events_stress.result: update result mysql-test/t/disabled.def: enable these tests mysql-test/t/events.test: optimize the test a bit for speed, save some seconds runtime remove FULL from SHOW EVENTS mostly use I_S.EVENTS mysql-test/t/events_bugs.test: Skip irrelevant for the current design tests - all events are loaded on server startup. Change in mysql.event will be visible on next server start. Don't use numeric error codes. mysql-test/t/events_logs_tests.test: optimize the test a bit for speed mysql-test/t/events_microsec.test: Skip irrelevant for the current design tests - all events are loaded on server startup. Change in mysql.event will be visible on next server start. Don't use numeric error codes. mysql-test/t/events_scheduling.test: broader test mysql-test/t/events_stress.test: Rework the test to the new architecture of suspending/resuming. Use less events, no need for thousands, hundreds is still ok. sql/Makefile.am: executor -> scheduler sql/cmakelists.txt: executor -> scheduler sql/event.cc: - remove todo comments - remove unneded evex_queue abstraction functions - move events_init() and events_shutdown() from event_executor.cc to here - export db_create_event - remove evex_load_and_compile_event, part of class Event_scheduler - integrate the public interface found in event.h and used by sql_parse.cc to use the new class Event_scheduler. sql/event.h: - add COND_finished so if one thread kills a running event it waits on this - export callback event_timed_definer_equal, event_timed_identifier_equal(), event_timed_name_equal and event_timed_db_equal() to be used by Event_scheduler::drop_matching_events() - cleanup event.h - encapsulated all external interface into class Events sql/event_executor.cc: make it empty, will delete after that sql/event_priv.h: - more things in the private header - remove event queue abstraction functions. tightly bind to QUEUE - export privately db_drop_event, db_find_event, db_create_event() - made change_security_context() and restore_security_context() free functions sql/event_timed.cc: - fix calculation of time when ENDS is set (STARTS is always set) - during Event_timed::compile() set the right Security_ctx. Prevents a crash during Event_scheduler::load_events_from_db() - add Event_timed::kill_thread() - implement event_timed_*_equal() - made change_security_context() and restore_security_context() free functions. - Comments cleanups sql/lex.h: new word scheduler for SHOW SCHEDULER STATUS (available only debug builds) sql/log.cc: move these from event_scheduler.cc sql/mysql_priv.h: refactor kill_one_thread export sql_print_message_func and sql_print_message_handlers sql/mysqld.cc: In close_connections, called by kill_server() skip the main scheduler thread and use events_shutdown() for shutting down the scheduler, in the same manner it's done for RPL. Add a new value to --event-scheduler : 0 <- No scheduler available 1 <- Start with scheduler enabled 2 <- Start with scheduler suspended sql/repl_failsafe.cc: refactor thd::system_thread to be an enum sql/set_var.cc: move sys_var_event_executor::update() to set_var.cc executor -> scheduler use thd::sys_var_tmp sql/set_var.h: executor -> scheduler sql/share/errmsg.txt: 3 new error messages sql/sql_class.cc: refactor thd::system_thread to be an enum . more type-safety sql/sql_class.h: refactor thd::system_thread to be an enum . more type-safety sql/sql_db.cc: get the error from evex_drop_schema_events sql/sql_error.h: export warning_level_names sql/sql_lex.h: new command SHOW SCHEDULER STATUS, available only in debug build and for debug purposes. sql/sql_parse.cc: refactor kill_one_thread() -> does the *dirty* work, and sql_kill just the reporting. add handler for SQLCOM_SHOW_SCHEDULER_STATUS sql/sql_show.cc: fix verbosity handling (this will be obsoleted anyway by the fix for 17394). sql/sql_yacc.yy: remove FULL from SHOW EVENTS add SHOW SCHEDULER STATUS in debug builds sql/table.cc: Fix valgrind warning.
Diffstat (limited to 'sql/set_var.cc')
-rw-r--r--sql/set_var.cc72
1 files changed, 67 insertions, 5 deletions
diff --git a/sql/set_var.cc b/sql/set_var.cc
index ae380bdf2d5..9b06e0f833f 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -56,6 +56,8 @@
#include <thr_alarm.h>
#include <myisam.h>
+#include "event_scheduler.h"
+
/* WITH_BERKELEY_STORAGE_ENGINE */
extern bool berkeley_shared_data;
extern ulong berkeley_max_lock, berkeley_log_buffer_size;
@@ -106,7 +108,6 @@ extern ulong ndb_report_thresh_binlog_mem_usage;
-extern my_bool event_executor_running_global_var;
static HASH system_variable_hash;
const char *bool_type_names[]= { "OFF", "ON", NullS };
@@ -222,9 +223,8 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout",
&delayed_insert_timeout);
sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size",
&delayed_queue_size);
-sys_var_event_executor sys_event_executor("event_scheduler",
- (my_bool *)
- &event_executor_running_global_var);
+
+sys_var_event_scheduler sys_event_scheduler("event_scheduler");
sys_var_long_ptr sys_expire_logs_days("expire_logs_days",
&expire_logs_days);
sys_var_bool_ptr sys_flush("flush", &myisam_flush);
@@ -747,7 +747,7 @@ SHOW_VAR init_vars[]= {
{sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS},
{sys_engine_condition_pushdown.name,
(char*) &sys_engine_condition_pushdown, SHOW_SYS},
- {sys_event_executor.name, (char*) &sys_event_executor, SHOW_SYS},
+ {sys_event_scheduler.name, (char*) &sys_event_scheduler, SHOW_SYS},
{sys_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS},
{sys_flush.name, (char*) &sys_flush, SHOW_SYS},
{sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS},
@@ -3579,6 +3579,68 @@ byte *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
return (byte*) thd->strdup(buf);
}
+
+/*
+ The update method of the global variable event_scheduler.
+ If event_scheduler is switched from 0 to 1 then the scheduler main
+ thread is resumed and if from 1 to 0 the scheduler thread is suspended
+
+ SYNOPSIS
+ sys_var_event_scheduler::update()
+ thd Thread context (unused)
+ var The new value
+
+ Returns
+ FALSE OK
+ TRUE Error
+*/
+
+bool
+sys_var_event_scheduler::update(THD *thd, set_var *var)
+{
+ enum Event_scheduler::enum_error_code res;
+ Event_scheduler *scheduler= Event_scheduler::get_instance();
+ /* here start the thread if not running. */
+ DBUG_ENTER("sys_var_event_scheduler::update");
+
+ DBUG_PRINT("new_value", ("%lu", (bool)var->save_result.ulong_value));
+ if (!scheduler->initialized())
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=0");
+ DBUG_RETURN(true);
+ }
+
+ if (var->save_result.ulong_value < 1 || var->save_result.ulong_value > 2)
+ {
+ char buf[64];
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "event_scheduler",
+ llstr(var->save_result.ulong_value, buf));
+ DBUG_RETURN(true);
+ }
+ if ((res= scheduler->suspend_or_resume(var->save_result.ulong_value == 1?
+ Event_scheduler::RESUME:
+ Event_scheduler::SUSPEND)))
+ my_error(ER_EVENT_SET_VAR_ERROR, MYF(0), (uint) res);
+ DBUG_RETURN((bool) res);
+}
+
+
+byte *sys_var_event_scheduler::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ Event_scheduler *scheduler= Event_scheduler::get_instance();
+
+ if (!scheduler->initialized())
+ thd->sys_var_tmp.long_value= 0;
+ else if (scheduler->get_state() == Event_scheduler::RUNNING)
+ thd->sys_var_tmp.long_value= 1;
+ else
+ thd->sys_var_tmp.long_value= 2;
+
+ return (byte*) &thd->sys_var_tmp;
+}
+
+
/****************************************************************************
Used templates
****************************************************************************/