MySQL锁表问题
今天遇到一个情况,一条SQL语句执行提示如下异常。
Lock wait timeout exceeded; try restarting transaction
翻译一下是说,获取锁超时,尝试重新启动事务。翻译一下就是当我们申请对表进行加锁时,另外一个事务已经对这个表加了锁,经过一段时间等待后,我们的事务依然没有获取到锁,所以提示超时了。如果稍后重试可以成功,说明我们的数据库设置的超时参数可能太短了,结合我们的业务我们可以调整数据库参数。如果重试后依然不行,很可能是大事务将表锁了,这个时候,我们需要从两方面解决问题,一方面需要优化大事务或者添加告警机制,另一方面需要手动终止这个大事务,解除表锁。
以下仅描述解锁过程,大事务优化暂且不表。
连接数据库
数据库是主备模式,同时配置了VIP,需要先查询下数据库的实际IP,确定主节点IP,然后通过数据库工具或者命令行连接主节点实例。
查找锁并解除锁
通过如下命令查找正在执行的进程,从中可以看到有一个进程执行了超过12000s,即已经执行数日还没结束,判断该进程就是执行异常锁表的进程,使用kill命令终止这个锁表进程。
show processlist;
kill 锁表进程id;
执行kill命令后,可以看到执行异常导致锁表的进程Command变成了Killed.
大功告成?
NO,该进程只是被标记为Killed状态,但是依然在执行,如果是大事务导致的,则在执行回滚动作,待回滚结束才是真的结束,所以需要耐心等待,等这个进程不再出现在processlist列表中,则该进程被成功终止。
如果你拥有PROCESS权限,则可以通过下面的SQL来查看这个大事务的状态。
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
待锁表的进程被终止后,可以通过下面的语句查看目前被使用的表,in_use表示有多少线程正在使用该表。
show open tables where in_use > 0;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?