MySQL 9.1.0
Source Code Documentation
opt_trace_context.h
Go to the documentation of this file.
1/* Copyright (c) 2011, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef OPT_TRACE_CONTEXT_INCLUDED
25#define OPT_TRACE_CONTEXT_INCLUDED
26
27#include <assert.h>
28
29#include "my_inttypes.h"
31#include "prealloced_array.h"
32
33struct CHARSET_INFO;
34
35/**
36 @file
37 This contains the declaration of class Opt_trace_context, which is needed
38 to declare THD.
39 It is recommend to read opt_trace.h first.
40*/
41
42class Opt_trace_stmt; // implementation detail local to opt_trace.cc
43class THD;
45
47
48/**
49 @class Opt_trace_context
50
51 A per-session context which is always available at any point of execution,
52 because in practice it's accessible from THD which contains:
53 @verbatim Opt_trace_context opt_trace; @endverbatim
54 It maintains properties of the session's regarding tracing: enabled/disabled
55 state, style (all trace on one line, or not, etc), a list of all remembered
56 traces of previous and current SQL statement (as restricted by
57 OFFSET/LIMIT), and a pointer to the current (being-generated) trace (which
58 itself has a pointer to its current open object/array).
59
60 Here is why the context needs to provide the current open object/array:
61
62 @li When adding a value (scalar or array or object) to an array, or adding a
63 key/value pair to an object, we need this outer object or array (from now
64 on, we will use the term "structure" for "object or array", as both are
65 structured types).
66
67 @li The most natural way would be that the outer object would be passed in
68 argument to the adder (the function which wants to add the value or
69 key/value).
70
71 @li But tracing is sometimes produced from deep down the stack trace, with
72 many intermediate frames doing no tracing (writing nothing to the trace), so
73 it would require passing the outer structure through many levels, thus
74 modifying many function prototypes.
75 Example (in gdb "backtrace" notation: inner frames first):
76@verbatim
77 #0 Item_in_subselect::single_value_transformer
78 - opens an object for key "transformation"
79 #1 Item_in_subselect::select_in_like_transformer - does no tracing
80 #2 Item_allany_subselect::select_transformer - does no tracing
81 #3 Query_block::prepare - opens an object for key "join_preparation"
82@endverbatim
83 So the object opened in #3 would have to be passed in argument to #2 and #1
84 in order to finally reach #0 where object "transformation" would be added to
85 it.
86
87 @li So, as we cannot practically pass the object down, we rather maintain a
88 "current object or array" accessible from the Opt_trace_context context;
89 it's a pointer to an instance of Opt_trace_struct, and the function deep
90 down (frame #0) grabs it from the context, where it was depositted by the
91 function high up (frame #3 in the last example).
92*/
93
95 public:
98
99 /**
100 Starts a new trace.
101 @param support_I_S Whether this statement should have its trace in
102 information_schema
103 @param support_dbug_or_missing_priv 'true' if this statement
104 should have its trace in the dbug log (--debug),
105 or if missing_privilege() may be called on this
106 trace
107 @param end_marker For a key/(object|array) pair, should the key be
108 repeated in a comment when the object|array
109 closes? like
110 @verbatim
111 "key_foo": {
112 multi-line blah
113 } / * key_foo * /
114 @endverbatim
115 This is for human-readability only, not valid in
116 JSON. Note that YAML supports #-prefixed
117 comments (we would just need to put the next
118 item's "," before the current item's "#").
119 @param one_line Should the trace be on a single line without
120 indentation? (More compact for network transfer
121 to programs, less human-readable.)
122 @param offset Offset for restricting trace production.
123 @param limit Limit for restricting trace production.
124 @param max_mem_size Maximum allowed for cumulated size of all
125 remembered traces.
126 @param features Only these optimizer features should be traced.
127
128 @retval false ok
129 @retval true error (OOM): instance is unusable, so only
130 destructor is permitted on it; any other
131 member function has undefined effects.
132 */
133 bool start(bool support_I_S, bool support_dbug_or_missing_priv,
134 bool end_marker, bool one_line, long offset, long limit,
135 ulong max_mem_size, ulonglong features);
136
137 /**
138 Ends the current (=open, unfinished, being-generated) trace.
139
140 If @c missing_privilege() has been called between start() and end(),
141 end() restores I_S support to what it was before the call to
142 @c missing_privilege(). This is the key to ensure that missing_privilege()
143 does not disable I_S support for the rest of the connection's life!
144 */
145 void end();
146
147 /// Returns whether there is a current trace
148 bool is_started() const {
149 return unlikely(pimpl != nullptr) && pimpl->current_stmt_in_gen != nullptr;
150 }
151
152 /**
153 @returns whether the current trace writes to I_S.
154 This function should rarely be used. Don't you use this for some clever
155 optimizations bypassing opt trace!
156 */
157 bool support_I_S() const;
158
159 /**
160 Set the "original" query (not transformed, as sent by client) for the
161 current trace.
162 @param query query
163 @param length query's length
164 @param charset charset which was used to encode this query
165 */
166 void set_query(const char *query, size_t length, const CHARSET_INFO *charset);
167
168 /**
169 Brainwash: deletes all remembered traces and resets counters regarding
170 OFFSET/LIMIT (so that the next statement is considered as "at offset
171 0"). Does not reset the @@@@optimizer_trace_offset/limit variables.
172 */
173 void reset();
174
175 /// @sa parameters of Opt_trace_context::start()
176 bool get_end_marker() const { return pimpl->end_marker; }
177 /// @sa parameters of Opt_trace_context::start()
178 bool get_one_line() const { return pimpl->one_line; }
179
180 /**
181 Names of flags for @@@@optimizer_trace variable of @c sys_vars.cc :
182 @li "enabled" = tracing enabled
183 @li "one_line"= see parameter of @ref Opt_trace_context::start
184 @li "default".
185 */
186 static const char *flag_names[];
187
188 /** Flags' numeric values for @@@@optimizer_trace variable */
189 enum { FLAG_DEFAULT = 0, FLAG_ENABLED = 1 << 0, FLAG_ONE_LINE = 1 << 1 };
190
191 /**
192 Features' names for @@@@optimizer_trace_features variable of
193 @c sys_vars.cc:
194 @li "greedy_search" = the greedy search for a plan
195 @li "range_optimizer" = the cost analysis of accessing data through
196 ranges in indexes
197 @li "dynamic_range" = the range optimization performed for each record
198 when access method is dynamic range
199 @li "repeated_subselect" = the repeated execution of subselects
200 @li "default".
201 */
202 static const char *feature_names[];
203
204 /** Features' numeric values for @@@@optimizer_trace_features variable */
210 /*
211 If you add here, update feature_value of empty implementation
212 and default_features!
213 */
214 /**
215 Anything unclassified, including the top object (thus, by "inheritance
216 from parent", disabling MISC makes an empty trace).
217 This feature cannot be disabled by the user; for this it is important
218 that it always has biggest flag; flag's value itself does not matter.
219 */
220 MISC = 1 << 7
221 };
222
223 /**
224 User lacks privileges to see the current trace. Make the trace appear
225 empty in Opt_trace_info, and disable I_S for all its upcoming children.
226
227 Once a call to this function has been made, subsequent calls to it before
228 @c end() have no effects.
229 */
230 void missing_privilege();
231
232 /// Optimizer features which are traced by default.
234
235 /**
236 @returns whether an optimizer feature should be traced.
237 @param f feature
238 */
240 return unlikely(pimpl != nullptr) && (pimpl->features & f);
241 }
242
243 /**
244 Opt_trace_struct is passed Opt_trace_context*, and needs to know
245 to which statement's trace to attach, so Opt_trace_context must provide
246 this information.
247 */
250 }
251
252 /**
253 @returns the next statement to show in I_S.
254 @param[in,out] got_so_far How many statements the caller got so far
255 (by previous calls to this function); function updates this count.
256 @note traces are returned from oldest to newest.
257 */
258 const Opt_trace_stmt *get_next_stmt_for_I_S(long *got_so_far) const;
259
260 /// Temporarily disables I_S for this trace and its children.
262 ++I_S_disabled;
264 }
265
266 /**
267 Restores I_S support to what it was before the previous call to
268 disable_I_S_for_this_and_children().
269 */
270 void restore_I_S() {
271 --I_S_disabled;
272 assert(I_S_disabled >= 0);
273 if (unlikely(pimpl != nullptr)) pimpl->restore_I_S();
274 }
275
278 }
279
282 }
283
284 /// Move unstructured trace text (as produced by Hypergraph) into the JSON
285 /// tree.
286 void ConsumeUnstructuredTrace(THD *thd);
287
288 private:
289 /**
290 To have the smallest impact on THD's size, most of the implementation is
291 moved to a separate class Opt_trace_context_impl which is instantiated on
292 the heap when really needed. So if a connection never sets
293 @@@@optimizer_trace to "enabled=on" and does not use --debug, this heap
294 allocation never happens.
295 This class is declared here so that frequently called functions like
296 Opt_trace_context::is_started() can be inlined.
297 */
299 public:
306 offset(0),
307 limit(0),
308 since_offset_0(0) {}
309
311 void restore_I_S();
312
313 /**
314 Trace which is currently being generated, where structures are being
315 added. "in_gen" stands for "in generation", being-generated.
316
317 In simple cases it is equal to the last element of array
318 all_stmts_for_I_S. But it can be prior to it, for example when calling
319 a stored routine:
320@verbatim
321 CALL statement starts executing
322 create trace of CALL (call it "trace #1")
323 add structure to trace #1
324 add structure to trace #1
325 First sub-statement executing
326 create trace of sub-statement (call it "trace #2")
327 add structure to trace #2
328 add structure to trace #2
329 First sub-statement ends
330 add structure to trace #1
331@endverbatim
332 In the beginning, the CALL statement's trace is the newest and current;
333 when the first sub-statement is executing, that sub-statement's trace
334 is the newest and current; when the first sub-statement ends, it is
335 still the newest but it's not the current anymore: the current is then
336 again the CALL's one, where structures will be added, until a second
337 sub-statement is executed.
338 Another case is when the current statement sends only to DBUG:
339 all_stmts_for_I_S lists only traces shown in OPTIMIZER_TRACE.
340 */
342
343 /**
344 To keep track of what is the current statement, as execution goes into
345 a sub-statement, and back to the upper statement, we have a stack of
346 successive values of current_stmt_in_gen:
347 when in a statement we enter a substatement (a new trace), we push the
348 statement's trace on the stack and change current_stmt_in_gen to the
349 substatement's trace; when leaving the substatement we pop from the
350 stack and set current_stmt_in_gen to the popped value.
351 */
353
354 /**
355 List of remembered traces for putting into the OPTIMIZER_TRACE
356 table. Element 0 is the one created first, will be first row of
357 OPTIMIZER_TRACE table. The array structure fulfills those needs:
358 - to output traces "oldest first" in OPTIMIZER_TRACE
359 - to preserve traces "newest first" when @@@@optimizer_trace_offset<0
360 - to delete a trace in the middle of the list when it is permanently
361 out of the offset/limit showable window.
362 */
364 /**
365 List of traces which are unneeded because of OFFSET/LIMIT, and
366 scheduled for deletion from memory.
367 */
369
370 bool end_marker; ///< copy of parameter of Opt_trace_context::start
373 long offset;
374 long limit;
376
377 /**
378 Number of statements traced so far since "offset 0", for comparison
379 with OFFSET and LIMIT, when OFFSET >= 0.
380 */
382
383 /// Trace in plain text, as used by Hypergraph.
385 };
386
387 Opt_trace_context_impl *pimpl; /// Dynamically allocated implementation.
388
389 /**
390 <>0 <=> any to-be-created statement's trace should not be in
391 information_schema. This applies to next statements, their substatements,
392 etc.
393 */
395
396 /**
397 Find and delete unneeded traces.
398 For example if OFFSET=-1,LIMIT=1, only the last trace is needed. When a
399 new trace is started, the previous traces becomes unneeded and this
400 function deletes them which frees memory.
401 @param purge_all if true, ignore OFFSET and thus delete everything
402 */
403 void purge_stmts(bool purge_all);
404
405 /**
406 Compute maximum allowed memory size for current trace. The current trace
407 is the only one active. Other traces break down in two groups:
408 - the finished ones (from previously executed statements),
409 - the "started but not finished ones": they are not current, are not
410 being updated at this moment: this must be the trace of a top
411 statement calling a substatement which is the current trace now: trace's
412 top statement is not being updated at this moment.
413 So the current trace can grow in the room left by all traces above.
414 */
416
417 /// Not defined copy constructor, to disallow copy.
419 /// Not defined assignment operator, to disallow assignment.
421};
422
423#endif /* OPT_TRACE_CONTEXT_INCLUDED */
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:251
To have the smallest impact on THD's size, most of the implementation is moved to a separate class Op...
Definition: opt_trace_context.h:298
Opt_trace_stmt_array stack_of_current_stmts
To keep track of what is the current statement, as execution goes into a sub-statement,...
Definition: opt_trace_context.h:352
Opt_trace_stmt_array all_stmts_to_del
List of traces which are unneeded because of OFFSET/LIMIT, and scheduled for deletion from memory.
Definition: opt_trace_context.h:368
size_t max_mem_size
Definition: opt_trace_context.h:375
long since_offset_0
Number of statements traced so far since "offset 0", for comparison with OFFSET and LIMIT,...
Definition: opt_trace_context.h:381
void restore_I_S()
Definition: opt_trace.cc:1125
void disable_I_S_for_this_and_children()
Definition: opt_trace.cc:1121
long offset
Definition: opt_trace_context.h:373
Opt_trace_context_impl()
Definition: opt_trace_context.h:300
bool end_marker
copy of parameter of Opt_trace_context::start
Definition: opt_trace_context.h:370
Opt_trace_stmt * current_stmt_in_gen
Definition: opt_trace_context.h:341
feature_value features
Definition: opt_trace_context.h:372
long limit
Definition: opt_trace_context.h:374
Opt_trace_stmt_array all_stmts_for_I_S
List of remembered traces for putting into the OPTIMIZER_TRACE table.
Definition: opt_trace_context.h:363
bool one_line
Definition: opt_trace_context.h:371
UnstructuredTrace * m_unstructured_trace
Trace in plain text, as used by Hypergraph.
Definition: opt_trace_context.h:384
A per-session context which is always available at any point of execution, because in practice it's a...
Definition: opt_trace_context.h:94
bool get_end_marker() const
Definition: opt_trace_context.h:176
bool get_one_line() const
Definition: opt_trace_context.h:178
bool start(bool support_I_S, bool support_dbug_or_missing_priv, bool end_marker, bool one_line, long offset, long limit, ulong max_mem_size, ulonglong features)
Starts a new trace.
Definition: opt_trace.cc:831
@ FLAG_ONE_LINE
Definition: opt_trace_context.h:189
@ FLAG_ENABLED
Definition: opt_trace_context.h:189
@ FLAG_DEFAULT
Definition: opt_trace_context.h:189
void purge_stmts(bool purge_all)
Find and delete unneeded traces.
Definition: opt_trace.cc:1004
void set_unstructured_trace(UnstructuredTrace *trace)
Definition: opt_trace_context.h:280
void disable_I_S_for_this_and_children()
Temporarily disables I_S for this trace and its children.
Definition: opt_trace_context.h:261
void set_query(const char *query, size_t length, const CHARSET_INFO *charset)
Set the "original" query (not transformed, as sent by client) for the current trace.
Definition: opt_trace.cc:1109
Opt_trace_stmt * get_current_stmt_in_gen()
Opt_trace_struct is passed Opt_trace_context*, and needs to know to which statement's trace to attach...
Definition: opt_trace_context.h:248
UnstructuredTrace * unstructured_trace()
Definition: opt_trace_context.h:276
const Opt_trace_stmt * get_next_stmt_for_I_S(long *got_so_far) const
Definition: opt_trace.cc:1171
feature_value
Features' numeric values for @@optimizer_trace_features variable.
Definition: opt_trace_context.h:205
@ REPEATED_SUBSELECT
Definition: opt_trace_context.h:209
@ RANGE_OPTIMIZER
Definition: opt_trace_context.h:207
@ MISC
Anything unclassified, including the top object (thus, by "inheritance from parent",...
Definition: opt_trace_context.h:220
@ GREEDY_SEARCH
Definition: opt_trace_context.h:206
@ DYNAMIC_RANGE
Definition: opt_trace_context.h:208
~Opt_trace_context()
Definition: opt_trace.cc:804
void reset()
Brainwash: deletes all remembered traces and resets counters regarding OFFSET/LIMIT (so that the next...
Definition: opt_trace.cc:1114
size_t allowed_mem_size_for_current_stmt() const
Compute maximum allowed memory size for current trace.
Definition: opt_trace.cc:1088
static const char * flag_names[]
Names of flags for @@optimizer_trace variable of sys_vars.cc :
Definition: opt_trace_context.h:186
bool support_I_S() const
Definition: opt_trace.cc:999
int I_S_disabled
Dynamically allocated implementation.
Definition: opt_trace_context.h:394
Opt_trace_context()
Definition: opt_trace_context.h:96
bool is_started() const
Returns whether there is a current trace.
Definition: opt_trace_context.h:148
void missing_privilege()
User lacks privileges to see the current trace.
Definition: opt_trace.cc:1155
static const char * feature_names[]
Features' names for @@optimizer_trace_features variable of sys_vars.cc:
Definition: opt_trace_context.h:202
void ConsumeUnstructuredTrace(THD *thd)
Move unstructured trace text (as produced by Hypergraph) into the JSON tree.
Definition: opt_trace.cc:1130
static const feature_value default_features
Optimizer features which are traced by default.
Definition: opt_trace_context.h:233
void restore_I_S()
Restores I_S support to what it was before the previous call to disable_I_S_for_this_and_children().
Definition: opt_trace_context.h:270
Opt_trace_context & operator=(const Opt_trace_context &)
Not defined assignment operator, to disallow assignment.
Opt_trace_context_impl * pimpl
Definition: opt_trace_context.h:387
void end()
Ends the current (=open, unfinished, being-generated) trace.
Definition: opt_trace.cc:957
Opt_trace_context(const Opt_trace_context &)
Not defined copy constructor, to disallow copy.
bool feature_enabled(feature_value f) const
Definition: opt_trace_context.h:239
The trace of one statement.
Definition: opt_trace.cc:113
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Trace in the form of plain text (i.e.
Definition: optimizer_trace.h:146
static constexpr unsigned PSI_INSTRUMENT_ME
Definition: psi_bits.h:43
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:58
Some integer typedefs for easier portability.
unsigned long long int ulonglong
Definition: my_inttypes.h:56
static char * query
Definition: myisam_ftdump.cc:47
const std::string charset("charset")
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
Prealloced_array< Opt_trace_stmt *, 16 > Opt_trace_stmt_array
Definition: opt_trace_context.h:44
Performance schema instrumentation interface.
Definition: m_ctype.h:421