Commit 5cfb6b47 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-7999 - PROFILING routines take 0.2% when profiling disabled

PROFILING::start_new_query() optimizations:
- no need to check "current": added assertion instead
- "enabled" now means "is enabled currently" instead of "was enabled at query
  start". Old meaning was useless, new meaning echoes OPTION_PROFILING so
  that start_new_query() can be defined in sql_profile.h.
- remnants of start_new_query() moved to sql_profile.h so it can be inlined

PROFILING::start_new_query() overhead dropped 0.08% -> out of radar.

PROFILING::set_query_source() optimizations:
- no need to check "enabled": !enabled && current is impossible
- remnants of set_query_source() moved to sql_profile.h so it can be inlined

PROFILING::set_query_source() overhead dropped 0.02% -> out of radar.

PROFILING::finish_current_query() optimizations:
- moved "current" check out to sql_profile.h so it can be inlined

PROFILING::finish_current_query() overhead dropped 0.10% -> out of radar.
parent 55d5af73
...@@ -337,36 +337,6 @@ PROFILING::~PROFILING() ...@@ -337,36 +337,6 @@ PROFILING::~PROFILING()
delete current; 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 Throw away the current profile, because it's useless or unwanted
or corrupted. or corrupted.
...@@ -386,16 +356,15 @@ void PROFILING::discard_current_query() ...@@ -386,16 +356,15 @@ void PROFILING::discard_current_query()
saved, and maintain the profile history size. Naturally, this may not saved, and maintain the profile history size. Naturally, this may not
succeed if the profile was previously discarded, and that's expected. 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"); DBUG_ENTER("PROFILING::finish_current_profile");
if (current != NULL) DBUG_ASSERT(current);
{
/* The last fence-post, so we can support the span before this. */ /* The last fence-post, so we can support the span before this. */
status_change("ending", NULL, NULL, 0); status_change("ending", NULL, NULL, 0);
if ((enabled) && /* ON at start? */ if (enabled && /* ON at end? */
((thd->variables.option_bits & OPTION_PROFILING) != 0) && /* and ON at end? */
(current->query_source != NULL) && (current->query_source != NULL) &&
(! current->entries.is_empty())) (! current->entries.is_empty()))
{ {
...@@ -403,19 +372,15 @@ void PROFILING::finish_current_query() ...@@ -403,19 +372,15 @@ void PROFILING::finish_current_query()
history.push_back(current); history.push_back(current);
last= current; /* never contains something that is not in the history. */ last= current; /* never contains something that is not in the history. */
current= NULL;
}
else
{
delete current;
current= NULL;
}
}
/* Maintain the history size. */ /* Maintain the history size. */
while (history.elements > thd->variables.profiling_history_size) while (history.elements > thd->variables.profiling_history_size)
delete history.pop(); delete history.pop();
}
else
delete current;
current= NULL;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -475,26 +440,6 @@ bool PROFILING::show_profiles() ...@@ -475,26 +440,6 @@ bool PROFILING::show_profiles()
DBUG_RETURN(FALSE); 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 . 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 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 ...@@ -720,4 +665,10 @@ int PROFILING::fill_statistics_info(THD *thd_arg, TABLE_LIST *tables, Item *cond
DBUG_RETURN(0); DBUG_RETURN(0);
} }
void PROFILING::reset()
{
enabled= thd->variables.option_bits & OPTION_PROFILING;
}
#endif /* ENABLED_PROFILING */ #endif /* ENABLED_PROFILING */
...@@ -268,32 +268,62 @@ private: ...@@ -268,32 +268,62 @@ private:
public: public:
PROFILING(); PROFILING();
~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 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, void status_change(const char *status_arg,
const char *function_arg, const char *function_arg,
const char *file_arg, unsigned int line_arg) const char *file_arg, unsigned int line_arg)
{ {
if (unlikely(current)) if (unlikely(current))
{
DBUG_ASSERT(enabled);
current->new_status(status_arg, function_arg, file_arg, line_arg); 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 */ /* SHOW PROFILES */
bool show_profiles(); bool show_profiles();
/* ... from INFORMATION_SCHEMA.PROFILING ... */ /* ... from INFORMATION_SCHEMA.PROFILING ... */
int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond); int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
void reset();
}; };
# endif /* ENABLED_PROFILING */ # endif /* ENABLED_PROFILING */
......
...@@ -3652,10 +3652,18 @@ static Sys_var_bit Sys_unique_checks( ...@@ -3652,10 +3652,18 @@ static Sys_var_bit Sys_unique_checks(
DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG); DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG);
#ifdef ENABLED_PROFILING #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( static Sys_var_bit Sys_profiling(
"profiling", "profiling", "profiling", "profiling",
NO_SET_STMT SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_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( static Sys_var_ulong Sys_profiling_history_size(
"profiling_history_size", "Limit of query profiling memory", "profiling_history_size", "Limit of query profiling memory",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment