Comment 7 for bug 1657737

Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

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 (
    thr=0x7fffa4010418)
    at ./storage/innobase/lock/lock0wait.cc:323
323 blocking[blocking_count].trx_id = lock_get_trx_id(curr_lock);
(gdb) l
318 lock_queue_iterator_reset(&iter, wait_lock, ULINT_UNDEFINED);
319 for (curr_lock = lock_queue_iterator_get_prev(&iter);
320 curr_lock != NULL;
321 curr_lock = lock_queue_iterator_get_prev(&iter)) {
322 if (lock_has_to_wait(trx->lock.wait_lock, curr_lock)) {
323 blocking[blocking_count].trx_id = lock_get_trx_id(curr_lock);
324 blocking[blocking_count].thread_id =
325 curr_lock->trx->mysql_thd ?
326 thd_get_thread_id(curr_lock->trx->mysql_thd) : 0;
327 blocking[blocking_count].query_id =

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=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.