前段时间系统老是出现insert死锁,很是纠结。经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围。间隙锁的主要作用是为了防止出现幻读,但是它会把锁定范围扩大,有时候也会给我们带来麻烦,我们就遇到了。 在数据库参数中, 控制间隙锁的参数是:innodb_locks_unsafe_for_binlog, 这个参数默认值是OFF, 也就是启用间隙锁, 他是一个bool值, 当值为true时表示disable间隙锁。那为了防止间隙锁是不是直接将innodb_locaks_unsafe_for_binlog设置为true就可以了呢? 不一定!而且这个参数会影响到主从复制及灾难恢复, 这个方法还尚待商量。

间隙锁的出现主要集中在同一个事务中先delete 后 insert的情况下, 当我们通过一个参数去删除一条记录的时候, 如果参数在数据库中存在, 那么这个时候产生的是普通行锁, 锁住这个记录, 然后删除, 然后释放锁。如果这条记录不存在,问题就来了, 数据库会扫描索引,发现这个记录不存在, 这个时候的delete语句获取到的就是一个间隙锁,然后数据库会向左扫描扫到第一个比给定参数小的值, 向右扫描扫描到第一个比给定参数大的值, 然后以此为界,构建一个区间, 锁住整个区间内的数据, 一个特别容易出现死锁的间隙锁诞生了。

举个例子:
表task_queue
Id           taskId
1              2
3              9
10            20
40            41

开启一个会话: session 1

sql> set autocommit=0;

##

取消自动提交

sql> delete from task_queue where taskId = 20;
sql> insert into task_queue values(20, 20);

在开启一个会话: session 2

sql> set autocommit=0;

##

取消自动提交

sql> delete from task_queue where taskId = 25;
sql> insert into task_queue values(30, 25);

在没有并发,或是极少并发的情况下, 这样会可能会正常执行,在Mysql中, 事务最终都是穿行执行, 但是在高并发的情况下, 执行的顺序就极有可能发生改变, 变成下面这个样子:
sql> delete from task_queue where taskId = 20;
sql> delete from task_queue where taskId = 25;
sql> insert into task_queue values(20, 20);
sql> insert into task_queue values(30, 25);

这个时候最后一条语句:insert into task_queue values(30, 25); 执行时就会爆出死锁错误。因为删除taskId = 20这条记录的时候,20 --  41 都被锁住了, 他们都取得了这一个数据段的共享锁, 所以在获取这个数据段的排它锁时出现死锁。

这种问题的解决办法:前面说了, 通过修改innodb_locaks_unsafe_for_binlog参数来取消间隙锁从而达到避免这种情况的死锁的方式尚待商量, 那就只有修改代码逻辑, 存在才删除,尽量不去删除不存在的记录。

Mysql innodb 间隙锁相关推荐

  1. mysql innodb 间隙锁_MySQL中InnoDB的间隙锁问题

    在为一个客户排除死锁问题时我遇到了一个有趣的包括InnoDB间隙锁的情形.对于一个WHERE子句不匹配任何行的非插入的写操作中,我预期事务应该不会有锁,但我错了.让我们看一下这张表及示例UPDATE. ...

  2. mysql innodb 间隙锁_Mysql innodb 间隙锁

    前段时间系统老是出现insert死锁,很是纠结.经过排查发现是间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围.间隙锁的主要作用是为了防止出现 ...

  3. MySQL InnoDB update锁表问题Record Locks

    最近做的项目中出现了锁表的问题,导致表无法进行事务(DML)操作,经过排查发现,我们项目中的购物车表有个字段cart_id为uuid类型,并且未设置索引,这里的场景是根据cart_id进行更新内容,M ...

  4. 从一个死锁看mysql innodb的锁机制

    2019独角兽企业重金招聘Python工程师标准>>> 背景及现象 线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作.经过DBA的分析,是某一张表的inse ...

  5. MySQL InnoDB引擎锁的总结

    为什么要锁 我们开的的各式各样系统中,系统运行需要CPU.内存.I/O.磁盘等等资源.但除了硬资源外,还有最为重要的软资源:数据. 当人们访问操作我们的系统时,其实归根是对数据的查看与生产.那么对于同 ...

  6. mysql隐式锁定辅助索引_当Mysql - InnoDB行锁遇到复合主键和多列索引-Go语言中文社区...

    背景 今天在配合其他项目组做系统压测,过程中出现了偶发的死锁问题.分析代码后发现有复合主键的update情况,更新复合主键表时只使用了一个字段更新,同时在事务内又有对该表的insert操作,结果出现了 ...

  7. mysql innodb 全表锁,Mysql InnoDB行锁及表锁分享

    一. 背景知识 二. 步入正题:表锁和行锁 1.1. 表锁 vs 行锁 在 MySQL 中锁的种类有很多,但是最基本的还是表锁和行锁:表锁指的是对一整张表加锁,一般是 DDL 处理时使用,也可以自己在 ...

  8. MySql进阶-间隙锁(gap-key)

    文章目录 Innodb锁算法 关闭Gap Lock Gap-key 解决的问题 间隙锁影响 MVCC 核心原理 ReadView 可参考 快照读,当前读可参考 参考<InnoDB存储引擎> ...

  9. mysql innodb 的锁机制_Mysql之Innodb锁机制详解

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.关于事务我们之前有专题介绍,这里就着重介绍下它的锁机制. 总的来说,InnoDB按照不同的分类共有 ...

最新文章

  1. 【android9.0】system/core下的usbhost模块无法输出log到logcat
  2. 翻译:Google大表(BigTable)
  3. python 语音识别机器人控制系统_python人脸识别+语音识别 的监控系统
  4. (软件工程复习核心重点)第一章软件工程概论-第二节:软件工程
  5. 1.4.2 solr字段类型--(1.4.2.4)使用Dates(日期)
  6. lcy mysql爆破_Lcy’s Blog
  7. 你是农村人吗,小时候放过牛吗,都有哪些好玩的趣事?
  8. 20210119:力扣第42周双周赛(下)
  9. [1] 图像预处理----图像灰度化处理
  10. 《计算机网络》谢希仁第七版课后答案完整版
  11. vaspkit使用_Vaspkit做电荷密度差图
  12. 考研复试数据库原理课后习题(七)——数据库设计
  13. DeepCross(DCN)模型及torch实现
  14. Activiti7-流程初体验
  15. 三口烧瓶规格有哪些_什么是三口烧瓶,应该如何制作 | | 化工资讯网
  16. “已成功与服务器建立连接,但是在登录过程中发生错误“的解决方法
  17. $Linux vi/vim编辑器常用命令与用法总结
  18. 计算机组装试卷分析,高中英语试卷分析
  19. java 事件链_Java设计模式——责任链模式(Chain of Responsibility)
  20. 算法设计与分析----马的周游路线

热门文章

  1. 广告业务系统 之 数据中转站 —— “日志中心-实时服务监控”
  2. Powershell 数字转大写中文,数字金额转中文繁体(改自C#)
  3. 作为一个精神病人是一种怎样的体验?
  4. 三菱编程软件GX Works2复制粘贴错位
  5. 数学公式识别神器Mathpix,零错误高效率
  6. Unity 简单随机创建玩家游戏名
  7. 标签纸张如何在条码打印软件中进行设置
  8. 【C语言 实现图书管理系统】
  9. 第三方软件测试有什么作用?可以包含哪些测试内容?怎么去做第三方检测?
  10. 【uniapp】根据身份证号获取生日日期