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

摘要:
对于insert,uplicatekeyupdate语句将导致解除锁定问题。官方文件没有对其进行描述,但对其进行了如下描述:AnINSERT ONDUPLICATEKEYUPDATEEstategainstablehave more one unique or primarykey is also market dasafe。也就是说,如果一个表定义有多个唯一键或主键,那么它是不安全的。这引发了另一个问题。看见https://bugs.mysql.com/bug.php?id=58637也就是说,当mysql执行INSERTONUPLICATEKEY的INSERT时,存储引擎将检查插入的行是否会生成重复的键错误。如果是这样,它将把现有的行返回给mysql,mysql将更新该行并将其发送回存储引擎。例如,InnoDB按照索引添加到表中的顺序检查键。

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

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

具体的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 的内容一样情况下不使用该语句
---------------------
作者:个人技术博客-潘民兰
来源:CSDN
原文:https://blog.csdn.net/pml18710973036/article/details/78452688
版权声明:本文为博主原创文章,转载请附上博文链接!

免责声明:文章转载自《死锁问题------------------------INSERT ... ON DUPLICATE KEY UPDATE*(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇hwclock和date源码分析Google Chrome浏览器开发人员工具(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

App 抓包提示网络异常怎么破?(抓包HTTPS)

  背景 当你测试App的时候,想要通过Fiddler/Charles等工具抓包看下https请求的数据情况,发现大部分的App都提示网络异常/无数据等等信息。以“贝壳找房”为例: Fiddler中看到的请求是这样的: 你可能开始找证书的问题:是不是Fiddler/Charles的证书没有导入的手机中去?配置一遍又一遍,又开始对比web端浏览器的ht...

vue之vue-cookies

npm链接:https://www.npmjs.com/package/vue-cookies 安装: npm install vue-cookies --save 使用:main.js引入 import Vue from 'Vue' import VueCookies from 'vue-cookies' Vue.use(VueCookies) Ap...

WebRTC学习(五)WebRTC信令服务器

一:使用socket.io发送消息 (一)socket.io服务端发送消息 broadcast会向站点中的所有房间发送消息 (二)socket.io客户端处理消息 二:WebRTC信令服务器 (一)信令服务器(TCP)作用 1.媒体相关信息交换:发送SDP描述信息(是否支持音频、视频,已经对应的编解码信息),通过信令服务器进行中转(因为两个客户端...

Red Team内网穿透技术开源工具

文章 https://artkond.com/2017/03/23/pivoting-guide/ https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology and Resources/Network Pivoting Techniques.md#sshuttl...

RT-Thread 在stm小内存系列产品的nano+msh完整移植教程

本教程基于CUBE-MX,搭建环境方便快捷,把更多精力用在移植的实现上。 ps:本次移植基于stm32l151, 理论上和F1系列通用, 和F4系列区别开来。 ps:纯手工搭建环境也是可以,在一个可以输出hello world的demo上进行移植。 ps: 基于官方移植思路,简单快捷,但是要调整一些小细节。 源地址: https://www.rt-thre...

超详细简单小白安装GIT教程

首先找到下载网站https://git-scm.com/官网:下载页面 本教程安装的版本选择安装页面,这里默认为C盘组件安装页面:这里把Windows Explorer integration全选上,这里是让鼠标右键出现安装页面Use a TrueType font in all console windows:在windows控制页面中使用TrueTyp...