背景介绍:
前两天被问道一个问题,数据库使用了MyISAM表,对表进行dml操作时发现出现阻塞,shou full processlist 显示为Waiting for table lock,并且看不到哪个session引起的表锁,最后很暴力的重启数据库来解决此问题.之前也遇到过此类问题,都是由于sql注入引起的,因此show full processlist时都能看到,此次显然不是,重启数据库代价很大,影响服务不说MyISAM表最后什么状态只有天知道,见手册中的如下说明:
If a thread is updating a nontransactional table, an operation such as a multiple-row UPDATE
or INSERT
may leave the table partially updated because the operation can terminate before completion.
代价最小的办法就是找到锁表的session kill掉,innodb 有show innodb status和information_schema里的表可以定位session,那么MyISAM如何定位持有锁的session那?如下是我使用percona5.6.26复现此问题过程,细节信息与其他版本可能有所出入.
问题复现:
分别打开三个client A/B/C:
键一个MyISAM表test_myisam;
A:执行
LOCK TABLES test_myisam write;
B:执行
select * from test_myisam;
出现锁等待
C:执行
show full processlist;
能看到Waiting for table metadata lock ,但是看不到哪个session引起的
此时执行mysqladmin -h127.0.0.1 -P3306 -uroot -p123456 debug
打开error log在尾部可以找到
可以看到引起表锁的session为4845383,直接将其kill掉即可.
注:kill掉session是万不得已的做法,最好还是等其执行完,如果是线上业务并且已经引起问题才考虑这么做.