← Back to team overview

maria-developers team mailing list archive

how do I count errors per database user?

 

I want to count errors by database user for IS.user_statistics. I have code
that does it in my_message_sql but hfisk thinks the counts might be
inflated. I don't understand the error reporting framework in MySQL so it is
possible that the counts are wrong or count errors and warnings rather than
only counting errors. The code below is from my_message_sql and shows where
I try to maintain the count. The assignment (thd->is_slave_error= 1) makes
me think that an error has occurred by the time I count it. But code that
follows has comments about clearing an error or converting an error to a
warning.

  if ((thd= current_thd))
  {
    /*
      TODO: There are two exceptions mechanism (THD and sp_rcontext),
      this could be improved by having a common stack of handlers.
    */
    if (thd->handle_error(error, str,
                          MYSQL_ERROR::WARN_LEVEL_ERROR))
      DBUG_RETURN(0);

    {
      USER_STATS *us= thd_get_user_stats(thd);
 --------------------------------> added by me
      my_atomic_add_bigint(&(us->errors_total), 1);
--------------------------------> added by me
    }

    thd->is_slave_error=  1; // needed to catch query errors during
replication

    /*
      thd->lex->current_select == 0 if lex structure is not inited
      (not query command (COM_QUERY))
    */
    if (thd->lex->current_select &&
        thd->lex->current_select->no_error && !thd->is_fatal_error)
    {
      DBUG_PRINT("error",
                 ("Error converted to warning: current_select: no_error %d
 "
                  "fatal_error: %d",
                  (thd->lex->current_select ?
                   thd->lex->current_select->no_error : 0),
                  (int) thd->is_fatal_error));
    }
    else
    {
      if (! thd->main_da.is_error())            // Return only first message
      {
        thd->main_da.set_error_status(thd, error, str);
      }
      query_cache_abort(&thd->net);
    }
    /*
      If a continue handler is found, the error message will be cleared
      by the stored procedures code.
    */
    if (thd->spcont &&
        ! (MyFlags & ME_NO_SP_HANDLER) &&
        thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR,
thd))
    {
      /*
        Do not push any warnings, a handled error must be completely
        silenced.
      */
      DBUG_RETURN(0);
    }

    /* When simulating OOM, skip writing to error log to avoid mtr errors */
    DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););

    if (!thd->no_warnings_for_error &&
        !(MyFlags & ME_NO_WARNING_FOR_ERROR))
    {
      /*
        Suppress infinite recursion if there a memory allocation error
        inside push_warning.
      */
      thd->no_warnings_for_error= TRUE;
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
      thd->no_warnings_for_error= FALSE;
    }
  }

  /* When simulating OOM, skip writing to error log to avoid mtr errors */
  DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););

  if (!thd || MyFlags & ME_NOREFRESH)
    sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
  DBUG_RETURN(0);
}



-- 
Mark Callaghan
mdcallag@xxxxxxxxx

Follow ups