专栏首页DDD死锁分析

死锁分析

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

死锁日志

日志一:

日志二:

日志三:

这三个死锁日志特别的有意思,都是同一条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查看此语句

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

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

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

事务1在T2时刻只能等待

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

日志二,sql完全一样

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

日志三,sql也完全一样

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


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

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

原来线上使用的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 死锁案例分析

本文分享自微信公众号 - 码农戏码(coder-game),作者:朱先生

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MySQL死锁分析

    当业务并发比较高时,如果数据库访问设计得不合理,可能时不时就爆出一个死锁错误。业务上表现为一个偶现的失败。这种情况,有时候非常让人抓狂,感觉无从入手。这里就介绍...

    海伯利安
  • 死锁分析延续

    update ? where userid=? and tenantid=? and no=?;如果先走(tenantid,userid) 则是日志一

    码农戏码
  • 一个死锁分析过程

    第一步的目标是找到锁被谁持有了,这只需要找到死锁的位置,然后查看pthread_mutex_t.__owner值是什么。接下来使用GDB的“info thr...

    一见
  • mysql insert duplicate key update 死锁分析

    数据入库这块有离线和实时两套入库系统,写同一个db的同一批mysql表,两边用的都是insert into table on duplicate key upd...

    YG
  • 一次线上Mysql死锁分析

    这个表用来保存用户的收货地址,下单时需要选择相应的收货地址;通过查看日志平台日志,出问题的主要发生在添加地址的场景。

    心平气和
  • TaobaoProtectSE.dll 注入引起的死锁分析

    一个以前运行良好的 Windows 程序,在添加了少量功能之后,在若干台测试机中的某一台上运行后一直得不到预期结果,并且能比较高机率地复现。排错过程如下:

    mzlogin
  • 死锁分析以及检测工具详解

    死锁:线程1等待线程2的互斥持有资源,而线程2等着线程1的互斥持有资源,两个线程都无法进行执行。

    JAVA葵花宝典
  • PostgreSQL 死锁与分析

    任何数据库都有死锁,MYSQL的死锁有相关的工具,或者去日志查找,postgresql的死锁又怎么搞,今天的来说说。

    AustinDatabases
  • 两次死锁的分析

    以上过程,因为S锁升级为X锁的时间间隔很短,所以不是很好复现,一般在高并发的时候出现。不过可以用3个事务来复现:

    十毛
  • insert事务产生duplicate key error引发的死锁分析

    先看程序报错: 2017-06-12 21:18:40.856 [ForkJoinPool.commonPool-worker-12] ERROR com....

    MySQL轻松学
  • 记一次排查DB死锁的分析

    文章摘要 在线上环境遇到数据库死锁问题该如何分析并解决问题呢? 虽然很多童鞋在学数据库课程时都了解数据库隔离级别、死锁和事务等概念,但在测试/线上环境遇到死锁却...

    企鹅号小编
  • Mysql查询语句使用select.. for update导致的数据库死锁分析

    近期有一个业务需求,多台机器需要同时从Mysql一个表里查询数据并做后续业务逻辑,为了防止多台机器同时拿到一样的数据,每台机器需要在获取时锁住获取数据的数据段,...

    李红
  • 一个AB锁死锁问题分析

    1,查看dmesg日志可以看到node在重启前确实出现频繁的cgroup oom:

    chudihuang
  • 一个Linux死锁信息分析

    这个事情很奇怪,我不觉得它提出来的Possible unsafe locking scenario真的会死锁啊。

    猿哥
  • 数据库死锁怎么分析?

    我们为hero表的id列创建了聚簇索引,为name列创建了一个二级索引。这个hero表主要是为了存储三国时的一些英雄,我们向表中插入一些记录:

    Bug开发工程师
  • 【MySQL】mysql死锁以及死锁日志分析

    死锁:死锁一般是事务相互等待对方资源,最后形成环路造成的。 对于死锁,数据库处理方法:牺牲一个连接,保证另外一个连接成功执行。 发生死锁会返回ERR...

    用户5522200
  • MySQL锁等待与死锁问题分析

    在 MySQL 运维过程中,锁等待和死锁问题是令各位 DBA 及开发同学非常头痛的事。出现此类问题会造成业务回滚、卡顿等故障,特别是业务繁忙的系统,出现死锁问题...

    MySQL技术
  • ​insert on duplicate key死锁问题分析

    开始今天的文章之前,先说明下昨天文章中的一个错误,昨天文章最后说replace into带来的死锁问题可以使用insert into duplicate...

    AsiaYe
  • MySQL批量更新死锁案例分析

    问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下:

    业余草

扫码关注云+社区

领取腾讯云代金券