前语:不要为了读文章而读文章,一定要带着问题来读文章,勤思考。在此,建议大家为本公众号加“星标”。如文章写得好,望大家阅读后在右下边“在看”处点个赞,以示鼓励!

作者:潘民兰  来源:http://t.cn/AiKrffGF

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

解决办法:

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

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

---------------

看到这里还没过瘾,那么就来群里与更多的同学交流切磋技术,戳这里:咱们来一起抱团取暖,好吗?

---END---

热文推荐

技术团队一般是如何进行代码审查的?

面试官:给我说说你对Java GC机制的理解?

mysql batch insert 遇到错误跳过_这是MySQL的bug吗?相关推荐

  1. mysql batch insert 遇到错误跳过_mysql 主从复制错误如何跳过

    Mysql 5.7 主从复制错误跳过处理 有时候因为一些操作使得mysql主从服务器有些误差,这样复制的时候会产生错误,一般而言我们可以通过逃过错误的方式,让复制继续下去,我们来演示下如何通过操作跳过 ...

  2. 关于mysql错误的是_下面关于MySQL描述错误的是( )。_学小易找答案

    [填空题]<5>/*------------------------------------------------------- [程序填空] 请在注释行SPACE下对应位置[?]处填写 ...

  3. mysql 5.7和8.0区别_前沿观察 | MySQL性能基准测试对比:5.7 VS 8.0

    点小蓝字加关注! 版权声明:本文由腾讯云数据库产品团队整理,页面原始内容来自于severalnines英文官网,若转载请注明出处.翻译目的在于传递更多全球最新数据库领域相关信息,并不意味着腾讯云数据库 ...

  4. mysql数据库默认密码在哪看_怎么查看mysql数据库的登录名和密码

    如何查看mysql数据库的登录名和密码: 通过Windows的服务管理器查看.首先安装Maki5.服务端 "开始"-"运行",输入"services. ...

  5. mysql同步的时候主挂掉了_聊聊关于mysql 主从 同步 问题

    总结:稍微有些规模的网站,基本上都会配置mysql主从复制,一方面用mysql的主从做数据库的读写分离,另一方面mysql本身的单机备份不是很强,一般采用主从架构,在从上进行数据备份. 在MySQL主 ...

  6. mysql数据库最后一步卡住了_[数据库]解决MySQL安装到最后一步未响应的三种方法...

    [数据库]解决MySQL安装到最后一步未响应的三种方法 0 2018-07-13 01:01:27 这种情况一般是你以前安装过MySQL数据库服务项被占用了. 解决方法: 方法一:安装MySQL的时候 ...

  7. MySQL返回多行错误怎么处理_结果包含多个行错误mysql

    我试图通过存储过程获得下一个可用的id,但到目前为止,我无法使其工作.这是我的存储过程 DELIMITER $$ USE `devt`$$ DROP PROCEDURE IF EXISTS `upda ...

  8. mysql单列索引和多列索引_浅谈MySQL索引优化

    索引基础知识总结及常见索引优化手段 一.索引简介 什么是索引? MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 可以简单理解为"排好序的快速查找数据 ...

  9. mysql锁机制为何设计如此复杂_再谈mysql锁机制及原理—锁的诠释

    加锁是实现数据库并发控制的一个非常重要的技术.当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁.加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更 ...

最新文章

  1. !Important:CSS中!important的作用用于Ie6.0 与Ie7.0、firefox
  2. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图
  3. 50万数据生成6位数不重复字符串_R语言系列3:高级数据管理
  4. 程序控制发送文件到邮箱_Kindle电子邮箱推送
  5. 以太坊服务器是什么_OKEX区块链60讲 | 第33集:什么是以太坊?
  6. 不会真的有人拿了上万甚至几十万在网络上赌博吧?
  7. 在vue的项目中引入swiper插件
  8. 极客大学架构师训练营 性能测试 性能优化 第七次作业
  9. 腾讯WebQQ 3.0 密码、验证码加密算法分析
  10. 讲解wpe抓包,封包
  11. Mac 解决 Font family [“sans-serif”] not found , Glyph xxx missing from current font 的问题
  12. 打印机、惠普打印机扫描分辨率低,扫描出来模糊,解决办法
  13. 数据预处理Part8——数据共线性
  14. Bundle adjustment
  15. 网易互娱耗时最长的活动
  16. 第三篇 香橙派的外设开发基础(中)— 串口篇
  17. 在线PDF转换PPT,不用安装软件
  18. 图像处理-最常见面试题(必问)
  19. [转帖]GT4 奖励车一览
  20. [附源码]Java计算机毕业设计SSM东北鹿产品售卖网站

热门文章

  1. 力扣: 268. 丢失的数字
  2. 自动化测试框架搭建-邮件-5
  3. Jedis的Spring配置
  4. android 分组柱状图_整理了一个 android 上的波形图及柱状图绘制控件
  5. python中gettext文件格式_Python locale.gettext方法代码示例
  6. vc++64位系统下long的长度为4个字节_新来的妹子把几百万数据放入了内存,系统立马爆了...
  7. 吐血,经过4个小时,终于发现这个可以解决虚拟机ubuntu不能联网的问题
  8. 并发基础(七):Thread 类的sleep()、yeild()、join()
  9. 算法--360面试:使用递归实现:a0=1,a1=1;a2=a0+a1;a3=a1+a2...以此类推,求a30
  10. LeetCode打卡 52八皇后Ⅱ53最大子序和54螺旋矩阵