Mysql查看锁阻塞信息

一 查看元数据锁

1.1 前提条件

1、需要确保下面这个sql查询出来的ENABLED值为YES

select ENABLED from performance_schema.setup_instruments WHERE NAME = 'wait/lock/metadata/sql/mdl';

如果为NO,则需要先将其开启:

UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES'WHERE NAME = 'wait/lock/metadata/sql/mdl';

如果要永久生效,需要在配置文件中加入如下内容:

performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'

2、需要确保events_statements_history的ENABLED值为YES

select ENABLED from performance_schema.setup_consumers

where name='events_statements_history';

如果为NO,则需要先将其开启:

UPDATE performance_schema.setup_consumers set ENABLED='YES' where name='events_statements_history';

1.2 查询元数据锁sql

#该sql在Mysql 5.7及8.0版本都试用

复制代码
select *
from 
(
    SELECT locked_schema,
    locked_table,
    locked_type,
    waiting_processlist_id,
    waiting_processlist_user,
    waiting_processlist_host,
    waiting_thread_id,
    waiting_time,
    waiting_query,
    waiting_state,
    blocking_processlist_id,
    blocking_processlist_user,
    blocking_processlist_host,
    granted_thread_id as blocking_thread_id,
    blocking_time,
    sql_text AS blocking_query,
    blocking_command,
    blocking_state,
    kill_blocking_id
    FROM 
    ( 
        SELECT 
        b.OWNER_THREAD_ID AS granted_thread_id,
        a.OWNER_THREAD_ID as waiting_thread_id,
        a.OBJECT_SCHEMA AS locked_schema,
        a.OBJECT_NAME AS locked_table,
        'Metadata Lock' AS locked_type,
        c.PROCESSLIST_ID AS waiting_processlist_id,
        c.PROCESSLIST_user AS waiting_processlist_user,
        c.PROCESSLIST_host AS waiting_processlist_host,
        c.PROCESSLIST_TIME AS waiting_time,
        c.PROCESSLIST_INFO AS waiting_query,
        c.PROCESSLIST_STATE AS waiting_state,
        d.PROCESSLIST_ID AS blocking_processlist_id,
        d.PROCESSLIST_user AS blocking_processlist_user,
        d.PROCESSLIST_host AS blocking_processlist_host,
        d.PROCESSLIST_TIME AS blocking_time,
        d.PROCESSLIST_INFO AS blocking_query,
        d.PROCESSLIST_COMMAND as blocking_command,
        d.PROCESSLIST_STATE as blocking_state,
        CONCAT('KILL ', d.PROCESSLIST_ID,';') AS kill_blocking_id
        FROM performance_schema.metadata_locks a 
        JOIN performance_schema.metadata_locks b ON a.OBJECT_SCHEMA = b.OBJECT_SCHEMA 
        AND a.OBJECT_NAME = b.OBJECT_NAME
        AND a.lock_status = 'PENDING'
        AND b.lock_status = 'GRANTED'
        AND a.OWNER_THREAD_ID <> b.OWNER_THREAD_ID
        #AND a.lock_type = 'EXCLUSIVE'
        JOIN performance_schema.threads c ON a.OWNER_THREAD_ID = c.THREAD_ID 
        JOIN performance_schema.threads d ON b.OWNER_THREAD_ID = d.THREAD_ID
    ) t1,
    (
        SELECT thread_id,  sql_text 
        FROM
        performance_schema.events_statements_history
    ) t2
    WHERE t1.granted_thread_id = t2.thread_id 
) t3 
where t3.blocking_query like concat('%',locked_table,'%');

如果blocking_query为空,则可能这个sql已经在历史会话里不存在了(每个会话默认存10条历史sql记录),需要酌情调整performance_schema_events_statements_history_size变量的大小

二 查看长时间运行的休眠(未提交)事务及相关锁等待信息

有时候有的同事会手动开启一个事务,执行完一些sql,但没提交该事务,事务处于sleep休眠状态,该事务会阻塞其他事务执行,这时需要找出这些正在运行的但是状态为休眠状态的事务。

