背景介绍:

   前两天被问道一个问题,数据库使用了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;

   MyISAM如何查看哪个session持有表锁_MyISAM锁 

B:执行

   select * from test_myisam;

   MyISAM如何查看哪个session持有表锁_MyISAM锁_02

  出现锁等待

C:执行

  show full processlist;

 MyISAM如何查看哪个session持有表锁_session_03

能看到Waiting for table metadata lock ,但是看不到哪个session引起的

此时执行mysqladmin -h127.0.0.1 -P3306 -uroot -p123456 debug

打开error log在尾部可以找到

MyISAM如何查看哪个session持有表锁_MyISAM锁_04


可以看到引起表锁的session为4845383,直接将其kill掉即可.

注:kill掉session是万不得已的做法,最好还是等其执行完,如果是线上业务并且已经引起问题才考虑这么做.