首页
学习
活动
专区
工具
TVP
发布

记一次高并发 Deadlock

Deadlock

关于死锁

在做认列项目时,由于用到了多进程,在高并发场景下,出现了死锁。

死锁并不可怕,可以用来查看最近一次死锁记录,分析找出原因。

PS: 更为妥当的做法是纪录到日志文件,5.6以上只要打开innodb_print_all_deadlocks配置即可,5.5则需要使用,percona-toolkit提供了的脚本pt-deadlock-logger实现

锁是解决多线程资源竞争的一种方法,mysql的锁就是解决事务间对数据检索更新的竞争,保证数据一致性的重要手段。

此前,我们要先了解innodb的锁

PS: 还有IX 和IS 这里为了方便说明,简化了锁

X:排他锁(读写锁)

更新、删除数据时用,阻塞其他线程对数据的读写操作

S:共享锁(写锁)

读取数据时用,阻塞写操作

所以有了很多文章里都提到的锁的相容性:

两个线程同时获取共享锁是相容的,不会出现锁的竞争;

只有有一个线程获取排他锁,就会与另外一个线程的锁冲突,产生竞争,从而有机会产生死锁。

下面看认列项目触发的死锁例子

在上面的日志我们可以看到,首行有具体的日期

接下来就是案发现场

我们首先来关注

这两行就是两个事务涉及到的SQL,正是这两个SQL引发了惨案,这里有助与我们定位程式的位置

再来看

这两行说明了两个事务锁住的行数

undo log entries 3 表示事务#2有将三行纪录到了回滚队列

接着看

重点在RECORD LOCKS… 三行

RECORD LOCKS 表明是行锁,锁住的是索引Indexof table.指出具体锁住或等待锁的索引是哪一个,属于哪个表

trx id 是事务的ID,事务ID说明了事务的执行顺序

lock_mode 表示锁的类型,X 排他锁,S 共享锁,还有IX,IS意向锁

好了,解释这么多,现在我们可以来重现案件

1.事务#2执行更新SQL,并获取了索引revenue_summary_status_index的行锁

2. 事务#2 还没提交,事务#1 执行了新的SQL,并申请了revenue_summary_status_index 的行锁,再等待事务#2 的锁释放

解决死锁的思路,就是降低锁的颗粒度。

本次问题是索引锁,通过降低索引数据颗粒度的方式解决,建立一个联合索引(user_id, status)。

数据颗粒度可以使用 Explain 命令验证 SQL 的扫描行数,行数越少,颗粒度越少,并发性能越高。

根据日志来看,死锁的危害就是数据一致性被破坏,获取了低权重锁的事务被回滚。

譬如并发提交订单,会出现某些订单被回滚,没有执行成功,造成会员订单无法正常开启

再譬如在我们8891使用的搜寻临时表,批量更新物件数据时,也会出现。

所以偶尔有会员反应,他的物件没有被及时更新,需要再做修改才会更新。

要解决死锁危害:降低锁粒度,捕捉死锁异常

需要尽量在重要流程使用显式事务,避免被数据逻辑被破坏,捕捉事务异常,对异常进行逻辑处理

增加必要的索引,定期检查慢速、死锁日志,针对业务的 SQL 进行索引优化

结语:

本文更多的是介绍如何通过理解死锁日志,针对性的解决问题。更多死锁、innodb 特性的细节可以查看参考文章,也欢迎大家留言讨论、指正。

我们大部分场景都处在IO密集型,所以大部分性能瓶颈,也都在IO、DB这些较后的服务,然后才是代码层。定期的对IO、DB优化,可以解决大部分的性能问题。

参考:

https://dev.mysql.com/doc/refman/5.5/en/innodb-locking.html

https://dev.mysql.com/doc/refman/5.5/en/innodb-deadlocks.html

https://www.percona.com/blog/2014/10/28/how-to-deal-with-mysql-deadlocks/

https://dba.stackexchange.com/questions/116113/meaning-of-locks-rec-but-not-gap-waiting-in-deadlock-report

http://mysql.taobao.org/monthly/2015/07/05/

https://www.packtpub.com/books/content/optimizing-your-mysql-servers-performance-using-indexes

https://www.alibabacloud.com/forum/read-515

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180112G0G18L00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券