The question is why? On what exactly step the string was cleaned up? Let's look on the following stack trace:
Thread 27 "mysqld" hit Breakpoint 6, THD::reset_query (this=0x7fffa0128060) at ./sql/sql_class.h:4564
4564 void reset_query() { set_query(LEX_CSTRING()); }
(gdb) bt
#0 THD::reset_query (this=0x7fffa0128060) at ./sql/sql_class.h:4564
#1 0x000000000164747b in dispatch_command (thd=0x7fffa0128060, com_data=0x7ffff11c2de0, command=COM_QUERY)
at ./sql/sql_parse.cc:1946
#2 0x0000000001644b80 in do_command (thd=0x7fffa0128060) at ./sql/sql_parse.cc:1021
#3 0x0000000001796f22 in handle_connection (arg=0x3949180) at ./sql/conn_handler/connection_handler_per_thread.cc:312
#4 0x0000000001e7e5ad in pfs_spawn_thread (arg=0x3962a00) at ./storage/perfschema/pfs.cc:2188
#5 0x00007ffff6f5e6ba in start_thread (arg=0x7ffff11c3700) at pthread_create.c:333
#6 0x00007ffff63f33dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
The query string is cleaned up after the statement result is sent. So it can't be accessed from the place where the list of blocking transactions is obtained.
The query string can be obtained from performance_schema.events_statements_current table. This requires additional code to execute query inside of the server(what is preferable for better portability) or get access to internal PFS data directly, what is easier, but can require PFS code patching and increases code cohesion.
The question is why don't output blocking transaction query string instead of or along with query id.
Let's consider the code from this https:/ /github. com/percona/ percona- server/ pull/1971 pull request.
This is the place in the code where the list of blocking transactions is obtained:
Thread 28 "mysqld" hit Breakpoint 2, lock_wait_ suspend_ thread ( 0x7fffa4010418) innobase/ lock/lock0wait. cc:323 blocking_ count]. trx_id = lock_get_ trx_id( curr_lock) ; iterator_ reset(& iter, wait_lock, ULINT_UNDEFINED); iterator_ get_prev( &iter); iterator_ get_prev( &iter)) { to_wait( trx->lock. wait_lock, curr_lock)) { blocking_ count]. trx_id = lock_get_ trx_id( curr_lock) ; blocking_ count]. thread_ id = >trx->mysql_ thd ? thread_ id(curr_ lock->trx- >mysql_ thd) : 0; blocking_ count]. query_id =
thr=
at ./storage/
323 blocking[
(gdb) l
318 lock_queue_
319 for (curr_lock = lock_queue_
320 curr_lock != NULL;
321 curr_lock = lock_queue_
322 if (lock_has_
323 blocking[
324 blocking[
325 curr_lock-
326 thd_get_
327 blocking[
If we look at the THD object of blocking transaction we will see that it does not contain query string:
(gdb) p curr_lock- >trx->mysql_ thd->m_ query_string
$2 = {str = 0x0, length = 0}
The question is why? On what exactly step the string was cleaned up? Let's look on the following stack trace:
Thread 27 "mysqld" hit Breakpoint 6, THD::reset_query (this=0x7fffa01 28060) at ./sql/sql_ class.h: 4564 LEX_CSTRING( )); } 28060) at ./sql/sql_ class.h: 4564 8060, com_data= 0x7ffff11c2de0, command=COM_QUERY) parse.cc: 1946 8060) at ./sql/sql_ parse.cc: 1021 handler/ connection_ handler_ per_thread. cc:312 perfschema/ pfs.cc: 2188 3700) at pthread_ create. c:333 unix/sysv/ linux/x86_ 64/clone. S:109
4564 void reset_query() { set_query(
(gdb) bt
#0 THD::reset_query (this=0x7fffa01
#1 0x000000000164747b in dispatch_command (thd=0x7fffa012
at ./sql/sql_
#2 0x0000000001644b80 in do_command (thd=0x7fffa012
#3 0x0000000001796f22 in handle_connection (arg=0x3949180) at ./sql/conn_
#4 0x0000000001e7e5ad in pfs_spawn_thread (arg=0x3962a00) at ./storage/
#5 0x00007ffff6f5e6ba in start_thread (arg=0x7ffff11c
#6 0x00007ffff63f33dd in clone () at ../sysdeps/
The query string is cleaned up after the statement result is sent. So it can't be accessed from the place where the list of blocking transactions is obtained.
The query string can be obtained from performance_ schema. events_ statements_ current table. This requires additional code to execute query inside of the server(what is preferable for better portability) or get access to internal PFS data directly, what is easier, but can require PFS code patching and increases code cohesion.