mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Second stage of optimizer_trace optimizations
- Move testing of my_writer to inline functions to avoid calls - Made more functions inline. Especially thd->thread_started() is now very optimized! - Moved Opt_trace_stmt classe to opt_trace_context.h to get critical functions inline
This commit is contained in:
@@ -260,50 +260,6 @@ void Json_writer::add_str(const String &str)
|
||||
add_str(str.ptr(), str.length());
|
||||
}
|
||||
|
||||
Json_writer_object::Json_writer_object(THD *thd) :
|
||||
Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->start_object();
|
||||
}
|
||||
|
||||
Json_writer_object::Json_writer_object(THD* thd, const char *str) :
|
||||
Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->add_member(str).start_object();
|
||||
}
|
||||
|
||||
Json_writer_object::~Json_writer_object()
|
||||
{
|
||||
if (my_writer && !closed)
|
||||
my_writer->end_object();
|
||||
closed= TRUE;
|
||||
}
|
||||
|
||||
Json_writer_array::Json_writer_array(THD *thd) :
|
||||
Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->start_array();
|
||||
}
|
||||
|
||||
Json_writer_array::Json_writer_array(THD *thd, const char *str) :
|
||||
Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->add_member(str).start_array();
|
||||
|
||||
}
|
||||
Json_writer_array::~Json_writer_array()
|
||||
{
|
||||
if (unlikely(my_writer && !closed))
|
||||
{
|
||||
my_writer->end_array();
|
||||
closed= TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Json_writer_temp_disable::Json_writer_temp_disable(THD *thd_arg)
|
||||
{
|
||||
thd= thd_arg;
|
||||
|
||||
@@ -256,63 +256,51 @@ public:
|
||||
void init(Json_writer *my_writer) { writer= my_writer; }
|
||||
void add_str(const char* val)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_str(val);
|
||||
}
|
||||
void add_str(const char* val, size_t length)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_str(val, length);
|
||||
}
|
||||
void add_str(const String &str)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_str(str.ptr(), str.length());
|
||||
}
|
||||
void add_str(const LEX_CSTRING &str)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_str(str.str, str.length);
|
||||
}
|
||||
void add_str(Item *item)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_str(item);
|
||||
}
|
||||
|
||||
void add_ll(longlong val)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_ll(val);
|
||||
}
|
||||
void add_size(longlong val)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_size(val);
|
||||
}
|
||||
void add_double(double val)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_double(val);
|
||||
}
|
||||
void add_bool(bool val)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_bool(val);
|
||||
}
|
||||
void add_null()
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_null();
|
||||
}
|
||||
void add_table_name(const JOIN_TAB *tab)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_table_name(tab);
|
||||
}
|
||||
void add_table_name(const TABLE* table)
|
||||
{
|
||||
if (unlikely(writer))
|
||||
writer->add_table_name(table);
|
||||
}
|
||||
};
|
||||
@@ -355,55 +343,90 @@ class Json_writer_object : public Json_writer_struct
|
||||
private:
|
||||
void add_member(const char *name)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->add_member(name);
|
||||
my_writer->add_member(name);
|
||||
}
|
||||
public:
|
||||
explicit Json_writer_object(THD *thd);
|
||||
explicit Json_writer_object(THD *thd, const char *str);
|
||||
explicit Json_writer_object(THD *thd)
|
||||
: Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->start_object();
|
||||
}
|
||||
|
||||
explicit Json_writer_object(THD* thd, const char *str)
|
||||
: Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->add_member(str).start_object();
|
||||
}
|
||||
|
||||
~Json_writer_object()
|
||||
{
|
||||
if (my_writer && !closed)
|
||||
my_writer->end_object();
|
||||
closed= TRUE;
|
||||
}
|
||||
|
||||
Json_writer_object& add(const char *name, bool value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_bool(value);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_bool(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add(const char *name, ulonglong value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add(const char *name, longlong value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_ll(value);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_ll(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add(const char *name, double value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_double(value);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_double(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#ifndef _WIN64
|
||||
Json_writer_object& add(const char *name, size_t value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
Json_writer_object& add(const char *name, const char *value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_str(value);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_str(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add(const char *name, const char *value, size_t num_bytes)
|
||||
@@ -415,46 +438,64 @@ public:
|
||||
Json_writer_object& add(const char *name, const LEX_CSTRING &value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_str(value.str, value.length);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_str(value.str, value.length);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add(const char *name, Item *value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_str(value);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_str(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add_null(const char*name)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member(name);
|
||||
context.add_null();
|
||||
if (my_writer)
|
||||
{
|
||||
add_member(name);
|
||||
context.add_null();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add_table_name(const JOIN_TAB *tab)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member("table");
|
||||
context.add_table_name(tab);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member("table");
|
||||
context.add_table_name(tab);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add_table_name(const TABLE *table)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member("table");
|
||||
context.add_table_name(table);
|
||||
if (my_writer)
|
||||
{
|
||||
add_member("table");
|
||||
context.add_table_name(table);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Json_writer_object& add_select_number(uint select_number)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
add_member("select_id");
|
||||
if (unlikely(select_number >= INT_MAX))
|
||||
context.add_str("fake");
|
||||
else
|
||||
context.add_ll(static_cast<longlong>(select_number));
|
||||
if (my_writer)
|
||||
{
|
||||
add_member("select_id");
|
||||
if (unlikely(select_number >= INT_MAX))
|
||||
context.add_str("fake");
|
||||
else
|
||||
context.add_ll(static_cast<longlong>(select_number));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
void end()
|
||||
@@ -464,7 +505,6 @@ public:
|
||||
my_writer->end_object();
|
||||
closed= TRUE;
|
||||
}
|
||||
~Json_writer_object();
|
||||
};
|
||||
|
||||
|
||||
@@ -479,8 +519,25 @@ public:
|
||||
class Json_writer_array : public Json_writer_struct
|
||||
{
|
||||
public:
|
||||
Json_writer_array(THD *thd);
|
||||
Json_writer_array(THD *thd, const char *str);
|
||||
Json_writer_array(THD *thd): Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->start_array();
|
||||
}
|
||||
|
||||
Json_writer_array(THD *thd, const char *str) : Json_writer_struct(thd)
|
||||
{
|
||||
if (unlikely(my_writer))
|
||||
my_writer->add_member(str).start_array();
|
||||
}
|
||||
~Json_writer_array()
|
||||
{
|
||||
if (unlikely(my_writer && !closed))
|
||||
{
|
||||
my_writer->end_array();
|
||||
closed= TRUE;
|
||||
}
|
||||
}
|
||||
void end()
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
@@ -492,78 +549,89 @@ public:
|
||||
Json_writer_array& add(bool value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_bool(value);
|
||||
if (my_writer)
|
||||
context.add_bool(value);
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add(ulonglong value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
if (my_writer)
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add(longlong value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_ll(value);
|
||||
if (my_writer)
|
||||
context.add_ll(value);
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add(double value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_double(value);
|
||||
if (my_writer)
|
||||
context.add_double(value);
|
||||
return *this;
|
||||
}
|
||||
#ifndef _WIN64
|
||||
Json_writer_array& add(size_t value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
if (my_writer)
|
||||
context.add_ll(static_cast<longlong>(value));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
Json_writer_array& add(const char *value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_str(value);
|
||||
if (my_writer)
|
||||
context.add_str(value);
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add(const char *value, size_t num_bytes)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_str(value, num_bytes);
|
||||
if (my_writer)
|
||||
context.add_str(value, num_bytes);
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add(const LEX_CSTRING &value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_str(value.str, value.length);
|
||||
if (my_writer)
|
||||
context.add_str(value.str, value.length);
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add(Item *value)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_str(value);
|
||||
if (my_writer)
|
||||
context.add_str(value);
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add_null()
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_null();
|
||||
if (my_writer)
|
||||
context.add_null();
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add_table_name(const JOIN_TAB *tab)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_table_name(tab);
|
||||
if (my_writer)
|
||||
context.add_table_name(tab);
|
||||
return *this;
|
||||
}
|
||||
Json_writer_array& add_table_name(const TABLE *table)
|
||||
{
|
||||
DBUG_ASSERT(!closed);
|
||||
context.add_table_name(table);
|
||||
if (my_writer)
|
||||
context.add_table_name(table);
|
||||
return *this;
|
||||
}
|
||||
~Json_writer_array();
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -328,52 +328,28 @@ void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view,
|
||||
The trace of one statement.
|
||||
*/
|
||||
|
||||
class Opt_trace_stmt {
|
||||
public:
|
||||
/**
|
||||
Constructor, starts a trace for information_schema and dbug.
|
||||
@param ctx_arg context
|
||||
*/
|
||||
Opt_trace_stmt(Opt_trace_context *ctx_arg)
|
||||
{
|
||||
ctx= ctx_arg;
|
||||
current_json= new Json_writer();
|
||||
missing_priv= false;
|
||||
I_S_disabled= 0;
|
||||
}
|
||||
~Opt_trace_stmt()
|
||||
{
|
||||
delete current_json;
|
||||
}
|
||||
void set_query(const char *query_ptr, size_t length, const CHARSET_INFO *charset);
|
||||
void open_struct(const char *key, char opening_bracket);
|
||||
void close_struct(const char *saved_key, char closing_bracket);
|
||||
void fill_info(Opt_trace_info* info);
|
||||
void add(const char *key, char *opening_bracket, size_t val_length);
|
||||
Json_writer* get_current_json() {return current_json;}
|
||||
void missing_privilege();
|
||||
void disable_tracing_for_children();
|
||||
void enable_tracing_for_children();
|
||||
bool is_enabled();
|
||||
Opt_trace_stmt::Opt_trace_stmt(Opt_trace_context *ctx_arg)
|
||||
{
|
||||
ctx= ctx_arg;
|
||||
current_json= new Json_writer();
|
||||
missing_priv= false;
|
||||
I_S_disabled= 0;
|
||||
}
|
||||
|
||||
void set_allowed_mem_size(size_t mem_size);
|
||||
size_t get_length() { return current_json->output.length(); }
|
||||
size_t get_truncated_bytes() { return current_json->get_truncated_bytes(); }
|
||||
bool get_missing_priv() { return missing_priv; }
|
||||
Opt_trace_stmt::~Opt_trace_stmt()
|
||||
{
|
||||
delete current_json;
|
||||
}
|
||||
|
||||
private:
|
||||
Opt_trace_context *ctx;
|
||||
String query; // store the query sent by the user
|
||||
Json_writer *current_json; // stores the trace
|
||||
bool missing_priv; ///< whether user lacks privilege to see this trace
|
||||
/*
|
||||
0 <=> this trace should be in information_schema.
|
||||
!=0 tracing is disabled, this currently happens when we want to trace a
|
||||
sub-statement. For now traces are only collect for the top statement
|
||||
not for the sub-statments.
|
||||
*/
|
||||
uint I_S_disabled;
|
||||
};
|
||||
size_t Opt_trace_stmt::get_length()
|
||||
{
|
||||
return current_json->output.length();
|
||||
}
|
||||
|
||||
size_t Opt_trace_stmt::get_truncated_bytes()
|
||||
{
|
||||
return current_json->get_truncated_bytes();
|
||||
}
|
||||
|
||||
void Opt_trace_stmt::set_query(const char *query_ptr, size_t length,
|
||||
const CHARSET_INFO *charset)
|
||||
@@ -381,13 +357,6 @@ void Opt_trace_stmt::set_query(const char *query_ptr, size_t length,
|
||||
query.append(query_ptr, length, charset);
|
||||
}
|
||||
|
||||
Json_writer* Opt_trace_context::get_current_json()
|
||||
{
|
||||
if (!is_started())
|
||||
return NULL;
|
||||
return current_trace->get_current_json();
|
||||
}
|
||||
|
||||
void Opt_trace_context::missing_privilege()
|
||||
{
|
||||
if (current_trace)
|
||||
@@ -573,11 +542,6 @@ void Opt_trace_stmt::enable_tracing_for_children()
|
||||
--I_S_disabled;
|
||||
}
|
||||
|
||||
bool Opt_trace_stmt::is_enabled()
|
||||
{
|
||||
return I_S_disabled == 0;
|
||||
}
|
||||
|
||||
void Opt_trace_stmt::set_allowed_mem_size(size_t mem_size)
|
||||
{
|
||||
current_json->set_size_limit(mem_size);
|
||||
|
||||
@@ -21,8 +21,6 @@ class Item;
|
||||
class THD;
|
||||
struct TABLE_LIST;
|
||||
|
||||
class Opt_trace_stmt;
|
||||
|
||||
/*
|
||||
User-visible information about a trace.
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,50 @@
|
||||
|
||||
#include "sql_array.h"
|
||||
|
||||
class Opt_trace_stmt;
|
||||
class Opt_trace_context;
|
||||
class Opt_trace_info;
|
||||
class Json_writer;
|
||||
|
||||
class Opt_trace_stmt {
|
||||
public:
|
||||
/**
|
||||
Constructor, starts a trace for information_schema and dbug.
|
||||
@param ctx_arg context
|
||||
*/
|
||||
Opt_trace_stmt(Opt_trace_context *ctx_arg);
|
||||
~Opt_trace_stmt();
|
||||
void set_query(const char *query_ptr, size_t length, const CHARSET_INFO *charset);
|
||||
void open_struct(const char *key, char opening_bracket);
|
||||
void close_struct(const char *saved_key, char closing_bracket);
|
||||
void fill_info(Opt_trace_info* info);
|
||||
void add(const char *key, char *opening_bracket, size_t val_length);
|
||||
Json_writer* get_current_json() {return current_json;}
|
||||
void missing_privilege();
|
||||
void disable_tracing_for_children();
|
||||
void enable_tracing_for_children();
|
||||
bool is_enabled()
|
||||
{
|
||||
return I_S_disabled == 0;
|
||||
}
|
||||
void set_allowed_mem_size(size_t mem_size);
|
||||
size_t get_length();
|
||||
size_t get_truncated_bytes();
|
||||
bool get_missing_priv() { return missing_priv; }
|
||||
|
||||
private:
|
||||
Opt_trace_context *ctx;
|
||||
String query; // store the query sent by the user
|
||||
Json_writer *current_json; // stores the trace
|
||||
bool missing_priv; ///< whether user lacks privilege to see this trace
|
||||
/*
|
||||
0 <=> this trace should be in information_schema.
|
||||
!=0 tracing is disabled, this currently happens when we want to trace a
|
||||
sub-statement. For now traces are only collect for the top statement
|
||||
not for the sub-statments.
|
||||
*/
|
||||
uint I_S_disabled;
|
||||
};
|
||||
|
||||
|
||||
class Opt_trace_context
|
||||
{
|
||||
@@ -48,7 +91,12 @@ public:
|
||||
This returns the current trace, to which we are still writing and has not been finished
|
||||
*/
|
||||
|
||||
Json_writer* get_current_json();
|
||||
Json_writer* get_current_json()
|
||||
{
|
||||
if (!is_started())
|
||||
return NULL;
|
||||
return current_trace->get_current_json();
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
@@ -57,7 +105,7 @@ public:
|
||||
|
||||
bool is_started()
|
||||
{
|
||||
return current_trace && is_enabled();
|
||||
return current_trace && current_trace->is_enabled();
|
||||
}
|
||||
|
||||
bool disable_tracing_if_required();
|
||||
|
||||
Reference in New Issue
Block a user