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()
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 */
......@@ -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 */
......
......@@ -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",
......
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