天天看点

如何查找到底是谁执行了FTWL导致Waiting for global read lock

MySQL · 特性分析 · 到底是谁执行了FTWL中

文章中,分析了为何出现大量Waiting for global read lock的连接。但是实际操作起来很多gdb版本不支持pset操作,而且连接过多,导致不可能手动打印每一个THD的state,所以笔者写了一个gdb的脚本供大家使用:

首先,先保存下面脚本到/tmp/getlockconn

# MySQL8.0
define mysql8_get
  set $begin_addr = 0
  set $end_addr = 0
  set $part_i = 0
  while $part_i < 8
    set $begin_addr = 0
    set variable $end_addr = Global_THD_manager::thd_manager->thd_list[$part_i]->m_size
    while $begin_addr < $end_addr
      set variable $stat = Global_THD_manager::thd_manager->thd_list[$part_i]->m_array_ptr[$begin_addr]->global_read_lock->m_state
      if $stat == 2
        p Global_THD_manager::thd_manager->thd_list[$part_i]->m_array_ptr[$begin_addr]->global_read_lock->m_state
        p Global_THD_manager::thd_manager->thd_list[$part_i]->m_array_ptr[$begin_addr]->m_thread_id
      end
      set $begin_addr = $begin_addr + 1
    end
    set $part_i = $part_i + 1
  end
end

define mysql57_get
  set $begin_addr = 0
  set $end_addr = 0
  set variable $end_addr = Global_THD_manager::thd_manager->thd_list->m_size
  while $begin_addr < $end_addr
    set variable $stat = Global_THD_manager::thd_manager->thd_list->m_array_ptr[$begin_addr]->global_read_lock->m_state
    if $stat == 2
      p Global_THD_manager::thd_manager->thd_list->m_array_ptr[$begin_addr]->global_read_lock->m_state
      p Global_THD_manager::thd_manager->thd_list->m_array_ptr[$begin_addr]->m_thread_id
    end
    set $begin_addr = $begin_addr + 1
  end
end           

然后,找到mysqld的pid执行:

gdb -batch -x ~/com -ex "mysql57_get" -p <pid>

Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007fcd6e56027d in poll () from /lib64/libc.so.6
$1 = Global_read_lock::GRL_ACQUIRED_AND_BLOCKS_COMMIT
$2 = 13           

最后,连接mysql,执行kill

kill 13           

继续阅读