2.1 查执行时间超过5分钟的休眠的事务

#Mysql 5.7,8.0版本都通用

复制代码
SELECT p.id,d.thread_id,t.trx_id,p.user,p.host,p.db,t.trx_started,p.time,p.state,t.trx_state,p.command,p.info,t.trx_query,l.sql_text
FROM information_schema.INNODB_TRX t
INNER JOIN information_schema.PROCESSLIST p ON t.trx_mysql_thread_id=p.id
INNER JOIN performance_schema.threads d on d.processlist_id=p.id 
INNER JOIN 
(
select thread_id,group_concat(sql_text SEPARATOR ';') as sql_text from 
performance_schema.events_statements_history  
where event_name not in('statement/sql/set_option','statement/sql/show_status')
and sql_text not like '%INFORMATION_SCHEMA%'
group by thread_id
) l
on l.thread_id=d.thread_id
WHERE t.trx_state='RUNNING'
AND p.COMMAND='Sleep'
AND p.TIME>300
ORDER BY t.trx_started ASC

2.2 查询相关具体阻塞信息(谁阻塞了谁)

2.2.1 Mysql 5.7版本

复制代码
select waiting_id,waiting_trx_id,waiting_user,waiting_host,waiting_query,db,blocking_id,blocking_command,blockting_trx_id,blocking_host,blocking_user,blocking_processlist_state,blocking_trx_started,blocking_trx_runtime,blocking_trx_state,blocking_id_current_query,blocking_sql_text,kill_blocking_id
from 
(
	select p1.id as 'waiting_id',w.REQUESTING_TRX_ID AS 'waiting_trx_id',p1.user as 'waiting_user',p1.host as 'waiting_host',p1.info as 'waiting_query',p1.db,p2.id as 'blocking_id',w.BLOCKING_TRX_ID as 'blockting_trx_id',p2.user as 'blocking_user',p2.host as 'blocking_host',p2.info as 'blocking_id_current_query',concat('kill ',p2.id,';') as 'kill_blocking_id'
	from 
	information_schema.innodb_lock_waits  w 
	inner join information_schema.innodb_trx t1 on w.REQUESTING_TRX_ID=t1.trx_id
	inner join information_schema.innodb_trx t2 on w.BLOCKING_TRX_ID=t2.trx_id
	inner join information_schema.PROCESSLIST p1 on t1.trx_mysql_thread_id=p1.id 
	inner join information_schema.PROCESSLIST p2 on t2.trx_mysql_thread_id=p2.id
) j1 
JOIN
(
	SELECT p.command as 'blocking_command',p.state as 'blocking_processlist_state',t.trx_id,t.trx_started as 'blocking_trx_started',p.time as 'blocking_trx_runtime',t.trx_state as 'blocking_trx_state',l.sql_text as 'blocking_sql_text'
	FROM information_schema.INNODB_TRX t
	INNER JOIN information_schema.PROCESSLIST p ON t.trx_mysql_thread_id=p.id
	INNER JOIN performance_schema.threads d on d.processlist_id=p.id 
	INNER JOIN 
	(
	select thread_id,group_concat(sql_text SEPARATOR ';') as sql_text from 
	performance_schema.events_statements_history  
	where event_name not in('statement/sql/set_option','statement/sql/show_status')
	and sql_text not like '%INFORMATION_SCHEMA%'
	group by thread_id
	) l
	on l.thread_id=d.thread_id
	WHERE t.trx_state='RUNNING'
	AND p.command='Sleep'
	AND p.TIME>300
	ORDER BY t.trx_started ASC
	) j2 on j1.blockting_trx_id=j2.trx_id;

2.2.2 Mysql 8.0版本

