The world's most popular open source database
#include "mysql_priv.h"#include "events_priv.h"#include "events.h"#include "event_timed.h"#include "event_scheduler.h"#include "sp_head.h"Include dependency graph for event_scheduler.cc:

Go to the source code of this file.
Classes | |
| class | Worker_thread_param |
Defines | |
| #define | SCHED_FUNC "<unknown>" |
| #define | LOCK_SCHEDULER_DATA() lock_data(SCHED_FUNC, __LINE__) |
| #define | UNLOCK_SCHEDULER_DATA() unlock_data(SCHED_FUNC, __LINE__) |
Functions | |
| static int | event_timed_compare_q (void *vptr, byte *a, byte *b) |
| static void | evex_print_warnings (THD *thd, Event_timed *et) |
| static int | init_event_thread (THD **t, enum enum_thread_type thread_type) |
| pthread_handler_t | event_scheduler_thread (void *arg) |
| pthread_handler_t | event_worker_thread (void *arg) |
Variables | |
| static LEX_STRING | states_names [] |
| pthread_attr_t | connection_attrib |
| #define LOCK_SCHEDULER_DATA | ( | ) | lock_data(SCHED_FUNC, __LINE__) |
Definition at line 249 of file event_scheduler.cc.
Referenced by Event_scheduler::clean_queue(), Event_scheduler::create_event(), Event_scheduler::destroy(), Event_scheduler::drop_event(), Event_scheduler::drop_schema_events(), Event_scheduler::events_count(), Event_scheduler::init(), Event_scheduler::report_error_during_start(), Event_scheduler::run(), Event_scheduler::start(), Event_scheduler::stop(), Event_scheduler::suspend_or_resume(), and Event_scheduler::update_event().
| #define SCHED_FUNC "<unknown>" |
Definition at line 246 of file event_scheduler.cc.
| #define UNLOCK_SCHEDULER_DATA | ( | ) | unlock_data(SCHED_FUNC, __LINE__) |
Definition at line 250 of file event_scheduler.cc.
Referenced by Event_scheduler::clean_queue(), Event_scheduler::create_event(), Event_scheduler::destroy(), Event_scheduler::drop_event(), Event_scheduler::drop_schema_events(), Event_scheduler::events_count(), Event_scheduler::init(), Event_scheduler::report_error_during_start(), Event_scheduler::run(), Event_scheduler::start(), Event_scheduler::stop(), Event_scheduler::suspend_or_resume(), and Event_scheduler::update_event().
| pthread_handler_t event_scheduler_thread | ( | void * | arg | ) |
Definition at line 470 of file event_scheduler.cc.
References Event_scheduler::check_system_tables(), DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, init_event_thread(), LOCK_thread_count, my_thread_end(), my_thread_init(), net_end(), NULL, pthread_detach_this_thread, pthread_mutex_lock, pthread_mutex_unlock, Event_scheduler::report_error_during_start(), Event_scheduler::run(), sql_print_error(), sql_print_information(), thread_count, and thread_running.
Referenced by Event_scheduler::start().
00471 { 00472 /* needs to be first for thread_stack */ 00473 THD *thd= NULL; 00474 Event_scheduler *scheduler= (Event_scheduler *) arg; 00475 00476 DBUG_ENTER("event_scheduler_thread"); 00477 00478 my_thread_init(); 00479 pthread_detach_this_thread(); 00480 00481 /* note that constructor of THD uses DBUG_ ! */ 00482 if (!(thd= new THD) || init_event_thread(&thd, SYSTEM_THREAD_EVENT_SCHEDULER)) 00483 { 00484 sql_print_error("SCHEDULER: Cannot init manager event thread."); 00485 scheduler->report_error_during_start(); 00486 } 00487 else 00488 { 00489 thd->security_ctx->set_user((char*)"event_scheduler"); 00490 00491 sql_print_information("SCHEDULER: Manager thread booting"); 00492 if (Event_scheduler::check_system_tables(thd)) 00493 scheduler->report_error_during_start(); 00494 else 00495 scheduler->run(thd); 00496 00497 /* 00498 NOTE: Don't touch `scheduler` after this point because we have notified 00499 the 00500 thread which shuts us down that we have finished cleaning. In this 00501 very moment a new scheduler thread could be started and a crash is 00502 not welcome. 00503 */ 00504 } 00505 00506 /* 00507 If we cannot create THD then don't decrease because we haven't touched 00508 thread_count and thread_running in init_event_thread() which was never 00509 called. In init_event_thread() thread_count and thread_running are 00510 always increased even in the case the method returns an error. 00511 */ 00512 if (thd) 00513 { 00514 thd->proc_info= "Clearing"; 00515 DBUG_ASSERT(thd->net.buff != 0); 00516 net_end(&thd->net); 00517 pthread_mutex_lock(&LOCK_thread_count); 00518 thread_count--; 00519 thread_running--; 00520 delete thd; 00521 pthread_mutex_unlock(&LOCK_thread_count); 00522 } 00523 my_thread_end(); 00524 DBUG_RETURN(0); // Can't return anything here 00525 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 325 of file event_scheduler.cc.
References my_time_compare().
Referenced by Event_scheduler::init().
00326 { 00327 return my_time_compare(&((Event_timed *)a)->execute_at, 00328 &((Event_timed *)b)->execute_at); 00329 }
Here is the call graph for this function:

Here is the caller graph for this function:

| pthread_handler_t event_worker_thread | ( | void * | arg | ) |
Definition at line 541 of file event_scheduler.cc.
References change_security_context(), Worker_thread_param::COND_started, Event_timed::dbname, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, Event_timed::definer, Event_timed::definer_host, Event_timed::definer_user, Worker_thread_param::et, EVEX_COMPILE_ERROR, EVEX_MICROSECOND_UNSUP, evex_print_warnings(), Event_timed::execute(), FALSE, init_event_thread(), Worker_thread_param::LOCK_started, LOCK_thread_count, my_thread_end(), my_thread_init(), Event_timed::name, net_end(), pthread_detach_this_thread, pthread_mutex_lock, pthread_mutex_unlock, Event_timed::set_thread_id(), Event_timed::spawn_thread_finish(), sql_print_error(), sql_print_information(), Worker_thread_param::started, LEX_STRING::str, thread_count, thread_running, TRUE, and VOID.
Referenced by Event_scheduler::execute_top().
00542 { 00543 THD *thd; /* needs to be first for thread_stack */ 00544 Worker_thread_param *param= (Worker_thread_param *) arg; 00545 Event_timed *event= param->et; 00546 int ret; 00547 bool startup_error= FALSE; 00548 Security_context *save_ctx; 00549 /* this one is local and not needed after exec */ 00550 Security_context security_ctx; 00551 00552 DBUG_ENTER("event_worker_thread"); 00553 DBUG_PRINT("enter", ("event=[%s.%s]", event->dbname.str, event->name.str)); 00554 00555 my_thread_init(); 00556 pthread_detach_this_thread(); 00557 00558 if (!(thd= new THD) || init_event_thread(&thd, SYSTEM_THREAD_EVENT_WORKER)) 00559 { 00560 sql_print_error("SCHEDULER: Startup failure."); 00561 startup_error= TRUE; 00562 event->spawn_thread_finish(thd); 00563 } 00564 else 00565 event->set_thread_id(thd->thread_id); 00566 00567 DBUG_PRINT("info", ("master_access=%d db_access=%d", 00568 thd->security_ctx->master_access, thd->security_ctx->db_access)); 00569 /* 00570 If we don't change it before we send the signal back, then an intermittent 00571 DROP EVENT will take LOCK_scheduler_data and try to kill this thread, because 00572 event->thread_id is already real. However, because thd->security_ctx->user 00573 is not initialized then a crash occurs in kill_one_thread(). Thus, we have 00574 to change the context before sending the signal. We are under 00575 LOCK_scheduler_data being held by Event_scheduler::run() -> ::execute_top(). 00576 */ 00577 change_security_context(thd, event->definer_user, event->definer_host, 00578 event->dbname, &security_ctx, &save_ctx); 00579 DBUG_PRINT("info", ("master_access=%d db_access=%d", 00580 thd->security_ctx->master_access, thd->security_ctx->db_access)); 00581 00582 /* Signal the scheduler thread that we have started successfully */ 00583 pthread_mutex_lock(¶m->LOCK_started); 00584 param->started= TRUE; 00585 pthread_cond_signal(¶m->COND_started); 00586 pthread_mutex_unlock(¶m->LOCK_started); 00587 00588 if (!startup_error) 00589 { 00590 thd->init_for_queries(); 00591 thd->enable_slow_log= TRUE; 00592 00593 event->set_thread_id(thd->thread_id); 00594 sql_print_information("SCHEDULER: [%s.%s of %s] executing in thread %lu", 00595 event->dbname.str, event->name.str, 00596 event->definer.str, thd->thread_id); 00597 00598 ret= event->execute(thd, thd->mem_root); 00599 evex_print_warnings(thd, event); 00600 sql_print_information("SCHEDULER: [%s.%s of %s] executed. RetCode=%d", 00601 event->dbname.str, event->name.str, 00602 event->definer.str, ret); 00603 if (ret == EVEX_COMPILE_ERROR) 00604 sql_print_information("SCHEDULER: COMPILE ERROR for event %s.%s of %s", 00605 event->dbname.str, event->name.str, 00606 event->definer.str); 00607 else if (ret == EVEX_MICROSECOND_UNSUP) 00608 sql_print_information("SCHEDULER: MICROSECOND is not supported"); 00609 00610 DBUG_PRINT("info", ("master_access=%d db_access=%d", 00611 thd->security_ctx->master_access, thd->security_ctx->db_access)); 00612 00613 /* If true is returned, we are expected to free it */ 00614 if (event->spawn_thread_finish(thd)) 00615 { 00616 DBUG_PRINT("info", ("Freeing object pointer")); 00617 delete event; 00618 } 00619 } 00620 00621 if (thd) 00622 { 00623 thd->proc_info= "Clearing"; 00624 DBUG_ASSERT(thd->net.buff != 0); 00625 /* 00626 Free it here because net.vio is NULL for us => THD::~THD will check it 00627 and won't call net_end(&net); See also replication code. 00628 */ 00629 net_end(&thd->net); 00630 DBUG_PRINT("info", ("Worker thread %lu exiting", thd->thread_id)); 00631 VOID(pthread_mutex_lock(&LOCK_thread_count)); 00632 thread_count--; 00633 thread_running--; 00634 delete thd; 00635 VOID(pthread_mutex_unlock(&LOCK_thread_count)); 00636 } 00637 00638 my_thread_end(); 00639 DBUG_RETURN(0); // Can't return anything here 00640 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void evex_print_warnings | ( | THD * | thd, | |
| Event_timed * | et | |||
| ) | [static] |
Definition at line 344 of file event_scheduler.cc.
References String::append(), append_identifier(), String::c_ptr(), Event_timed::dbname, DBUG_ASSERT, DBUG_ENTER, DBUG_VOID_RETURN, Event_timed::definer_host, Event_timed::definer_user, err, LEX_STRING::length, String::length(), MYSQL_ERROR::level, MYSQL_ERROR::msg, msg_buf, Event_timed::name, sql_print_message_handlers, LEX_STRING::str, STRING_BUFFER_USUAL_SIZE, strlen(), and system_charset_info.
Referenced by event_worker_thread().
00345 { 00346 MYSQL_ERROR *err; 00347 DBUG_ENTER("evex_print_warnings"); 00348 if (!thd->warn_list.elements) 00349 DBUG_VOID_RETURN; 00350 00351 char msg_buf[10 * STRING_BUFFER_USUAL_SIZE]; 00352 char prefix_buf[5 * STRING_BUFFER_USUAL_SIZE]; 00353 String prefix(prefix_buf, sizeof(prefix_buf), system_charset_info); 00354 prefix.length(0); 00355 prefix.append("SCHEDULER: ["); 00356 00357 append_identifier(thd, &prefix, et->definer_user.str, et->definer_user.length); 00358 prefix.append('@'); 00359 append_identifier(thd, &prefix, et->definer_host.str, et->definer_host.length); 00360 prefix.append("][", 2); 00361 append_identifier(thd,&prefix, et->dbname.str, et->dbname.length); 00362 prefix.append('.'); 00363 append_identifier(thd,&prefix, et->name.str, et->name.length); 00364 prefix.append("] ", 2); 00365 00366 List_iterator_fast<MYSQL_ERROR> it(thd->warn_list); 00367 while ((err= it++)) 00368 { 00369 String err_msg(msg_buf, sizeof(msg_buf), system_charset_info); 00370 /* set it to 0 or we start adding at the end. That's the trick ;) */ 00371 err_msg.length(0); 00372 err_msg.append(prefix); 00373 err_msg.append(err->msg, strlen(err->msg), system_charset_info); 00374 err_msg.append("]"); 00375 DBUG_ASSERT(err->level < 3); 00376 (sql_print_message_handlers[err->level])("%*s", err_msg.length(), 00377 err_msg.c_ptr()); 00378 } 00379 DBUG_VOID_RETURN; 00380 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int init_event_thread | ( | THD ** | t, | |
| enum enum_thread_type | thread_type | |||
| ) | [static] |
Definition at line 400 of file event_scheduler.cc.
References CLIENT_MULTI_RESULTS, DBUG_ENTER, DBUG_RETURN, init_thr_lock(), LOCK_thread_count, my_localhost, my_net_init(), OPTION_AUTO_IS_NULL, pthread_mutex_lock, pthread_mutex_unlock, refresh_version, sigemptyset, slave_net_timeout, thread_count, thread_id, thread_running, threads, and VOID.
Referenced by event_scheduler_thread(), and event_worker_thread().
00401 { 00402 THD *thd= *t; 00403 thd->thread_stack= (char*)t; // remember where our stack is 00404 DBUG_ENTER("init_event_thread"); 00405 thd->client_capabilities= 0; 00406 thd->security_ctx->master_access= 0; 00407 thd->security_ctx->db_access= 0; 00408 thd->security_ctx->host_or_ip= (char*)my_localhost; 00409 my_net_init(&thd->net, 0); 00410 thd->net.read_timeout= slave_net_timeout; 00411 thd->slave_thread= 0; 00412 thd->options|= OPTION_AUTO_IS_NULL; 00413 thd->client_capabilities|= CLIENT_MULTI_RESULTS; 00414 thd->real_id=pthread_self(); 00415 VOID(pthread_mutex_lock(&LOCK_thread_count)); 00416 thd->thread_id= thread_id++; 00417 threads.append(thd); 00418 thread_count++; 00419 thread_running++; 00420 VOID(pthread_mutex_unlock(&LOCK_thread_count)); 00421 00422 if (init_thr_lock() || thd->store_globals()) 00423 { 00424 thd->cleanup(); 00425 DBUG_RETURN(-1); 00426 } 00427 00428 #if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) 00429 sigset_t set; 00430 VOID(sigemptyset(&set)); // Get mask in use 00431 VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals)); 00432 #endif 00433 00434 /* 00435 Guarantees that we will see the thread in SHOW PROCESSLIST though its 00436 vio is NULL. 00437 */ 00438 thd->system_thread= thread_type; 00439 00440 thd->proc_info= "Initialized"; 00441 thd->version= refresh_version; 00442 thd->set_time(); 00443 00444 DBUG_RETURN(0); 00445 }
Here is the call graph for this function:

Here is the caller graph for this function:

| pthread_attr_t connection_attrib |
Definition at line 590 of file mysqld.cc.
Referenced by delayed_get_table(), and Event_timed::spawn_now().
LEX_STRING states_names[] [static] |
Initial value:
{
{(char*) STRING_WITH_LEN("UNINITIALIZED")},
{(char*) STRING_WITH_LEN("INITIALIZED")},
{(char*) STRING_WITH_LEN("COMMENCING")},
{(char*) STRING_WITH_LEN("CANTSTART")},
{(char*) STRING_WITH_LEN("RUNNING")},
{(char*) STRING_WITH_LEN("SUSPENDED")},
{(char*) STRING_WITH_LEN("IN_SHUTDOWN")}
}
Definition at line 255 of file event_scheduler.cc.
Referenced by Event_scheduler::check_n_wait_for_non_empty_queue(), and Event_scheduler::dump_internal_status().
1.4.7

