YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense alongwiththisprogram;ifnot,writetotheFreeSoftware
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
expr= tmp_expr - (tmp_expr/60)*60; /* the code after the switch will finish */ break;
} case INTERVAL_DAY_MICROSECOND: case INTERVAL_HOUR_MICROSECOND: case INTERVAL_MINUTE_MICROSECOND: case INTERVAL_SECOND_MICROSECOND: case INTERVAL_MICROSECOND:
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND"); return1; case INTERVAL_QUARTER:
expr/= 3;
close_quote= FALSE; break; case INTERVAL_WEEK:
expr/= 7;
close_quote= FALSE; break; default:
close_quote= FALSE; break;
} if (close_quote)
buf->append(separator);
end= longlong10_to_str(expr, tmp_buff, 10);
buf->append(tmp_buff, (uint) (end- tmp_buff)); if (close_quote)
buf->append('\'');
@return 0ok 1error
*/ staticint
create_query_string(THD *thd, String *buf)
{
buf->length(0); /* Append the "CREATE" part of the query */ if (thd->lex->create_info.or_replace())
{ if (buf->append(STRING_WITH_LEN("CREATE OR REPLACE "))) return1;
} elseif (buf->append(STRING_WITH_LEN("CREATE "))) return1; /* Append definer */
append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host)); /* Append the left part of thd->query after "DEFINER" part */ if (buf->append(thd->lex->stmt_definition_begin,
thd->lex->stmt_definition_end -
thd->lex->stmt_definition_begin)) return1;
if (lock_object_name(thd, MDL_key::EVENT,
parse_data->dbname, parse_data->name))
DBUG_RETURN(TRUE);
if (check_db_dir_existence(parse_data->dbname.str))
{
my_error(ER_BAD_DB_ERROR, MYF(0), parse_data->dbname.str);
DBUG_RETURN(TRUE);
}
if (parse_data->do_not_create)
DBUG_RETURN(FALSE); /* Turnoffrowbinloggingofthisstatementandusestatement-based sothatallsupportingtablesareupdatedforCREATEEVENTcommand.
*/
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
if (thd->lex->create_info.or_replace() && event_queue)
event_queue->drop_event(thd, &parse_data->dbname, &parse_data->name);
/* On error conditions my_error() is called so no need to handle here */ if (!(ret= db_repository->create_event(thd, parse_data,
&event_already_exists)))
{
Event_queue_element *new_element; bool dropped= 0;
if (!event_already_exists)
{ if (!(new_element= new Event_queue_element()))
ret= TRUE; // OOM elseif ((ret= db_repository->load_named_event(thd, &parse_data->dbname,
&parse_data->name,
new_element)))
{ if (!db_repository->drop_event(thd, &parse_data->dbname,
&parse_data->name, TRUE))
dropped= 1; delete new_element;
} else
{ /* TODO: do not ignore the out parameter and a possible OOM error! */ bool created; if (event_queue)
event_queue->create_event(thd, new_element, &created);
}
} /* binlogthecreateeventunlessit'sbeensuccessfullydropped
*/ if (!dropped)
{ /* Binlog the create event. */
DBUG_ASSERT(thd->query() && thd->query_length()); char buffer[1024];
String log_query(buffer, sizeof(buffer), &my_charset_bin); if (create_query_string(thd, &log_query))
ret= true; // EE_OUTOFMEMORY set by my_malloc() else
{ /* IfthedefinerisnotsetorsettoCURRENT_USER,thevalue ofCURRENT_USERwillbewrittenintothebinarylogasthe definerfortheSQLthread.
*/
ret= write_bin_log(thd, TRUE, log_query.ptr(), log_query.length());
}
}
}
if (!ret && Events::opt_event_scheduler == Events::EVENTS_OFF)
{
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, "Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it.");
}
if (lock_object_name(thd, MDL_key::EVENT,
parse_data->dbname, parse_data->name))
DBUG_RETURN(TRUE);
if (check_db_dir_existence(parse_data->dbname.str))
{
my_error(ER_BAD_DB_ERROR, MYF(0), parse_data->dbname.str);
DBUG_RETURN(TRUE);
}
if (new_dbname) /* It's a rename */
{ /* Check that the new and the old names differ. */ if ( !sortcmp_lex_string(&parse_data->dbname, new_dbname,
system_charset_info) &&
!sortcmp_lex_string(&parse_data->name, new_name,
system_charset_info))
{
my_error(ER_EVENT_SAME_NAME, MYF(0));
DBUG_RETURN(TRUE);
}
/* On error conditions my_error() is called so no need to handle here */ if (!(ret= db_repository->update_event(thd, parse_data,
new_dbname, new_name)))
{
LEX_CSTRING dbname= new_dbname ? *new_dbname : parse_data->dbname;
LEX_CSTRING name= new_name ? *new_name : parse_data->name;
if (!(new_element= new Event_queue_element()))
ret= TRUE; // OOM elseif ((ret= db_repository->load_named_event(thd, &dbname, &name,
new_element))) delete new_element; else
{ /* TODO:checkifanupdateactuallyhasinsertedanentry intothequeue. Ifnot,andtheelementisONCOMPLETIONNOTPRESERVE,delete itrightaway.
*/ if (event_queue)
event_queue->update_event(thd, &parse_data->dbname, &parse_data->name,
new_element); /* Binlog the alter event. */
DBUG_ASSERT(thd->query() && thd->query_length());
ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
}
if (lock_object_name(thd, MDL_key::EVENT, *dbname, *name))
DBUG_RETURN(TRUE); /* On error conditions my_error() is called so no need to handle here */ if (!(ret= db_repository->drop_event(thd, dbname, name, if_exists)))
{ if (event_queue)
event_queue->drop_event(thd, dbname, name); /* Binlog the drop event. */
DBUG_ASSERT(thd->query() && thd->query_length());
ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); /* Drop statistics for this stored program from performance schema. */
MYSQL_DROP_SP(SP_TYPE_EVENT,
dbname->str, static_cast<uint>(dbname->length), name->str, static_cast<uint>(name->length));
}
/* Wasdisabledexplicitlyfromthecommandline
*/ if (opt_event_scheduler == Events::EVENTS_DISABLED || opt_bootstrap)
DBUG_RETURN(FALSE); if (opt_noacl_or_bootstrap)
{ if (opt_event_scheduler == Events::EVENTS_ON)
sql_print_error("Event Scheduler will not function when starting with %s",
opt_bootstrap ? "--bootstrap" : "--skip-grant-tables");
opt_event_scheduler= EVENTS_DISABLED;
DBUG_RETURN(FALSE);
}
/* We need a temporary THD during boot */ if (!thd)
{ if (!(thd= new THD(0)))
{
res= TRUE; goto end;
}
thd->store_globals();
thd->set_query_inner((char*) STRING_WITH_LEN("intern:Events::init"),
default_charset_info); /* Setcurrenttimeforthethreadthathandlesevents. Currenttimeisstoredindatamemberstart_timeofTHDclass. Subsequently,thisvalueisusedtocheckwhethereventwasexpired whenmakeloadingeventsfromstorage.Checkforeventexpirationtime isdoneatEvent_queue_element::compute_next_execution_time()where event'sstatussettoEvent_parse_data::DISABLEDanddroppedflagset totrueifeventwasexpired.
*/
thd->set_time();
}
Ifrunwith--skip-grant-tablesor--bootstrap,wehavealready disabledtheeventscheduleranyway.
*/ if (Event_db_repository::check_system_tables(thd))
{ delete db_repository;
db_repository= 0;
my_message(ER_STARTUP, "Event Scheduler: An error occurred when initializing " "system tables. Disabling the Event Scheduler.",
MYF(ME_ERROR_LOG)); /* Disable the scheduler since the system tables are not up to date */
opt_event_scheduler= EVENTS_OFF; goto end;
}
PSI_stage_info stage_waiting_on_empty_queue= { 0, "Waiting on empty queue", 0};
PSI_stage_info stage_waiting_for_next_activation= { 0, "Waiting for next activation", 0};
PSI_stage_info stage_waiting_for_scheduler_to_stop= { 0, "Waiting for the scheduler to stop", 0};
void
Events::dump_internal_status()
{
DBUG_ENTER("Events::dump_internal_status");
puts("\n\n\nEvents status:");
puts("LLA = Last Locked At LUA = Last Unlocked At");
puts("WOC = Waiting On Condition DL = Data Locked");
/* opt_event_schedulershouldonlybeaccessedwhile holdingLOCK_global_system_variables.
*/
mysql_mutex_lock(&LOCK_global_system_variables); if (!inited)
puts("The Event Scheduler is disabled"); else
{
scheduler->dump_internal_status();
event_queue->dump_internal_status();
}
while (!(read_record_info.read_record()))
{
Event_queue_element *et; bool created, dropped;
if (!(et= new Event_queue_element)) goto end;
DBUG_PRINT("info", ("Loading event from row."));
if (et->load_from_row(thd, table))
{
my_message(ER_STARTUP, "Event Scheduler: " "Error while loading events from mysql.event. " "The table probably contains bad data or is corrupted",
MYF(ME_ERROR_LOG)); delete et; goto end;
}
/* All the dmls to mysql.events tables are stmt bin-logged. */
table->file->row_logging= 0;
(void) table->file->ha_update_row(table->record[1], table->record[0]);
delete et; continue;
} #endif/* WITH_WSREP */
/** SincetheEvent_queue_elementobjectcouldbedeletedinside Event_queue::create_eventweshouldsavethevalueofdroppedflag intothetemporaryvariable.
*/
dropped= et->dropped; if (event_queue->create_event(thd, et, &created))
{ /* Out of memory */ delete et; goto end;
} if (created)
count++; elseif (dropped)
{ /* Ifnotcreated,astaleevent-dropifimmediatelyif ONCOMPLETIONNOTPRESERVE. XXX:Thiswon'tbereplicated,thusthedropwon'tappearin intheslave.Whentheslaveisrestarteditwilldropevents. However,astheslavewillbe"outofsync",itmighthappenthat aneventcreatedonthemaster,aftermasterrestart,won'tbe replicatedtotheslavecorrectly,asthecreatewillfailthere.
*/ int rc= table->file->ha_delete_row(table->record[0]); if (rc)
{
table->file->print_error(rc, MYF(0)); goto end;
}
}
}
my_printf_error(ER_STARTUP, "Event Scheduler: Loaded %d event%s",
MYF(ME_ERROR_LOG | ME_NOTE),
count, (count == 1) ? "" : "s");
ret= FALSE;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.