复制代码
select waiting_id,waiting_thread_id,waiting_trx_id,waiting_user,waiting_host,waiting_query,db,blocking_id,blocking_command,BLOCKING_THREAD_ID,blockting_trx_id,blocking_host,blocking_user,blocking_processlist_state,blocking_trx_started,blocking_trx_runtime,blocking_trx_state,blocking_id_current_query,blocking_sql_text,kill_blocking_id
from 
(
	select p1.id as 'waiting_id',w.REQUESTING_THREAD_ID as 'waiting_thread_id',w.REQUESTING_ENGINE_TRANSACTION_ID AS 'waiting_trx_id',p1.user as 'waiting_user',p1.host as 'waiting_host',p1.info as 'waiting_query',p1.db,p2.id as 'blocking_id',w.BLOCKING_THREAD_ID,w.BLOCKING_ENGINE_TRANSACTION_ID as 'blockting_trx_id',p2.user as 'blocking_user',p2.host as 'blocking_host',p2.info as 'blocking_id_current_query',concat('kill ',p2.id,';') as 'kill_blocking_id'
	from 
	performance_schema.data_lock_waits  w 
	inner join performance_schema.threads t1 on w.REQUESTING_THREAD_ID=t1.THREAD_ID
	inner join performance_schema.threads t2 on w.BLOCKING_THREAD_ID=t2.THREAD_ID
	inner join information_schema.PROCESSLIST p1 on t1.PROCESSLIST_ID=p1.id 
	inner join information_schema.PROCESSLIST p2 on t2.PROCESSLIST_ID=p2.id
) j1 
JOIN
(
	SELECT p.command as 'blocking_command',p.state as 'blocking_processlist_state',t.trx_id,t.trx_started as 'blocking_trx_started',p.time as 'blocking_trx_runtime',t.trx_state as 'blocking_trx_state',l.sql_text as 'blocking_sql_text'
	FROM information_schema.INNODB_TRX t
	INNER JOIN information_schema.PROCESSLIST p ON t.trx_mysql_thread_id=p.id
	INNER JOIN performance_schema.threads d on d.processlist_id=p.id 
	INNER JOIN 
	(
	select thread_id,group_concat(sql_text SEPARATOR ';') as sql_text from 
	performance_schema.events_statements_history  
	where event_name not in('statement/sql/set_option','statement/sql/show_status')
	and sql_text not like '%INFORMATION_SCHEMA%'
	group by thread_id
	) l
	on l.thread_id=d.thread_id
	WHERE t.trx_state='RUNNING'
	AND p.command='Sleep'
	AND p.TIME>300
	ORDER BY t.trx_started ASC
	) j2 on j1.blockting_trx_id=j2.trx_id

三 查看当前行锁(包括休眠事务)

3.1 Mysql 5.7版本

复制代码
select waiting_id,waiting_trx_id,waiting_user,waiting_host,waiting_query,db,blocking_id,blocking_command,blockting_trx_id,blocking_host,blocking_user,blocking_processlist_state,blocking_trx_started,blocking_trx_runtime,blocking_trx_state,blocking_id_current_query,blocking_sql_text,kill_blocking_id
from 
(
	select p1.id as 'waiting_id',w.REQUESTING_TRX_ID AS 'waiting_trx_id',p1.user as 'waiting_user',p1.host as 'waiting_host',p1.info as 'waiting_query',p1.db,p2.id as 'blocking_id',w.BLOCKING_TRX_ID as 'blockting_trx_id',p2.user as 'blocking_user',p2.host as 'blocking_host',p2.info as 'blocking_id_current_query',concat('kill ',p2.id,';') as 'kill_blocking_id'
	from 
	information_schema.innodb_lock_waits  w 
	inner join information_schema.innodb_trx t1 on w.REQUESTING_TRX_ID=t1.trx_id
	inner join information_schema.innodb_trx t2 on w.BLOCKING_TRX_ID=t2.trx_id
	inner join information_schema.PROCESSLIST p1 on t1.trx_mysql_thread_id=p1.id 
	inner join information_schema.PROCESSLIST p2 on t2.trx_mysql_thread_id=p2.id
) j1 
JOIN
(
	SELECT p.command as 'blocking_command',p.state as 'blocking_processlist_state',t.trx_id,t.trx_started as 'blocking_trx_started',p.time as 'blocking_trx_runtime',t.trx_state as 'blocking_trx_state',l.sql_text as 'blocking_sql_text'
	FROM information_schema.INNODB_TRX t
	INNER JOIN information_schema.PROCESSLIST p ON t.trx_mysql_thread_id=p.id
	INNER JOIN performance_schema.threads d on d.processlist_id=p.id 
	INNER JOIN 
	(
	select thread_id,group_concat(sql_text SEPARATOR ';') as sql_text from 
	performance_schema.events_statements_history  
	where event_name not in('statement/sql/set_option','statement/sql/show_status')
	and sql_text not like '%INFORMATION_SCHEMA%'
	group by thread_id
	) l
	on l.thread_id=d.thread_id	
	ORDER BY t.trx_started ASC
	) j2 on j1.blockting_trx_id=j2.trx_id;

