前言

编辑

我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用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 的内容一样情况下不使用该语句

https://blog.csdn.net/pml18710973036/article/details/78452688

INSERT ... ON DUPLICATE KEY UPDATE产生death lock死锁原理的更多相关文章

  1. 死锁问题------------------------INSERT ... ON DUPLICATE KEY UPDATE*(转)

    前言    我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE K ...

  2. mysql 插入重复值 INSERT ... ON DUPLICATE KEY UPDATE

    向数据库插入记录时,有时会有这种需求,当符合某种条件的数据存在时,去修改它,不存在时,则新增,也就是saveOrUpdate操作.这种控制可以放在业务层,也可以放在数据库层,大多数数据库都支持这种需求 ...

  3. INSERT ... ON DUPLICATE KEY UPDATE Syntax

    一 mybatis中返回自动生成的id 当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢.在mysql数据中我们可以在insert下添加一个selectK ...

  4. 可遇不可求的Question之INSERT … ON DUPLICATE KEY UPDATE 语法篇

    MySQL 自4.1版以后开始支持INSERT … ON DUPLICATE KEY UPDATE语法,使得原本需要执行3条SQL语句(SELECT,INSERT,UPDATE),缩减为1条语句即可完 ...

  5. 翻译:insert on duplicate key update(已提交到MariaDB官方手册)

    本文为mariadb官方手册:INSERT ON DUPLICATE KEY UPDATE的译文. 原文:https://mariadb.com/kb/en/insert-on-duplicate-k ...

  6. Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践

    转: Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践 阿里加多 0.1 2018.03.23 17:19* 字数 492 阅读 2613评论 2喜欢 1 一.前 ...

  7. mysql INSERT ... ON DUPLICATE KEY UPDATE语句

    网上关于INSERT ... ON DUPLICATE KEY UPDATE大多数文章都是同一篇文章转来转去,首先这个语法的目的是为了解决重复性,当数据库中存在某个记录时,执行这条语句会更新它,而不存 ...

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

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

  9. INSERT ... ON DUPLICATE KEY UPDATE Syntax 专题

    ON DUPLICATE KEY UPDATE :不用用于批量,除 insert into t1  select * from t2 on duplicated key update k1=v1,k2 ...

随机推荐

  1. 内部类访问外部类方法中的参数-使用final

    public synchronized <T extends MetricsSource> T register(final String name, final String desc, ...

  2. 【C】貌似不友好的scanf()

    scanf语句执行过程: (1)逆序取参数的偏移地址并分别入栈. (2)根据控制字符串的格式说明符从缓冲区取数据给各变量赋值. ①若格式说明符是数值类数据:如果从缓冲区中拿出的第一个字符可以合法表示该 ...

  3. win10 下安装linux子系统

    一.开发人员选项 打开控制面板->程序与功能->启用或关闭windows功能 勾选    [适用于linux的windows子系统]    选项 打开win10设置 找到更新与安全 启动开 ...

  4. bzoj 4711 小奇挖矿 ——“承诺”类树形dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4711 对“承诺”有了更深的了解. 向外和向内要区分,所以 f [ i ][ j ] 表示根向 ...

  5. 洛谷P3385判负环——spfa

    题目:https://www.luogu.org/problemnew/show/P3385 两种方法,dfs和bfs: 一开始写的dfs,要把dis数组初值赋成0,这样从一个连着负边的点开始搜: 在 ...

  6. MTK USB 子系统

    一.USB 子系统初始化 1. kernel/drivers/usb/core/usb.c subsys_initcall(usb_init); static int __init usb_init( ...

  7. openstack封装镜像

    1.准备工作:准备你想要封装的各种镜像的iso,完整版本最简单版本都ok,只要能出虚拟机就行,这个大家去官网下载自己要的iso就可以,我这里用centos6.4最简版本,因为分给我的活让做这个的... ...

  8. 十张Gif动图让你弄懂递归等概念

    图像(包括动图)是传递信息的一种高效方式,往往能增强表象.记忆与思维等方面的反应强度.所谓一图胜千言,说的就是这个道理. 今天为大家整理了十张动图GIFS,有助于认识循环.递归.二分检索等概念的具体运 ...

  9. 4-1逻辑与运算符介绍 & 4-2逻辑或运算符介绍

    后面括号内的(n++)不运算了. 4-2逻辑或运算符介绍

  10. UVaLive 3695 Distant Galaxy (扫描线)

    题意:给平面上的 n 个点,找出一个矩形,使得边界上包含尽量多的点. 析:如果暴力那么就是枚举上下边界,左右边界,还得统计个数,时间复杂度太高,所以我们考虑用扫描线来做,枚举上下边界, 然后用其他方法 ...