MySQL从5.5版本开始引入了MDL锁(Metadata Lock),用于解决DDL操作与DML操作的一致性,但是在以下场景下中会导致阻塞现象,例如执行DML操作时执行ALTER操作、长时间查询数据时执行ALTER操作等,在异常情况下的元数据锁MDL会阻塞后续对表的操作。本文主要介绍如何通过DMS工具解决该问题。
常见的问题原因如下:
请参考以下步骤解决问题:
说明 : 网络地址和端口需要输入对应RDS实例的内网地址及内网端口,可在RDS管理控制台中的RDS实例基本信息页面查看。
show full processlist;系统显示类似如下,确认在State列存在大量“Waiting for table metadata lock”信息, 即表示出现阻塞。在对应的Info列查看是对哪个表进行的操作,找到正在对该表进行操作的会话,查看并记录对应的会话ID。
说明:
- 这里需要找到的是一直在占用该表的会话,而不是正在等待MDL锁解除的会话,注意区分。可以根据State列的状态和Info列的命令内容来进行分析判断。
- 您也可以执行如下SQL语句,查询长时间未完成的事务。如果导致阻塞语句的用户与当前用户不同,请使用执行SQL语句导致阻塞的用户登录来终止会话。
select concat('kill ', i.trx_mysql_thread_id, ';')
from information_schema.innodb_trx i,
(select id,
time
from information_schema.processlist
where time =
(select max(time)
from information_schema.processlist
where state = 'Waiting for table metadata lock'
and substring(info, 1, 5) in ('alter',
'optim',
'repai',
'lock ',
'drop ',
'creat'))) p
where timestampdiff(second, i.trx_started, now()) > p.time
and i.trx_mysql_thread_id not in (connection_id(),
p.id);
kill [$ID]
说明:[$ID]为上一步获取的ID。
create event my_long_running_trx_monitor on schedule every 60 minute starts '2015-09-15 11:00:00' on completion preserve enable do begin declare v_sql varchar(500); declare no_more_long_running_trx integer default 0; declare c_tid
cursor
for
select concat ('kill ',
trx_mysql_thread_id,
';')
from information_schema.innodb_trx
where timestampdiff(minute, trx_started, now()) >= 60; declare continue
handler for not found
set no_more_long_running_trx=1; open c_tid; repeat fetch c_tid into v_sql;
set @v_sql=v_sql; prepare stmt
from @v_sql; execute stmt; deallocate prepare stmt; until no_more_long_running_trx end repeat; close c_tid; end
如果您的问题仍未解决,您可以在阿里云社区提交工单联系阿里云技术支持。