数据库的监控点中,阻塞情况是一个重要指标,Innodb 是主流存储引擎,下面实验一下如何监控器阻塞状态


模拟阻塞状态


使用两个MySQL客户端连接同一个MySQL服务器,并查询出各自的连接ID


Mysql 监控 Innodb 阻塞状况_java


client1 的 ID为 5


Mysql 监控 Innodb 阻塞状况_java_02


client2 的 ID为 6


先把阻塞过期时间设得大一点,便于测试


mysql> set global innodb_lock_wait_timeout=200;


在 client1 中执行语句


mysql> begin;

mysql> select film_id from film for update;


Mysql 监控 Innodb 阻塞状况_java_03


可以正常返回数据


在 client2 中执行语句


mysql> begin;

mysql> select title from film for update;


Mysql 监控 Innodb 阻塞状况_java_04


没有返回结果,处于等待状态,因为被阻塞了,完成了模拟


查询阻塞


执行下面的语句来查询阻塞


select b.trx_mysql_thread_id as '被阻塞线程'

,b.trx_query as '被阻塞SQL'

,c.trx_mysql_thread_id as '阻塞线程'

,c.trx_query as '阻塞SQL'

,(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(c.trx_started)) as '阻塞时间' 

from

information_schema.innodb_lock_waits a 

join

information_schema.innodb_trx b

on a.requesting_trx_id=b.trx_id 

join

information_schema.innodb_trx c

on a.blocking_trx_id=c.trx_id 

where

(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(c.trx_started))>10


查询结果


Mysql 监控 Innodb 阻塞状况_java_05


可以看到,已经正确查出了阻塞状态


这个查询语句比较长,但实际并不复杂,只查询了两张表,尾部的数字 10 可以随意改,是表示要查询阻塞时间大于多少秒的