diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index 2eaaea41f18..9fa4d646fa1 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -337,36 +337,6 @@ PROFILING::~PROFILING() delete current; } - -/** - Prepare to start processing a new query. It is an error to do this - if there's a query already in process; nesting is not supported. - - @param initial_state (optional) name of period before first state change -*/ -void PROFILING::start_new_query(const char *initial_state) -{ - DBUG_ENTER("PROFILING::start_new_query"); - - /* This should never happen unless the server is radically altered. */ - if (unlikely(current != NULL)) - { - DBUG_PRINT("warning", ("profiling code was asked to start a new query " - "before the old query was finished. This is " - "probably a bug.")); - finish_current_query(); - } - - enabled= ((thd->variables.option_bits & OPTION_PROFILING) != 0); - - if (! enabled) DBUG_VOID_RETURN; - - DBUG_ASSERT(current == NULL); - current= new QUERY_PROFILE(this, initial_state); - - DBUG_VOID_RETURN; -} - /** Throw away the current profile, because it's useless or unwanted or corrupted. @@ -386,36 +356,31 @@ void PROFILING::discard_current_query() saved, and maintain the profile history size. Naturally, this may not succeed if the profile was previously discarded, and that's expected. */ -void PROFILING::finish_current_query() +void PROFILING::finish_current_query_impl() { DBUG_ENTER("PROFILING::finish_current_profile"); - if (current != NULL) + DBUG_ASSERT(current); + + /* The last fence-post, so we can support the span before this. */ + status_change("ending", NULL, NULL, 0); + + if (enabled && /* ON at end? */ + (current->query_source != NULL) && + (! current->entries.is_empty())) { - /* The last fence-post, so we can support the span before this. */ - status_change("ending", NULL, NULL, 0); + current->profiling_query_id= next_profile_id(); /* assign an id */ - if ((enabled) && /* ON at start? */ - ((thd->variables.option_bits & OPTION_PROFILING) != 0) && /* and ON at end? */ - (current->query_source != NULL) && - (! current->entries.is_empty())) - { - current->profiling_query_id= next_profile_id(); /* assign an id */ + history.push_back(current); + last= current; /* never contains something that is not in the history. */ - history.push_back(current); - last= current; /* never contains something that is not in the history. */ - current= NULL; - } - else - { - delete current; - current= NULL; - } + /* Maintain the history size. */ + while (history.elements > thd->variables.profiling_history_size) + delete history.pop(); } + else + delete current; - /* Maintain the history size. */ - while (history.elements > thd->variables.profiling_history_size) - delete history.pop(); - + current= NULL; DBUG_VOID_RETURN; } @@ -475,26 +440,6 @@ bool PROFILING::show_profiles() DBUG_RETURN(FALSE); } -/** - At a point in execution where we know the query source, save the text - of it in the query profile. - - This must be called exactly once per descrete statement. -*/ -void PROFILING::set_query_source(char *query_source_arg, uint query_length_arg) -{ - DBUG_ENTER("PROFILING::set_query_source"); - - if (! enabled) - DBUG_VOID_RETURN; - - if (current != NULL) - current->set_query_source(query_source_arg, query_length_arg); - else - DBUG_PRINT("info", ("no current profile to send query source to")); - DBUG_VOID_RETURN; -} - /** Fill the information schema table, "query_profile", as defined in show.cc . There are two ways to get to this function: Selecting from the information @@ -720,4 +665,10 @@ int PROFILING::fill_statistics_info(THD *thd_arg, TABLE_LIST *tables, Item *cond DBUG_RETURN(0); } + + +void PROFILING::reset() +{ + enabled= thd->variables.option_bits & OPTION_PROFILING; +} #endif /* ENABLED_PROFILING */ diff --git a/sql/sql_profile.h b/sql/sql_profile.h index 52eaba49181..1d770ca1147 100644 --- a/sql/sql_profile.h +++ b/sql/sql_profile.h @@ -268,32 +268,62 @@ private: public: PROFILING(); ~PROFILING(); - void set_query_source(char *query_source_arg, uint query_length_arg); - void start_new_query(const char *initial_state= "starting"); + /** + At a point in execution where we know the query source, save the text + of it in the query profile. + + This must be called exactly once per descrete statement. + */ + void set_query_source(char *query_source_arg, uint query_length_arg) + { + if (unlikely(current)) + current->set_query_source(query_source_arg, query_length_arg); + } + + /** + Prepare to start processing a new query. It is an error to do this + if there's a query already in process; nesting is not supported. + + @param initial_state (optional) name of period before first state change + */ + void start_new_query(const char *initial_state= "starting") + { + DBUG_ASSERT(!current); + if (unlikely(enabled)) + current= new QUERY_PROFILE(this, initial_state); + } void discard_current_query(); - void finish_current_query(); + void finish_current_query() + { + if (unlikely(current)) + finish_current_query_impl(); + } + + void finish_current_query_impl(); void status_change(const char *status_arg, const char *function_arg, const char *file_arg, unsigned int line_arg) { if (unlikely(current)) - { - DBUG_ASSERT(enabled); current->new_status(status_arg, function_arg, file_arg, line_arg); - } } - inline void set_thd(THD *thd_arg) { thd= thd_arg; }; + inline void set_thd(THD *thd_arg) + { + thd= thd_arg; + reset(); + } /* SHOW PROFILES */ bool show_profiles(); /* ... from INFORMATION_SCHEMA.PROFILING ... */ int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond); + void reset(); }; # endif /* ENABLED_PROFILING */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 8304bda1347..4d8d5a9223b 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3652,10 +3652,18 @@ static Sys_var_bit Sys_unique_checks( DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG); #ifdef ENABLED_PROFILING +static bool update_profiling(sys_var *self, THD *thd, enum_var_type type) +{ + if (type == OPT_SESSION) + thd->profiling.reset(); + return false; +} + static Sys_var_bit Sys_profiling( "profiling", "profiling", NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_PROFILING, - DEFAULT(FALSE)); + DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(update_profiling)); static Sys_var_ulong Sys_profiling_history_size( "profiling_history_size", "Limit of query profiling memory",