前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发replace操作导致的死锁问题

并发replace操作导致的死锁问题

作者头像
翎野君
发布2023-05-12 20:48:17
4550
发布2023-05-12 20:48:17
举报
文章被收录于专栏:翎野君翎野君

背景

批量对一张表进行replace into操作,每个SQL操作1000条数据,最近有同事反馈使用并发replace操作的时候,遇到了死锁的问题。针对这个问题,我看了看表的结构,发现表中有一个主键,一个唯一索引,然后用replace的操作去对表中的记录进行插入,如果存在相同的唯一索引,那么就更新这条记录。

探究

开始分析这个问题之前,我们首先对replace into这个语法做个简单了解,replace into的语法是当我们不确定即将插入的记录是否存在唯一性冲突时,可以通过Replace into的方式让MySQL自动处理:当存在冲突时,会把旧记录替换成新的记录。

假设我们有表test

代码语言:javascript
复制
create table test (
a int auto_increment primary key,
b int,
c int,
unique key (b)
);

那么一个replace into的语句执行过程可能如下:

上面的图中,有几点需要解释:

1、当我们判断唯一索引的记录是否唯一时,需要对该条记录加上X锁,也就是第2步下面的判断时,需要加X锁

2、第5步检测该唯一索引,并对索引上的记录加X锁,在这个过程中,对于唯一索引对应的聚集索引记录,也需要加X锁。

3、第5步后面的条件判断的内容如下:

  • 如果发生uk冲突的索引是最后一个唯一索引、没有外键引用、且不存在delete trigger时,使用UPDATE ROW的方式来解决冲突;
  • 否则,使用DELETE ROW + INSERT ROW的方式解决冲突。

详见:淘宝数据库月报

4、第6步和第7步,本质上是在更新唯一索引列上的记录。

5、第8步需要更新聚集索引列上的记录,该过程中,如果插入位置的下一条记录上存在记录锁,那么在插入时,当前session需要对其加插入意向锁,具体类型为LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION。这也是导致死锁的关键点之一

死锁成因分析:

1、假设我们有两个会话,也就是session

2、session1执行到第6或者第7步,准备更新唯一索引和聚集索引记录,更新前,需要持有该唯一索引和聚集索引的记录锁,假设该记录是unique key=2020的一条记录

3、此时session2发现了唯一索引冲突,也就是图中第2步下面的"判断重复记录"过程中,出现了索引冲突,也在记录上加X锁,假设该记录是unique key=2021的一条记录

4、session 1 在标记删除记录后,尝试插入新的unique key记录,发现预插入记录2020的下一条记录2021上有锁请求,因此尝试加插入意向X锁,导致死锁产生。

相关文章:

http://mysql.taobao.org/monthly/2015/03/01/

https://cloud.tencent.com/developer/article/1574074

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 探究
    • 上面的图中,有几点需要解释:
      • 死锁成因分析:
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档