insert ... on duplicate key update产生death lock死锁原理
转载自 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
2、在有可能有并发事务执行的insert 的内容一样情况下不使用该语句
insert ... on duplicate key update产生death lock死锁原理相关推荐
- “ INSERT IGNORE”与“ INSERT…ON DUPLICATE KEY UPDATE”
在执行包含多行的INSERT语句时,我想跳过重复的条目,否则它们会导致失败. 经过研究后,我的选择似乎是使用以下任一方法: ON DUPLICATE KEY UPDATE ,这意味着要付出一定的代价进 ...
- MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况
MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况 在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句 ...
- insert...on duplicate key update语法详解
一.作用和使用场景 在mysql入库时,不能出现两条数据主键一致的情况,因为在两条数据的主键一致的情况下,mysql就会判定为待插入数据在数据库中存在重复数据,也就是说判断数据是否重复是根据主键来区别 ...
- mysql使用INSERT INTO ON DUPLICATE KEY UPDATE导致dead lock分析和解决
一.事件回放 2019年1月的几天时间里每天会收到1次或者2次死锁的短信告警,死锁日志如下图. 二.检查业务场景和程序处理流程 用户打赏礼物请求处理,涉及到用户余额表和佣金账户表,以下所有操作在一个事 ...
- (转载)[MySQL技巧]INSERT INTO… ON DUPLICATE KEY UPDATE
(转载)http://blog.zol.com.cn/2299/article_2298921.html MySQL 自4.1版以后开始支持INSERT - ON DUPLICATE KEY UPDA ...
- MySQL的INSERT INTO··· ON DUPLICATE KEY UPDATE使用的几种情况
保存或更新 在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新:如 ...
- 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 ...
- mysql insert into on_MySQL之INSERT INTO ON DUPLICATE KEY UPDATE用法详解 | 夕辞
MySQL数据库使用中如果主键或唯一键冲突,会报错,因此我们会用到insert into on duplicate key update语法,但是该语法具体怎么用以及返回什么值,今天就来讨论下. 首先 ...
- 为什么不建议使用ON DUPLICATE KEY UPDATE
昨天评审代码时,大佬同事看到我代码里使用了mysql的on duplicate key update语法实现了对数据的save or update,说这个语法有严重的性能和其他隐患问题,让我必须改成先 ...
最新文章
- 原理分析之三:初始化(配置文件读取和解析)
- Java程序设计第三次作业
- 深度学习总结——CS231n课程深度学习(机器视觉相关)笔记整理
- js兼容注意事项--仅供参考
- GDC2017分享:移动VR开发者的赚钱之道
- d778: NOIP2009 2.Hankson的趣味题
- Hive分桶(bucket)
- activity绑定service
- php程序301重定向,php 301重定向的实现方法
- idea本地运行JavaWeb项目
- git 存在多个commit 时将修改,追加到某次commit 上
- 永磁直驱风机matlab模型,直驱永磁最大功率捕捉matlab仿真建模模型(风力发电)...
- 得物(毒)APP,8位抽奖码需求,这不就是产品给我留的数学作业!
- Android初学者的疑惑与“死板”的Android初学之路
- 如何实现一个简单的过滤器
- 关于DES加密强制更新版(4.22)
- Java用“埃氏筛法”求素数
- 财务人员怎么用python_财务人员有必要学习Python语言吗?
- java-php-python-springboot图书借阅管理系统计算机毕业设计
- DUILIB异形窗口实现
热门文章
- Linux中 安装centos-release-scl 报错No package centos-release-scl available.
- 一个例子带你搞懂python作用域中的global、nonlocal和local
- [PAT乙级]1023 组个最小数
- Java连接Mysql数据库警告:Establishing SSL connection without server's identity verification is not recommend
- 2019-03-13-算法-进化(验证回文串)
- Mr. Panda and Kakin(拓展欧几里得 + O(1)快速乘)
- 【Hitachi2020C】ThREE【构造】【二分图染色】
- [树链剖分][SDOI 2011]染色,Housewife Wind
- ARC132D-Between Two Binary Strings【贪心】
- Loj#6039-「雅礼集训 2017 Day5」珠宝【四边形不等式,dp】