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