mysql innodb死锁问题详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013380694/article/details/79041711

一 首先发现问题

1 最近旅游电商平台对外提供的接口经常有终端用户反映请求超时异常 。

2 进过排查服务器日志有报错,错误信息如下:

ERROR 1205 (HY000): Lockwait timeout exceeded; try restarting transaction

二 了解环境情况

3 了解平台使用的是mysql 数据库版本5.6.34 存储引擎是innodb。

4 推断是mysql innodb 死锁问题。

三 快速非完美解决问题

5 查看数据库隔离级别如下图:

数据库隔离级别 Read Uncommitted(读取未提交内容) Read Committed(读取提交内容)Repeatable Read(可重读) Serializable(可串行化)

6 去查看先当前库的线程情况

 

没有看到正在执行的慢SQL记录线程,再去查看innodb的事务表INNODB_TRX,看下里面是否有正在锁定的事务线程,看看ID是否在show full processlist里面的sleep线程中,如果是,就证明这个sleep的线程事务一直没有commit或者rollback而是卡住了

SELECT * FROM information_schema.INNODB_TRX G;


看到有这条9930577的sql,kill掉,执行kill 9930577;

Ok 问题就非完美解决了

7 小结

表数据量也不大,按照普通的情况来说,简单的update应该不会造成阻塞的,mysql都是autocommit,不会出现update卡住的情况,去查看下autocommit的值。

mysql> select @@autocommit;

| @@autocommit |

+--------------+

|        0 |

1 row in set (0.00 sec)

看到亮闪闪的0,这个设置导致原来的update语句如果没有commit的话,你再重新执行update语句,就会等待锁定,当等待时间过长的时候,就会报ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction的错误。

所以赶紧commit刚才执行的update语句,之后 set global autocommit=1;

四 彻底解决问题

8

Innodb 关于锁的表有三个

在5.5中,information_schema 库中增加了三个关于锁的表(MEMORY引擎):

innodb_trx        ## 当前运行的所有事务

innodb_locks      ## 当前出现的锁

innodb_lock_waits ## 锁等待的对应关系

9 直接使用show engine innodbstatus查看

先使用innodb_lock_monitor来获取阻塞锁线程

CREATE TABLE `innodb_lock_monitor` (

  `a` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8; ## 随便在一个数据库中创建这个表,就会打开lock monitor  

      然后再使用show engineinnodb status查看

 

从以上很容易就分析出了有两个问题,一个是由于使用了唯一外索引导致的`xixing`.`t_mp_message_config`表的fk_mf_user 索引shopId字段是唯一的索引,然后插入已经存在的shopId 导致行锁住,事务不能提交。

第二个是因为`mp_zshl`.`seller_consume_code` trx id 31375933 lockmode IX 表被锁住,锁是IX 互斥锁。

从以上就很容易定位到代码具体位置 ,然后从代码处尽量屏蔽这种情况发生。

 

10. 结论

在分析innodb中锁阻塞时,几种方法的对比情况:

(1)  使用show processlist查看不靠谱;

(2)  直接使用show engine innodb status查看,无法判断到问题的根因;

(3)  使用mysqladmin debug查看,能看到所有产生锁的线程,但无法判断哪个才是根因;

(4)  开启innodb_lock_monitor后,再使用showengine innodb status查看,能够找到锁阻塞的根因。

四 参考

blog地址:http://blog.csdn.net/hw_libo/article/details/39080809

http://stackoverflow.com/questions/5836623/getting-lock-wait-timeout-exceeded-try-restarting-transaction-even-though-im getting-lock-wait-timeout-exceeded-try-restarting-transaction-even-though-im 

http://blog.csdn.net/hw_libo/article/details/39080809 MySQL锁阻塞分析

http://blog.sina.com.cn/s/blog_6bb63c9e0100s7cb.html MySQL innodb_lock_wait 锁等待

http://dev.mysql.com/doc/refman/5.6/en/innodb-information-schema-understanding-innodb-locking.html mysql5.6官方文档

猜你喜欢

转载自blog.csdn.net/u013380694/article/details/79041711
今日推荐