Commit 185a3192 authored by unknown's avatar unknown
Browse files

fix for bug #19170 (Event creation leads to 100% CPU usage)


sql/event_timed.cc:
  - fix 100% cpu usage problem. If time_now==last_exec then don't schedule
    the event for time_now but increase the multiplier
  - if time_now is between STARTS and ENDS (the latter is set) or after STARTS
    (ENDS is not set) and there was no previous execution (imagine disabled
    scheduler being started) then don't schedule for time_now but for STARTS
    and then get_next_time() will find the correct time.
parent 365b9d4e
Loading
Loading
Loading
Loading
+17 −14
Original line number Diff line number Diff line
@@ -731,7 +731,9 @@ bool get_next_time(TIME *next, TIME *start, TIME *time_now, TIME *last_exec,
      get the next exec if the modulus is not
    */
    DBUG_PRINT("info", ("multiplier=%d", multiplier));
    if (seconds_diff % seconds || (!seconds_diff && last_exec->year))
    if (seconds_diff % seconds || (!seconds_diff && last_exec->year) ||
        TIME_to_ulonglong_datetime(time_now) ==
          TIME_to_ulonglong_datetime(last_exec))
      ++multiplier;
    interval.second= seconds * multiplier;
    DBUG_PRINT("info", ("multiplier=%u interval.second=%u", multiplier,
@@ -893,16 +895,15 @@ Event_timed::compute_next_execution_time()
    DBUG_PRINT("info", ("Both STARTS & ENDS are set"));
    if (!last_executed.year)
    {
      DBUG_PRINT("info", ("Not executed so far. Execute NOW."));
      execute_at= time_now;
      execute_at_null= FALSE;
      DBUG_PRINT("info", ("Not executed so far."));
    }
    else

    {
      TIME next_exec;

      DBUG_PRINT("info", ("Executed at least once"));
      if (get_next_time(&next_exec, &starts, &time_now, &last_executed,
      if (get_next_time(&next_exec, &starts, &time_now,
                        last_executed.year? &last_executed:&starts,
                        expression, interval))
        goto err;

@@ -927,6 +928,7 @@ Event_timed::compute_next_execution_time()
  }
  else if (starts_null && ends_null) 
  {
    /* starts is always set, so this is a dead branch !! */
    DBUG_PRINT("info", ("Neither STARTS nor ENDS are set"));
    /*
      Both starts and m_ends are not set, so we schedule for the next
@@ -961,25 +963,26 @@ Event_timed::compute_next_execution_time()
        Hence schedule for starts + m_expression in case last_executed
        is not set, otherwise to last_executed + m_expression
      */
      if (last_executed.year)
      if (!last_executed.year)
      {
        DBUG_PRINT("info", ("Not executed so far."));
      }

      {
        TIME next_exec;
        DBUG_PRINT("info", ("Executed at least once."));
        if (get_next_time(&next_exec, &starts, &time_now, &last_executed,
        if (get_next_time(&next_exec, &starts, &time_now, 
                          last_executed.year? &last_executed:&starts,
                          expression, interval))
          goto err;
        execute_at= next_exec;
        DBUG_PRINT("info",("Next[%llu]",TIME_to_ulonglong_datetime(&next_exec)));
      }
      else
      {
        DBUG_PRINT("info", ("Not executed so far. Execute at STARTS"));
        execute_at= starts;
      }
      execute_at_null= FALSE;
    }
    else
    {
      /* this is a dead branch, because starts is always set !!! */
      DBUG_PRINT("info", ("STARTS is not set. ENDS is set"));
      /*
        - m_ends is set