diff options
author | unknown <andrey@lmy004.> | 2006-05-22 20:46:13 +0200 |
---|---|---|
committer | unknown <andrey@lmy004.> | 2006-05-22 20:46:13 +0200 |
commit | 6b6a9b76d06355e3e16e65099485418e93b811b9 (patch) | |
tree | 3d492384ce369edfba63a049dc688265d9d27a21 /sql/set_var.cc | |
parent | 18e11fe5b85944000a92f2b789b571eda21f5082 (diff) | |
download | mariadb-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.cc | 72 |
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 ****************************************************************************/ |