关于mysql反复死锁的问题

OLESHI 发布于 2018/01/24 17:39
阅读 586
收藏 0

今天测试环境,Mysql发生了一个莫名其妙的问题。

一个表里面,有3W多数据,有一条数据,无论通过代码,还是数据库连接工具,一修改就卡死,过一段时间提示“Lock wait timeout exceeded; try restarting transaction”。

把卡死的进程,杀掉。再次修改这条数据,还是卡死。

重启Mysql数据库后,问题得到解决。

① 求解,为何杀死发生死锁的进程,这条数据仍然不能修改?

② 有没有不重启Mysql的解决办法?

如果是生产环境,也要重启。。。不可描述啦就!

以下是问题补充:

@OLESHI:show full processlist; 显示只有一个进程在修改! (2018/01/25 14:20)
加载中
1
老菜鸟0217
老菜鸟0217

你要update的那行数据,可能别人(程序或者客户端)也修改了但没有commit或者rollback,造成行级锁没有释放。

你杀进程杀的是自己,如果别人把持着锁不放,你照样还会卡死,所以你发现重启mysql就好了。

模拟一下:

假设有一张表t1,有一行id=1的记录,然后执行以下操作:

SET AUTOCOMMIT=0; -- 关闭自动提交
UPDATE t1 SET f1='test' WHERE id=1; -- 更新id=1的行
-- COMMIT; -- 先不提交,把持着锁不放

然后你再新开一个窗口(会话),去修改这一行记录,你就会发现卡死。。。

简单排查锁等待:

SELECT	* FROM information_schema.INNODB_TRX; -- 事务运行状态

SELECT	* FROM information_schema.INNODB_LOCK_WAITS; -- 谁在等谁

排查结果如图:

 

老菜鸟0217
老菜鸟0217
回复 @OLESHI : 只是你不知道谁在修改而已,报错已经很明显:Lock wait。。。
O
OLESHI
并没有人在修改。。。
0
hzajie
hzajie

给你一点提示,如果你表是3w数据,则请注意,你只有启动行锁进行数据修改的时候,才能提高并发写表的性能和速度,否则很容易锁表,因此,请关注下你的索引以及修改的

0
sprouting
sprouting

很显然,发生了死锁肯定是程序出现了问题,哪个地方出现了没释放或提交。

换连接池 Druid 可以监控sql,可以帮助找到出现问题的代码。

发生死锁后,虽然杀掉了锁的进程,但可能还有其他地方没有释放。

这种问题最好还是在代码上解决,否则会反反复复的出现。我们的系统最近就出现锁的问题,排查了N久发现是以前的一个老项目做大量的复杂查询导致加了S锁,然后导致很多请求堆积。给查询加了 with (nolock)  和重建索引后问题解决

返回顶部
顶部