MySQL 8.4.0
Source Code Documentation
opt_trace2server.cc File Reference

Implementation of the Optimizer trace API (WL#5257) Helpers connecting the optimizer trace to THD or Information Schema. More...

#include "my_config.h"
#include <string.h>
#include <sys/types.h>
#include "lex_string.h"
#include "my_compiler.h"
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_sqlcommand.h"
#include "mysql/strings/m_ctype.h"
#include "sql/auth/auth_acls.h"
#include "sql/auth/auth_common.h"
#include "sql/auth/sql_security_ctx.h"
#include "sql/enum_query_type.h"
#include "sql/field.h"
#include "sql/opt_trace.h"
#include "sql/opt_trace_context.h"
#include "sql/set_var.h"
#include "sql/sp_head.h"
#include "sql/sp_instr.h"
#include "sql/sql_class.h"
#include "sql/sql_lex.h"
#include "sql/sql_list.h"
#include "sql/sql_parse.h"
#include "sql/sql_show.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "sql_string.h"

Namespaces

namespace  anonymous_namespace{opt_trace2server.cc}
 

Functions

bool anonymous_namespace{opt_trace2server.cc}::list_has_optimizer_trace_table (const Table_ref *tbl)
 Whether a list of tables contains information_schema.OPTIMIZER_TRACE. More...
 
bool anonymous_namespace{opt_trace2server.cc}::sql_command_can_be_traced (enum enum_sql_command sql_command)
 Whether a SQL command qualifies for optimizer tracing. More...
 
bool anonymous_namespace{opt_trace2server.cc}::sets_var_optimizer_trace (enum enum_sql_command sql_command, List< set_var_base > *set_vars)
 
void anonymous_namespace{opt_trace2server.cc}::opt_trace_disable_if_no_tables_access (THD *thd, Table_ref *tbl)
 If tracing is on, checks additional privileges on a list of tables/views, to make sure that the user has the right to do SHOW CREATE TABLE/VIEW and "SELECT *". More...
 
void opt_trace_print_expanded_query (const THD *thd, Query_block *query_block, Opt_trace_object *trace_object)
 Prints SELECT query to optimizer trace. More...
 
void opt_trace_disable_if_no_security_context_access (THD *thd)
 If the security context is not that of the connected user, inform the trace system that a privilege is missing. More...
 
void opt_trace_disable_if_no_stored_proc_func_access (THD *thd, sp_head *sp)
 If tracing is on, checks additional privileges on a stored routine, to make sure that the user has the right to do SHOW CREATE PROCEDURE/FUNCTION. More...
 
void opt_trace_disable_if_no_view_access (THD *thd, Table_ref *view, Table_ref *underlying_tables)
 If tracing is on, checks additional privileges for a view, to make sure that the user has the right to do SHOW CREATE VIEW. More...
 
int fill_optimizer_trace_info (THD *thd, Table_ref *tables, Item *)
 Fills information_schema.OPTIMIZER_TRACE with rows (one per trace) More...
 

Variables

const char anonymous_namespace{opt_trace2server.cc}::I_S_table_name [] = "OPTIMIZER_TRACE"
 
ST_FIELD_INFO optimizer_trace_info []
 For creating fields of information_schema.OPTIMIZER_TRACE. More...
 

Detailed Description

Implementation of the Optimizer trace API (WL#5257) Helpers connecting the optimizer trace to THD or Information Schema.

They are dedicated "to the server" (hence the file's name). In order to create a unit test of the optimizer trace without defining Item_field (and all its parent classes), Query_block..., these helpers are defined in opt_trace2server.cc.

Function Documentation

◆ fill_optimizer_trace_info()

int fill_optimizer_trace_info ( THD thd,
Table_ref tables,
Item  
)

Fills information_schema.OPTIMIZER_TRACE with rows (one per trace)

Return values
0ok
1error

◆ opt_trace_disable_if_no_security_context_access()

void opt_trace_disable_if_no_security_context_access ( THD thd)

If the security context is not that of the connected user, inform the trace system that a privilege is missing.

With one exception: see below.

Parameters
thdthe THD

This serves to eliminate the following issue. Any information readable by a SELECT may theoretically end up in the trace. And a SELECT may read information from other places than tables:

  • from views (reading their bodies)
  • from stored routines (reading their bodies)
  • from files (reading their content), with LOAD_FILE()
  • from the list of connections (reading their queries...), with I_S.PROCESSLIST. If the connected user has EXECUTE privilege on a routine which does a security context change, the routine can retrieve information internally (if allowed by the SUID context's privileges), and present only a portion of it to the connected user. But with tracing on, all information is possibly in the trace. So the connected user receives more information than the routine's definer intended to provide. Fixing this issue would require adding, near many privilege checks in the server, a new optimizer-trace-specific check done against the connected user's context, to verify that the connected user has the right to see the retrieved information.

Instead, our chosen simpler solution is that if we see a security context change where SUID user is not the connected user, we disable tracing. With only one safe exception: if the connected user has all global privileges (because then she/he can find any information anyway). By "all global privileges" we mean everything but WITH GRANT OPTION (that latter one isn't related to information gathering).

Read access to I_S.OPTIMIZER_TRACE by another user than the connected user is restricted:

See also
fill_optimizer_trace_info().

◆ opt_trace_disable_if_no_stored_proc_func_access()

void opt_trace_disable_if_no_stored_proc_func_access ( THD thd,
sp_head sp 
)

If tracing is on, checks additional privileges on a stored routine, to make sure that the user has the right to do SHOW CREATE PROCEDURE/FUNCTION.

For that, we use the same checks as in those SHOW commands. If a privilege is missing, notifies the trace system.

This function is not redundant with opt_trace_disable_if_no_security_context_access(). Indeed, for a SQL SECURITY INVOKER routine, there is no context change, but we must still verify that the invoker can do SHOW CREATE.

For triggers, see note in sp_head::execute_trigger().

Parameters
thdThe THD
sproutine to check

◆ opt_trace_disable_if_no_view_access()

void opt_trace_disable_if_no_view_access ( THD thd,
Table_ref view,
Table_ref underlying_tables 
)

If tracing is on, checks additional privileges for a view, to make sure that the user has the right to do SHOW CREATE VIEW.

For that:

  • this function checks SHOW VIEW
  • SELECT is tested in opt_trace_disable_if_no_tables_access()
  • SELECT + SHOW VIEW is sufficient for SHOW CREATE VIEW. We also check underlying tables. If a privilege is missing, notifies the trace system. This function should be called when the view's underlying tables have not yet been merged.
Parameters
thdTHD context
viewview to check
underlying_tablesunderlying tables/views of 'view'

◆ opt_trace_print_expanded_query()

void opt_trace_print_expanded_query ( const THD thd,
Query_block query_block,
Opt_trace_object trace_object 
)

Prints SELECT query to optimizer trace.

It is not the original query (as in Opt_trace_context::set_query()) but a printout of the parse tree (Item-s).

Parameters
thdthe THD
query_blockquery's parse tree
trace_objectOpt_trace_object to which the query will be added

It's hard to prove that Query_block::print() doesn't modify any of its Item-s in a dangerous way. Item_int::print(), for example, modifies its internal str_value. To make the danger rare, we print the expanded query as rarely as possible: only if I_S output is needed. If only –debug is on, we don't print it. See also the corresponding call to "set_items_ref_array" at end of JOIN::exec().

Variable Documentation

◆ optimizer_trace_info

ST_FIELD_INFO optimizer_trace_info[]
Initial value:
= {
{"QUERY", 65535, MYSQL_TYPE_STRING, 0, false, nullptr, 0},
{"TRACE", 65535, MYSQL_TYPE_STRING, 0, false, nullptr, 0},
{"MISSING_BYTES_BEYOND_MAX_MEM_SIZE", 20, MYSQL_TYPE_LONG, 0, false,
nullptr, 0},
{"INSUFFICIENT_PRIVILEGES", 1, MYSQL_TYPE_TINY, 0, false, nullptr, 0},
{nullptr, 0, MYSQL_TYPE_STRING, 0, true, nullptr, 0}}
@ MYSQL_TYPE_TINY
Definition: field_types.h:57
@ MYSQL_TYPE_STRING
Definition: field_types.h:88
@ MYSQL_TYPE_LONG
Definition: field_types.h:59

For creating fields of information_schema.OPTIMIZER_TRACE.