3.2 Mysql 8.0版本

复制代码
select waiting_id,waiting_thread_id,waiting_trx_id,waiting_user,waiting_host,waiting_query,db,blocking_id,blocking_command,BLOCKING_THREAD_ID,blockting_trx_id,blocking_host,blocking_user,blocking_processlist_state,blocking_trx_started,blocking_trx_runtime,blocking_trx_state,blocking_id_current_query,blocking_sql_text,kill_blocking_id
from 
(
	select p1.id as 'waiting_id',w.REQUESTING_THREAD_ID as 'waiting_thread_id',w.REQUESTING_ENGINE_TRANSACTION_ID AS 'waiting_trx_id',p1.user as 'waiting_user',p1.host as 'waiting_host',p1.info as 'waiting_query',p1.db,p2.id as 'blocking_id',w.BLOCKING_THREAD_ID,w.BLOCKING_ENGINE_TRANSACTION_ID as 'blockting_trx_id',p2.user as 'blocking_user',p2.host as 'blocking_host',p2.info as 'blocking_id_current_query',concat('kill ',p2.id,';') as 'kill_blocking_id'
	from 
	performance_schema.data_lock_waits  w 
	inner join performance_schema.threads t1 on w.REQUESTING_THREAD_ID=t1.THREAD_ID
	inner join performance_schema.threads t2 on w.BLOCKING_THREAD_ID=t2.THREAD_ID
	inner join information_schema.PROCESSLIST p1 on t1.PROCESSLIST_ID=p1.id 
	inner join information_schema.PROCESSLIST p2 on t2.PROCESSLIST_ID=p2.id
) j1 
JOIN
(
	SELECT p.command as 'blocking_command',p.state as 'blocking_processlist_state',t.trx_id,t.trx_started as 'blocking_trx_started',p.time as 'blocking_trx_runtime',t.trx_state as 'blocking_trx_state',l.sql_text as 'blocking_sql_text'
	FROM information_schema.INNODB_TRX t
	INNER JOIN information_schema.PROCESSLIST p ON t.trx_mysql_thread_id=p.id
	INNER JOIN performance_schema.threads d on d.processlist_id=p.id 
	INNER JOIN 
	(
	select thread_id,group_concat(sql_text SEPARATOR ';') as sql_text from 
	performance_schema.events_statements_history  
	where event_name not in('statement/sql/set_option','statement/sql/show_status')
	and sql_text not like '%INFORMATION_SCHEMA%'
	group by thread_id
	) l
	on l.thread_id=d.thread_id	
	ORDER BY t.trx_started ASC
	) j2 on j1.blockting_trx_id=j2.trx_id
相关推荐
roman_日积跬步-终至千里11 分钟前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科12 分钟前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构
野犬寒鸦33 分钟前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
霖霖总总35 分钟前
[小技巧66]当自增主键耗尽:MySQL 主键溢出问题深度解析与雪花算法替代方案
mysql·算法
晚霞的不甘2 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d
市场部需要一个软件开发岗位2 小时前
JAVA开发常见安全问题:纵向越权
java·数据库·安全
海奥华22 小时前
mysql索引
数据库·mysql
2601_949593653 小时前
深入解析CANN-acl应用层接口:构建高效的AI应用开发框架
数据库·人工智能
javachen__3 小时前
mysql新老项目版本选择
数据库·mysql
Dxy12393102163 小时前
MySQL如何高效查询表数据量:从基础到进阶的优化指南
数据库·mysql