diff --git a/sql/event.cc b/sql/event.cc index 36180adb90f..56e93ac7c33 100644 --- a/sql/event.cc +++ b/sql/event.cc @@ -27,8 +27,6 @@ - Use timestamps instead of datetime. - - Don't use SP's functionality for opening and closing of tables - - CREATE EVENT should not go into binary log! Does it now? The SQL statements issued by the EVENT are replicated. I have an idea how to solve the problem at failover. So the status field @@ -44,31 +42,16 @@ ENABLED to DISABLED status change and this is safe for replicating. As well an event may be deleted which is also safe for RBR. - - Add a lock and use it for guarding access to events_array dynamic array. - - - Add checks everywhere where new instance of THD is created. NULL can be - returned and this will crash the server. The server will crash probably - later but should not be in this code! Add a global variable, and a lock - to guard it, that will specify an error in a worker thread so preventing - new threads from being spawned. - - Maybe move all allocations during parsing to evex_mem_root thus saving double parsing in evex_create_event! - If the server is killed (stopping) try to kill executing events.. - What happens if one renames an event in the DB while it is in memory? - Or even deleting it? - - - created & modified in the table should be UTC? - - - Add a lock to event_timed to serialize execution of an event - do not - allow parallel executions. Hmm, however how last_executed is marked - then? The call to event_timed::mark_last_executed() must be moved to - event_timed::execute()? - + Or even deleting it? + - Consider using conditional variable when doing shutdown instead of - waiting some time (tries < 5). + waiting till all worker threads end. - Make event_timed::get_show_create_event() work - Add function documentation whenever needed. - Add logging to file @@ -77,7 +60,7 @@ Warning: - For now parallel execution is not possible because the same sp_head cannot be executed few times!!! There is still no lock attached to particular event. - */ +*/ @@ -216,17 +199,17 @@ TABLE *evex_open_event_table(THD *thd, enum thr_lock_type lock_type) table TABLE object for open mysql.event table. RETURN VALUE - SP_OK - Routine found + 0 - Routine found SP_KEY_NOT_FOUND- No routine with given name */ int evex_db_find_routine_aux(THD *thd, const LEX_STRING dbname, - const LEX_STRING rname, TABLE *table) + const LEX_STRING ev_name, TABLE *table) { byte key[MAX_KEY_LENGTH]; // db, name, optional key length type DBUG_ENTER("evex_db_find_routine_aux"); - DBUG_PRINT("enter", ("name: %.*s", rname.length, rname.str)); + DBUG_PRINT("enter", ("name: %.*s", ev_name.length, ev_name.str)); /* Create key to find row. We have to use field->store() to be able to @@ -235,16 +218,16 @@ evex_db_find_routine_aux(THD *thd, const LEX_STRING dbname, 'db' and 'name' and the first key is the primary key over the same fields. */ - if (rname.length > table->field[1]->field_length) - DBUG_RETURN(SP_KEY_NOT_FOUND); + if (ev_name.length > table->field[1]->field_length) + DBUG_RETURN(EVEX_KEY_NOT_FOUND); table->field[0]->store(dbname.str, dbname.length, &my_charset_bin); - table->field[1]->store(rname.str, rname.length, &my_charset_bin); + table->field[1]->store(ev_name.str, ev_name.length, &my_charset_bin); key_copy(key, table->record[0], table->key_info, table->key_info->key_length); if (table->file->index_read_idx(table->record[0], 0, key, - table->key_info->key_length,HA_READ_KEY_EXACT)) - DBUG_RETURN(SP_KEY_NOT_FOUND); + table->key_info->key_length,HA_READ_KEY_EXACT)) + DBUG_RETURN(EVEX_KEY_NOT_FOUND); DBUG_RETURN(0); } @@ -394,19 +377,18 @@ db_create_event(THD *thd, event_timed *et) restore_record(table, s->default_values); // Get default values for fields -/* TODO : Uncomment these and add handling in sql_parse.cc or here - if (sp->m_name.length > table->field[MYSQL_PROC_FIELD_NAME]->field_length) + if (et->m_name.length > table->field[EVEX_FIELD_NAME]->field_length) { - ret= SP_BAD_IDENTIFIER; - goto done; + my_error(ER_TOO_LONG_IDENT, MYF(0), et->m_name.str); + goto err; } - if (sp->m_body.length > table->field[MYSQL_PROC_FIELD_BODY]->field_length) + if (et->m_body.length > table->field[EVEX_FIELD_BODY]->field_length) { - ret= SP_BODY_TOO_LONG; - goto done; + my_error(ER_TOO_LONG_BODY, MYF(0), et->m_name.str); + goto err; } -*/ + if (!(et->m_expr) && !(et->m_execute_at.year)) { DBUG_PRINT("error", ("neither m_expr nor m_execute_as are set!")); @@ -434,7 +416,8 @@ db_create_event(THD *thd, event_timed *et) my_error(ER_EVENT_STORE_FAILED, MYF(0), et->m_name.str); goto err; } - else if (mysql_bin_log.is_open()) + + if (mysql_bin_log.is_open()) { thd->clear_error(); /* Such a statement can always go directly to binlog, no trans cache */ @@ -472,20 +455,20 @@ static int db_update_event(THD *thd, sp_name *name, event_timed *et) { TABLE *table; - int ret; + int ret= EVEX_OPEN_TABLE_FAILED; DBUG_ENTER("db_update_event"); DBUG_PRINT("enter", ("name: %.*s", et->m_name.length, et->m_name.str)); if (name) DBUG_PRINT("enter", ("rename to: %.*s", name->m_name.length, name->m_name.str)); - // Todo: Handle in sql_prepare.cc SP_OPEN_TABLE_FAILED if (!(table= evex_open_event_table(thd, TL_WRITE))) { my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0)); goto err; } - if (evex_db_find_routine_aux(thd, et->m_db, et->m_name, table) == SP_KEY_NOT_FOUND) + if (EVEX_KEY_NOT_FOUND == evex_db_find_routine_aux(thd, et->m_db, et->m_name, + table)) { my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->m_name.str); goto err; @@ -526,8 +509,21 @@ err: /* - Use sp_name for look up, return in **ett if found + Looks for a named event in mysql.event and in case of success returns + an object will data loaded from the table. + + SYNOPSIS + db_find_event() + thd THD + name the name of the event to find + ett event's data if event is found + tbl TABLE object to use when not NULL + + NOTES + 1) Use sp_name for look up, return in **ett if found + 2) tbl is not closed at exit */ + static int db_find_event(THD *thd, sp_name *name, event_timed **ett, TABLE *tbl) { @@ -581,6 +577,22 @@ done: } +/* + Looks for a named event in mysql.event and then loads it from + the table, compiles it and insert it into the cache. + + SYNOPSIS + evex_load_and_compile_event() + thd THD + spn the name of the event to alter + use_lock whether to obtain a lock on LOCK_event_arrays or not + + RETURN VALUE + 0 - OK + < 0 - error (in this case underlying functions call my_error()). + +*/ + static int evex_load_and_compile_event(THD * thd, sp_name *spn, bool use_lock) { @@ -727,7 +739,7 @@ done: /* - Exported functions follow + -= Exported functions follow =- */ /* @@ -754,15 +766,6 @@ evex_create_event(THD *thd, event_timed *et, uint create_options) DBUG_PRINT("enter", ("name: %*s options:%d", et->m_name.length, et->m_name.str, create_options)); -/* - VOID(pthread_mutex_lock(&LOCK_evex_running)); - if (!evex_is_running) - // TODO: put an warning to the user here. - // Is it needed? (Andrey, 051129) - {} - VOID(pthread_mutex_unlock(&LOCK_evex_running)); -*/ - if ((ret = db_create_event(thd, et)) == EVEX_WRITE_ROW_FAILED && (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) { @@ -821,13 +824,6 @@ evex_update_event(THD *thd, sp_name *name, event_timed *et) DBUG_ENTER("evex_update_event"); DBUG_PRINT("enter", ("name: %*s", et->m_name.length, et->m_name.str)); -/* - VOID(pthread_mutex_lock(&LOCK_evex_running)); - if (!evex_is_running) - // put an warning to the user here - {} - VOID(pthread_mutex_unlock(&LOCK_evex_running)); -*/ /* db_update_event() opens & closes the table to prevent crash later in the code when loading and compiling the new definition @@ -837,17 +833,8 @@ evex_update_event(THD *thd, sp_name *name, event_timed *et) VOID(pthread_mutex_lock(&LOCK_evex_running)); if (!evex_is_running) - { - // not running - therefore no memory structures - VOID(pthread_mutex_unlock(&LOCK_evex_running)); - goto done; - } - VOID(pthread_mutex_unlock(&LOCK_evex_running)); + UNLOCK_MUTEX_AND_BAIL_OUT(LOCK_evex_running, done); - /* - It is possible that 2 (or 1) pass(es) won't find the event in memory. - The reason is that DISABLED events are not cached. - */ VOID(pthread_mutex_lock(&LOCK_event_arrays)); evex_remove_from_cache(&et->m_db, &et->m_name, false); if (et->m_status == MYSQL_EVENT_ENABLED) @@ -860,9 +847,14 @@ evex_update_event(THD *thd, sp_name *name, event_timed *et) delete spn; } VOID(pthread_mutex_unlock(&LOCK_event_arrays)); + VOID(pthread_mutex_unlock(&LOCK_evex_running)); + + /* + It is possible that 2 (or 1) pass(es) won't find the event in memory. + The reason is that DISABLED events are not cached. + */ done: - DBUG_RETURN(ret); } @@ -882,24 +874,17 @@ int evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists) { TABLE *table; - int ret; + int ret= EVEX_OPEN_TABLE_FAILED; bool opened; DBUG_ENTER("evex_drop_event"); -/* - VOID(pthread_mutex_lock(&LOCK_evex_running)); - if (!evex_is_running) - // put an warning to the user here - {} - VOID(pthread_mutex_unlock(&LOCK_evex_running)); -*/ -//// if (!(table= evex_open_event_table(thd, TL_WRITE))) - DBUG_RETURN(SP_OPEN_TABLE_FAILED); + { + my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0)); + goto done; + } - ret= evex_db_find_routine_aux(thd, et->m_db, et->m_name, table); - - if (ret == EVEX_OK) + if (!(ret= evex_db_find_routine_aux(thd, et->m_db, et->m_name, table))) { if (ret= table->file->delete_row(table->record[0])) { diff --git a/sql/event_executor.cc b/sql/event_executor.cc index 763f440df64..90c08d045db 100644 --- a/sql/event_executor.cc +++ b/sql/event_executor.cc @@ -21,7 +21,7 @@ #define DBUG_FAULTY_THR2 -static uint workers_count; +extern ulong thread_created; pthread_mutex_t LOCK_event_arrays, @@ -33,10 +33,8 @@ bool evex_is_running= false; ulong opt_event_executor; my_bool event_executor_running_global_var= false; - -extern ulong thread_created; - static my_bool evex_mutexes_initted= false; +static uint workers_count; static int evex_load_events_from_db(THD *thd); @@ -48,8 +46,11 @@ evex_load_events_from_db(THD *thd); the main thread or not. */ -pthread_handler_t event_executor_worker(void *arg); -pthread_handler_t event_executor_main(void *arg); +pthread_handler_t +event_executor_worker(void *arg); + +pthread_handler_t +event_executor_main(void *arg); static void evex_init_mutexes() @@ -142,8 +143,8 @@ init_event_thread(THD* thd) DBUG_RETURN(0); } - -pthread_handler_t event_executor_main(void *arg) +pthread_handler_t +event_executor_main(void *arg) { THD *thd; /* needs to be first for thread_stack */ ulonglong iter_num= 0; @@ -152,13 +153,10 @@ pthread_handler_t event_executor_main(void *arg) DBUG_ENTER("event_executor_main"); DBUG_PRINT("event_executor_main", ("EVEX thread started")); - VOID(pthread_mutex_lock(&LOCK_evex_running)); - evex_is_running= true; - event_executor_running_global_var= opt_event_executor; - VOID(pthread_mutex_unlock(&LOCK_evex_running)); // init memory root init_alloc_root(&evex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff my_thread_init(); @@ -196,6 +194,15 @@ pthread_handler_t event_executor_main(void *arg) VOID(my_init_dynamic_array(&evex_executing_queue, sizeof(event_timed *), 50, 100)); VOID(pthread_mutex_unlock(&LOCK_event_arrays)); + /* + eventually manifest that we are running, not to crashe because of + usage of non-initialized memory structures. + */ + VOID(pthread_mutex_lock(&LOCK_evex_running)); + evex_is_running= true; + event_executor_running_global_var= opt_event_executor; + VOID(pthread_mutex_unlock(&LOCK_evex_running)); + if (evex_load_events_from_db(thd)) goto err; @@ -208,7 +215,6 @@ pthread_handler_t event_executor_main(void *arg) my_ulonglong cnt; DBUG_PRINT("info", ("EVEX External Loop %d", ++cnt)); -// sql_print_information("[EVEX] External Loop!"); thd->proc_info = "Sleeping"; my_sleep(1000000);// sleep 1s if (!event_executor_running_global_var) @@ -216,16 +222,13 @@ pthread_handler_t event_executor_main(void *arg) time(&now); my_tz_UTC->gmt_sec_to_TIME(&time_now, now); - VOID(pthread_mutex_lock(&LOCK_event_arrays)); for (i= 0; (i < evex_executing_queue.elements) && !thd->killed; ++i) { - event_timed **p_et=dynamic_element(&evex_executing_queue,i,event_timed**); - event_timed *et= *p_et; -// sql_print_information("[EVEX] External Loop 2!"); - + event_timed *et= *dynamic_element(&evex_executing_queue,i,event_timed**); +// printf("%llu\n", TIME_to_ulonglong_datetime(&et->m_execute_at)); if (!event_executor_running_global_var) - break;// soon we will do only continue (see the code a bit above) + break; thd->proc_info = "Iterating"; THD_CHECK_SENTRY(thd); @@ -233,7 +236,7 @@ pthread_handler_t event_executor_main(void *arg) if this is the first event which is after time_now then no more need to iterate over more elements since the array is sorted. */ - if (et->m_execute_at.year && + if (et->m_execute_at.year > 1969 && my_time_compare(&time_now, &et->m_execute_at) == -1) break; @@ -250,8 +253,7 @@ pthread_handler_t event_executor_main(void *arg) if (pthread_create(&th, NULL, event_executor_worker, (void*)et)) { sql_print_error("Problem while trying to create a thread"); - VOID(pthread_mutex_unlock(&LOCK_event_arrays)); - goto err; // for now finish execution of the Executor + UNLOCK_MUTEX_AND_BAIL_OUT(LOCK_event_arrays, err); } #else event_executor_worker((void *) et); @@ -272,12 +274,12 @@ pthread_handler_t event_executor_main(void *arg) j= 0; while (j < i && j < evex_executing_queue.elements) { - event_timed **p_et= dynamic_element(&evex_executing_queue, j, event_timed**); - event_timed *et= *p_et; + event_timed *et= *dynamic_element(&evex_executing_queue, j, event_timed**); if (et->m_flags & EVENT_EXEC_NO_MORE || et->m_status == MYSQL_EVENT_DISABLED) { delete_dynamic_element(&evex_executing_queue, j); - DBUG_PRINT("", ("DELETING FROM EXECUTION QUEUE [%s.%s]",et->m_db.str, et->m_name.str)); + DBUG_PRINT("EVEX main thread", ("DELETING FROM EXECUTION QUEUE [%s.%s]", + et->m_db.str, et->m_name.str)); // nulling the position, will delete later if (et->m_dropped) { @@ -301,29 +303,44 @@ pthread_handler_t event_executor_main(void *arg) ); VOID(pthread_mutex_unlock(&LOCK_event_arrays)); - }// while (!thd->killed) + } err: + // First manifest that this thread does not work and then destroy VOID(pthread_mutex_lock(&LOCK_evex_running)); evex_is_running= false; VOID(pthread_mutex_unlock(&LOCK_evex_running)); sql_print_information("Event executor stopping"); - // LEX_STRINGs reside in the memory root and will be destroyed with it. - // Hence no need of delete but only freeing of SP - for (i=0; i < events_array.elements; ++i) - { - event_timed *et= dynamic_element(&events_array, i, event_timed*); - et->free_sp(); - } - // TODO Andrey: USE lock here! + + /* + TODO: A better will be with a conditional variable + */ + /* + Read workers_count without lock, no need for locking. + In the worst case we have to wait 1sec more. + */ + while (workers_count) + my_sleep(1000000);// 1s + + /* + LEX_STRINGs reside in the memory root and will be destroyed with it. + Hence no need of delete but only freeing of SP + */ + for (i= 0; i < events_array.elements; ++i) + dynamic_element(&events_array, i, event_timed*)->free_sp(); + + VOID(pthread_mutex_lock(&LOCK_event_arrays)); + // No need to use lock here if EVEX is not running but anyway delete_dynamic(&evex_executing_queue); delete_dynamic(&events_array); + VOID(pthread_mutex_unlock(&LOCK_evex_running)); thd->proc_info = "Clearing"; DBUG_ASSERT(thd->net.buff != 0); net_end(&thd->net); // destructor will not free it, because we are weird THD_CHECK_SENTRY(thd); + pthread_mutex_lock(&LOCK_thread_count); thread_count--; thread_running--; @@ -331,28 +348,6 @@ err: delete thd; pthread_mutex_unlock(&LOCK_thread_count); - /* - sleeping some time may help not crash the server. sleeping - is done to wait for spawned threads to finish. - - TODO: A better will be with a conditional variable - */ - { - uint tries= 0; - while (tries++ < 5) - { - VOID(pthread_mutex_lock(&LOCK_workers_count)); - if (!workers_count) - { - VOID(pthread_mutex_unlock(&LOCK_workers_count)); - break; - } - VOID(pthread_mutex_unlock(&LOCK_workers_count)); - DBUG_PRINT("info", ("Sleep %d", tries)); - my_sleep(1000000 * tries);// 1s - } - DBUG_PRINT("info", ("Maybe now it is ok to kill the thread and evex MRoot")); - } err_no_thd: VOID(pthread_mutex_lock(&LOCK_evex_running)); @@ -362,30 +357,25 @@ err_no_thd: free_root(&evex_mem_root, MYF(0)); sql_print_information("Event executor stopped"); -// shutdown_events(); - my_thread_end(); pthread_exit(0); - DBUG_RETURN(0); // Can't return anything here + DBUG_RETURN(0);// Can't return anything here } -pthread_handler_t event_executor_worker(void *event_void) +pthread_handler_t +event_executor_worker(void *event_void) { THD *thd; /* needs to be first for thread_stack */ - List empty_item_list; event_timed *event = (event_timed *) event_void; - MEM_ROOT mem_root; + MEM_ROOT worker_mem_root; DBUG_ENTER("event_executor_worker"); VOID(pthread_mutex_lock(&LOCK_workers_count)); ++workers_count; VOID(pthread_mutex_unlock(&LOCK_workers_count)); - init_alloc_root(&mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); - - //we pass this empty list as parameter to the SP_HEAD of the event - empty_item_list.empty(); + init_alloc_root(&worker_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); my_thread_init(); @@ -395,8 +385,10 @@ pthread_handler_t event_executor_worker(void *event_void) goto err_no_thd; } thd->thread_stack = (char*)&thd; // remember where our stack is - thd->mem_root= &mem_root; + thd->mem_root= &worker_mem_root; + pthread_detach(pthread_self()); + if (init_event_thread(thd)) goto err; @@ -425,7 +417,7 @@ pthread_handler_t event_executor_worker(void *event_void) my_TIME_to_str(&event->m_execute_at, exec_time); DBUG_PRINT("info", (" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time)); sql_print_information(" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time); - ret= event->execute(thd, &mem_root); + ret= event->execute(thd, &worker_mem_root); sql_print_information(" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]. RetCode=%d", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time, ret); DBUG_PRINT("info", (" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time)); } @@ -454,8 +446,7 @@ err: err_no_thd: - free_root(&mem_root, MYF(0)); -// sql_print_information(" Worker thread exiting"); + free_root(&worker_mem_root, MYF(0)); VOID(pthread_mutex_lock(&LOCK_workers_count)); --workers_count; @@ -496,29 +487,38 @@ evex_load_events_from_db(THD *thd) } DBUG_PRINT("evex_load_events_from_db", ("Loading event from row.")); - if (et->load_from_row(&evex_mem_root, table)) - //error loading! - continue; + if ((ret= et->load_from_row(&evex_mem_root, table))) + { + sql_print_error("Error while loading from mysql.event. " + "Table probably corrupted"); + goto end; + } DBUG_PRINT("evex_load_events_from_db", ("Event %s loaded from row. Time to compile", et->m_name.str)); - if (et->compile(thd, &evex_mem_root)) - //problem during compile - continue; + if ((ret= et->compile(thd, &evex_mem_root))) + { + sql_print_error("Error while compiling %s.%s. Aborting load.", + et->m_db.str, et->m_name.str); + goto end; + } // let's find when to be executed et->compute_next_execution_time(); DBUG_PRINT("evex_load_events_from_db", ("Adding %s to the executor list.", et->m_name.str)); VOID(push_dynamic(&events_array,(gptr) et)); - // we always add at the end so the number of elements - 1 is the place - // in the buffer + /* + We always add at the end so the number of elements - 1 is the place + in the buffer. + DYNAMIC_ARRAY copies the object bit by bit so we have a hollow copy + in event_array. We don't need the original therefore we delete it. + */ et_copy= dynamic_element(&events_array, events_array.elements - 1, - event_timed*); + event_timed*); VOID(push_dynamic(&evex_executing_queue,(gptr) &et_copy)); et->m_free_sphead_on_delete= false; - DBUG_PRINT("info", ("")); delete et; } end_read_record(&read_record_info); @@ -536,8 +536,7 @@ evex_load_events_from_db(THD *thd) end: close_thread_tables(thd); - DBUG_PRINT("evex_load_events_from_db", - ("Events loaded from DB. Status code %d", ret)); + DBUG_PRINT("info", ("Finishing with status code %d", ret)); DBUG_RETURN(ret); } @@ -547,7 +546,8 @@ bool sys_var_event_executor::update(THD *thd, set_var *var) { // here start the thread if not running. VOID(pthread_mutex_lock(&LOCK_evex_running)); - if ((my_bool) var->save_result.ulong_value && !evex_is_running) { + if ((my_bool) var->save_result.ulong_value && !evex_is_running) + { VOID(pthread_mutex_unlock(&LOCK_evex_running)); init_events(); } else diff --git a/sql/event_priv.h b/sql/event_priv.h index 73618d1b44a..f377a012e19 100644 --- a/sql/event_priv.h +++ b/sql/event_priv.h @@ -18,6 +18,9 @@ #define _EVENT_PRIV_H_ +#define UNLOCK_MUTEX_AND_BAIL_OUT(__mutex, __label) \ + { VOID(pthread_mutex_unlock(&__mutex)); goto __label; } + enum { EVEX_FIELD_DB = 0, diff --git a/sql/event_timed.cc b/sql/event_timed.cc index 45314dc9dbc..b986e650a13 100644 --- a/sql/event_timed.cc +++ b/sql/event_timed.cc @@ -290,7 +290,7 @@ event_timed::init_ends(THD *thd, Item *ends) if (ends->fix_fields(thd, &ends)) DBUG_RETURN(EVEX_PARSE_ERROR); - // the field was already fixed in init_ends + // the field was already fixed in init_ends if ((not_used= ends->get_date(<ime, TIME_NO_ZERO_DATE))) DBUG_RETURN(EVEX_BAD_PARAMS); @@ -537,10 +537,19 @@ event_timed::compute_next_execution_time() my_tz_UTC->gmt_sec_to_TIME(&time_now, now); /* sql_print_information("[%s.%s]", m_db.str, m_name.str); - sql_print_information("time_now : [%d-%d-%d %d:%d:%d ]", time_now.year, time_now.month, time_now.day, time_now.hour, time_now.minute, time_now.second); - sql_print_information("m_starts : [%d-%d-%d %d:%d:%d ]", m_starts.year, m_starts.month, m_starts.day, m_starts.hour, m_starts.minute, m_starts.second); - sql_print_information("m_ends : [%d-%d-%d %d:%d:%d ]", m_ends.year, m_ends.month, m_ends.day, m_ends.hour, m_ends.minute, m_ends.second); - sql_print_information("m_last_ex: [%d-%d-%d %d:%d:%d ]", m_last_executed.year, m_last_executed.month, m_last_executed.day, m_last_executed.hour, m_last_executed.minute, m_last_executed.second); + sql_print_information("time_now : [%d-%d-%d %d:%d:%d ]", + time_now.year, time_now.month, time_now.day, + time_now.hour, time_now.minute, time_now.second); + sql_print_information("m_starts : [%d-%d-%d %d:%d:%d ]", m_starts.year, + m_starts.month, m_starts.day, m_starts.hour, + m_starts.minute, m_starts.second); + sql_print_information("m_ends : [%d-%d-%d %d:%d:%d ]", m_ends.year, + m_ends.month, m_ends.day, m_ends.hour, + m_ends.minute, m_ends.second); + sql_print_information("m_last_ex: [%d-%d-%d %d:%d:%d ]", m_last_executed.year, + m_last_executed.month, m_last_executed.day, + m_last_executed.hour, m_last_executed.minute, + m_last_executed.second); */ //if time_now is after m_ends don't execute anymore if (m_ends.year && (tmp= my_time_compare(&m_ends, &time_now)) == -1) @@ -702,7 +711,6 @@ event_timed::mark_last_executed() bool event_timed::drop(THD *thd) { - return (bool) evex_drop_event(thd, this, false); }