I had already written more than once how to check MySQL threads one by one in gdb, depending on version and your real goal. For this post I decided to concentrate on checking the values of session variables and, specifically, individual switchable optimizations. This is actually easy, comparing to checking MySQL plugin variables...
I've used Percona 5.7.x and executed set session optimizer_switch='mrr=off'; in one of sessions. I checked threads one by one in gdb until I find the one I need, where thd variable is defined in some frame:
...Local session variables are kept in the field called variables in the THD structure:
(gdb) thread 3
[Switching to thread 3 (Thread 0x7f7171fbc700 (LWP 2186))]#0 0x00007f71a4be3383 in poll () from /lib64/libc.so.6
(gdb) p do_command::thd->m_thread_id
$1 = 7
(gdb) p do_command::thd->variablesNow, this is surely cool, but how to interpret the value I see, that must be some bitmask? I've printed the value of global variable also (it's in global_system_variables), so from comparing the values I can assume mrr setting is controlled by bit 64 in this bitmask. But we have to check this in the code.
$2 = {dynamic_variables_version = 61,
dynamic_variables_ptr = 0x7f717359c820 "\001", dynamic_variables_head = 384,
dynamic_variables_size = 392, dynamic_variables_allocs = 0x7f71735f9040,
max_heap_table_size = 16777216, tmp_table_size = 16777216,
long_query_time = 0, end_markers_in_json = 0 '\000',
optimizer_switch = 523711, optimizer_trace = 0,
optimizer_trace_features = 15, optimizer_trace_offset = -1,
optimizer_trace_limit = 1, optimizer_trace_max_mem_size = 16384,
sql_mode = 1075838976, option_bits = 2147748608,
...
(gdb) p do_command::thd->variables->optimizer_switch
$3 = 523711
...
(gdb) p global_system_variables->optimizer_switch
$9 = 523775
Quick search with grep helps to find out that individual switches are defined in the sql/sql_const.h header file as follows:
/* @@optimizer_switch flags. These must be in sync with optimizer_switch_typelib */So, to check if at session level we have mrr set, we should do a bitwise AND with 1<<6:
#define OPTIMIZER_SWITCH_INDEX_MERGE (1ULL << 0)
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION (1ULL << 1)
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION (1ULL << 2)
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT (1ULL << 3)
#define OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN (1ULL << 4)
#define OPTIMIZER_SWITCH_INDEX_CONDITION_PUSHDOWN (1ULL << 5)
/** If this is off, MRR is never used. */
#define OPTIMIZER_SWITCH_MRR (1ULL << 6)/**
If OPTIMIZER_SWITCH_MRR is on and this is on, MRR is used depending on a
cost-based choice ("automatic"). If OPTIMIZER_SWITCH_MRR is on and this is
off, MRR is "forced" (i.e. used as long as the storage engine is capable of
doing it).
*/
#define OPTIMIZER_SWITCH_MRR_COST_BASED (1ULL << 7)
#define OPTIMIZER_SWITCH_BNL (1ULL << 8)
#define OPTIMIZER_SWITCH_BKA (1ULL << 9)
#define OPTIMIZER_SWITCH_MATERIALIZATION (1ULL << 10)
#define OPTIMIZER_SWITCH_SEMIJOIN (1ULL << 11)
#define OPTIMIZER_SWITCH_LOOSE_SCAN (1ULL << 12)
#define OPTIMIZER_SWITCH_FIRSTMATCH (1ULL << 13)
#define OPTIMIZER_SWITCH_DUPSWEEDOUT (1ULL << 14)
#define OPTIMIZER_SWITCH_SUBQ_MAT_COST_BASED (1ULL << 15)
#define OPTIMIZER_SWITCH_USE_INDEX_EXTENSIONS (1ULL << 16)
#define OPTIMIZER_SWITCH_COND_FANOUT_FILTER (1ULL << 17)
#define OPTIMIZER_SWITCH_DERIVED_MERGE (1ULL << 18)
#define OPTIMIZER_SWITCH_LAST (1ULL << 19)
(gdb) thread 7Note that if you know bit positions for individual switches by heart printing with /t modifier may show you all bits set quickly.
[Switching to thread 7 (Thread 0x7f7171e77700 (LWP 2257))]#0 0x00007f71a4be3383 in poll () from /lib64/libc.so.6
(gdb) p do_command::thd->variables->optimizer_switch
$1 = 523775
(gdb) p do_command::thd->variables->optimizer_switch & (1 << 6)
$2 = 64
...
(gdb) p /t do_command::thd->variables->optimizer_switch
$6 = 1111111110111111111
No comments:
Post a Comment