死锁分析

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 最近新项目上线,在压测和发布生产都出现了好几种死锁情况,分析一二

最近新项目上线,在压测和发布生产都出现了好几种死锁情况,分析一二

死锁日志

日志一:

image.png

日志二:

image.png

日志三:

image.png

这三个死锁日志特别的有意思,都是同一条SQL,但各种组合样的死锁都齐活了

日志一的两条sql,where里面的条件不同;

日志二和日志三sql完全一样,其实是两次调用(同一时刻并发调用),调用条件不同,但在程序处理时这条SQL的where条件一样而已

分析

隔离级别RC

日志一,where里面的条件不同

第一个事务在等待RECORD LOCKS,锁模式为X model;位置在space id 428 page no 178

第二个事务持有RECORD LOCKS,锁模式为X model;位置也在space id 428 page no 178;等待的锁也是RECORD LOCKS,锁模式为X model,也在space id 428 page no 178

这个死锁很是奇怪,同一条sql,都是在索引【idx_tenant_user】上加锁,完全不符合死锁的循环等待特征

这张表上的索引




KEY `idx_collection_no` (`collection_no`) USING BTREE,KEY `idx_uniflag` (`invoice_uiq_flag`) USING BTREE,KEY `idx_tenant_user` (`tenant_id`,`user_id`) USING BTREE

通过explain查看此语句

image.png

索引上看使用idx_tenant_user,也与死锁日志一致,但怎么就死锁了呢?

【SHOW ENGINE INNODB STATUS;】只能显示最终发生死锁时的sql,并不能显示全部的sql,从程序上下文中寻找,发现点蛛丝马迹

image.png

事务2在T1时刻执行了一条根据id更新数据的sql,这条sql会在id聚簇索引上加X锁,还会在二级索引上加X锁,所以先获得了(userid,tenantid)锁,

事务1在T2时刻只能等待

事务2在T3时刻形成了循环等待,deadlock

日志二,sql完全一样

与前面解释,两个并发请求,入参不同,但到这个方法时,sql的条件是一样的

image.png

日志三,sql也完全一样

虽然与日志二的SQL一样,但死锁日志却不同

image.png


为什么同样的SQL,却得出各样的结果?时而collection_no索引在前,时而组合索引在前

苦思几日,在线上跑了下explain,发现了些问题

image.png

原来线上使用的index merge

有官网上有介绍:https://dev.mysql.com/doc/refman/5.6/en/index-merge-optimization.html

MySQL在分析执行计划时发现走单个索引的过滤效果都不是很好,于是对多个索引分别进行条件扫描,然后将多个索引单独扫描的结果进行合并的一种优化操作。合并的方式分为三种:intersection、union和sort_union

index merge 之 intersect,简单而言,index intersect merge就是多个索引条件扫描得到的结果进行交集运算。显然在多个索引提交之间是 AND 运算时,才会出现 index intersect merge.

正因为index merge,所以索引的真正执行顺序是不一样的,也就造成了各种表象

解决

建立联合索引

都使用主键更新

关掉参数index_merge_intersection=off,禁用index_merge功能

参照

MySQL 优化之 index_merge

一个 MySQL 死锁案例分析


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
关于死锁的原因及解决方案
关于死锁的原因及解决方案
173 0
|
7天前
|
算法
死锁的必要条件
互斥条件:同一资源同时只能由一个线程读取 不可抢占条件:不能强行剥夺线程占有的资源 请求和保持条件:请求其他资源的同时对自己手中的资源保持不放 循环等待条件:在相互等待资源的过程中,形成一个闭环 想要预防死锁,只需要破坏其中一个条件即可,银行家算法可以预防死锁
|
6月前
|
Java
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
86 1
什么是死锁?产生死锁的原因?产生死锁的四个必要条件?死锁的避免与预防?
什么是死锁?产生死锁的原因?产生死锁的四个必要条件?死锁的避免与预防?
276 0
|
6月前
|
算法
死锁的一点分析
死锁的一点分析
|
6月前
|
算法 安全
解决死锁的方法
解决死锁的方法
|
算法 安全 Java
死锁的原理
之前在学校学习过程中,很少写多进程的代码,虽然操作系统中学过死锁相关的内容,但考试过后也基本就忘记了,后来自己也遇到过有些多进程死锁的情况,再加上看了有些资料,对死锁才算是有了有些深入的理解。
82 0
|
设计模式
【并发技术04】线程技术之死锁问题
【并发技术04】线程技术之死锁问题
|
SQL 调度 数据库
浅谈死锁原理
死锁是两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序请求同一组锁的时候。
179 0
浅谈死锁原理
|
SQL 存储 Oracle