转载自  insert ... on duplicate key update产生death lock死锁原理

前言

编辑

我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE KEY UPDATE语句,一条语句就搞定了查询是否存在和插入或者更新这几个步骤,但是使用这条语句在msyql的innodb5.0以上版本有很多的陷阱,即有可能导致death lock死锁也有可能导致主从模式下的replication产生数据不一致。

正文

正如前言说的那样,在实际业务中,曾经有过一个需求就是插入一条业务数据,如果不存在则新增,存在则累加更新某一个字段的值,于是乎就想到了使用insert... on duplicate key update这个语句,但是有一天去测试环境查看错误日志时,却发现了在多个事务并发执行同一条insert...on duplicate key update 语句时,也就是insert的内容相同时,发生 了死锁。

对于insert...on duplicate key update这个语句会引发dealth lock问题,官方文档也没有相关描述,只是进行如下描述:

An INSERT ... ON DUPLICATE KEY UPDATE statement against a table having more than one unique or primary key is also marked as unsafe. (Bug #11765650, Bug #58637)

也就是如果一个表定义有多个唯一键或者主键时,是不安全的,这又引发了以一个问题,见https://bugs.mysql.com/bug.php?id=58637

也就是

     当mysql执行INSERT ON DUPLICATE KEY的 INSERT时,存储引擎会检查插入的行是否会产生重复键错误。如果是的话,它会将现有的
行返回给mysql,mysql会更新它并将其发送回存储引擎。当表具有多个唯一或主键时,此语句对存储引擎检查密钥的顺序非常敏感。根据这个顺序,
存储引擎可以确定不同的行数据给到mysql,因此mysql可以更新不同的行。存储引擎检查key的顺序不是确定性的。例如,InnoDB按照索引添加到
表的顺序检查键。

insert ... on duplicate key 在执行时,innodb引擎会先判断插入的行是否产生重复key错误,如果存在,在对该现有的行加上S(共享锁)锁,如果返回该行数据给mysql,然后mysql执行完duplicate后的update操作,然后对该记录加上X(排他锁),最后进行update写入。

如果有两个事务并发的执行同样的语句,那么就会产生death lock,如:

具体的bug描述见:https://bugs.mysql.com/bug.php?id=52020

https://bugs.mysql.com/bug.php?id=58637

编辑

https://bugs.mysql.com/bug.php?id=21356

解决办法:

1、尽量不对存在多个唯一键的table使用该语句

2、在有可能有并发事务执行的insert 的内容一样情况下不使用该语句

insert ... on duplicate key update产生death lock死锁原理相关推荐

  1. “ INSERT IGNORE”与“ INSERT…ON DUPLICATE KEY UPDATE”

    在执行包含多行的INSERT语句时,我想跳过重复的条目,否则它们会导致失败. 经过研究后,我的选择似乎是使用以下任一方法: ON DUPLICATE KEY UPDATE ,这意味着要付出一定的代价进 ...

  2. MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况

    MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况 在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句 ...

  3. insert...on duplicate key update语法详解

    一.作用和使用场景 在mysql入库时,不能出现两条数据主键一致的情况,因为在两条数据的主键一致的情况下,mysql就会判定为待插入数据在数据库中存在重复数据,也就是说判断数据是否重复是根据主键来区别 ...

  4. mysql使用INSERT INTO ON DUPLICATE KEY UPDATE导致dead lock分析和解决

    一.事件回放 2019年1月的几天时间里每天会收到1次或者2次死锁的短信告警,死锁日志如下图. 二.检查业务场景和程序处理流程 用户打赏礼物请求处理,涉及到用户余额表和佣金账户表,以下所有操作在一个事 ...

  5. (转载)[MySQL技巧]INSERT INTO… ON DUPLICATE KEY UPDATE

    (转载)http://blog.zol.com.cn/2299/article_2298921.html MySQL 自4.1版以后开始支持INSERT - ON DUPLICATE KEY UPDA ...

  6. MySQL的INSERT INTO··· ON DUPLICATE KEY UPDATE使用的几种情况

    保存或更新 在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新:如 ...

  7. mysql insert delayed_mysql insert的几点操作(DELAYED 、IGNORE、ON DUPLICATE KEY UPDATE )

    INSERT语法 INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] V ...

  8. mysql insert into on_MySQL之INSERT INTO ON DUPLICATE KEY UPDATE用法详解 | 夕辞

    MySQL数据库使用中如果主键或唯一键冲突,会报错,因此我们会用到insert into on duplicate key update语法,但是该语法具体怎么用以及返回什么值,今天就来讨论下. 首先 ...

  9. 为什么不建议使用ON DUPLICATE KEY UPDATE

    昨天评审代码时,大佬同事看到我代码里使用了mysql的on duplicate key update语法实现了对数据的save or update,说这个语法有严重的性能和其他隐患问题,让我必须改成先 ...

最新文章

  1. 原理分析之三:初始化(配置文件读取和解析)
  2. Java程序设计第三次作业
  3. 深度学习总结——CS231n课程深度学习(机器视觉相关)笔记整理
  4. js兼容注意事项--仅供参考
  5. GDC2017分享:移动VR开发者的赚钱之道
  6. d778: NOIP2009 2.Hankson的趣味题
  7. Hive分桶(bucket)
  8. activity绑定service
  9. php程序301重定向,php 301重定向的实现方法
  10. idea本地运行JavaWeb项目
  11. git 存在多个commit 时将修改,追加到某次commit 上
  12. 永磁直驱风机matlab模型,直驱永磁最大功率捕捉matlab仿真建模模型(风力发电)...
  13. 得物(毒)APP,8位抽奖码需求,这不就是产品给我留的数学作业!
  14. Android初学者的疑惑与“死板”的Android初学之路
  15. 如何实现一个简单的过滤器
  16. 关于DES加密强制更新版(4.22)
  17. Java用“埃氏筛法”求素数
  18. 财务人员怎么用python_财务人员有必要学习Python语言吗?
  19. java-php-python-springboot图书借阅管理系统计算机毕业设计
  20. DUILIB异形窗口实现

热门文章

  1. Linux中 安装centos-release-scl 报错No package centos-release-scl available.
  2. 一个例子带你搞懂python作用域中的global、nonlocal和local
  3. [PAT乙级]1023 组个最小数
  4. Java连接Mysql数据库警告:Establishing SSL connection without server's identity verification is not recommend
  5. 2019-03-13-算法-进化(验证回文串)
  6. Mr. Panda and Kakin(拓展欧几里得 + O(1)快速乘)
  7. 【Hitachi2020C】ThREE【构造】【二分图染色】
  8. [树链剖分][SDOI 2011]染色,Housewife Wind
  9. ARC132D-Between Two Binary Strings【贪心】
  10. Loj#6039-「雅礼集训 2017 Day5」珠宝【四边形不等式,dp】