文章中,分析了为何出现大量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