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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值