前段时间系统老是出现update死锁,很是纠结。经过排查发现是间隙锁!间隙锁是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参数来取消间隙锁从而达到避免这种情况的死锁的方式尚待商量, 那就只有修改代码逻辑, 存在才删除,尽量不去删除不存在的记录。

转自; http://blog.csdn.net/andyxm/article/details/44810417

关于mysql 间隙锁的更多相关文章

  1. MySQL 间隙锁

    一.根据案例二:不同索引加锁顺序的问题,模拟重现死锁(详细操作步骤) 1.RR级别下,更新操作默认会加行级锁,行级锁会对索引加锁 2.如果更新语句使用多个索引,行级锁会先锁定普通索引,再锁定聚簇索引 ...

  2. mysql 间隙锁专题

    本文研究记录mysql间隙锁,涉及以下情况 唯一索引 非唯一索引 范围更新 等值更新 mysql8 mysql7 RR RC 数据准备 mysql> select * from vodb.tes ...

  3. Mysql 间隙锁原理,以及Repeatable Read隔离级别下可以防止幻读原理(百度)

    Mysql知识实在太丰富了,前几天百度的面试官问我MySql在Repeatable Read下面是否会有幻读出现,我说按照事务的特性当然会有, 但是面试官却说 Mysql 在Repeatable Re ...

  4. MySQL间隙锁问题

    间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间. 最近用户反馈说系统老是出现insert时,等待超时了,最后发现是ins ...

  5. mysql间隙锁

    什么是间隙锁(gap lock)? 间隙锁是一个在索引记录之间的间隙上的锁. 间隙锁的作用? 保证某个间隙内的数据在锁定情况下不会发生任何变化.比如我mysql默认隔离级别下的可重复读(RR). 当使 ...

  6. mysql间隙锁 转

    前面一文 mysql锁 介绍了mysql innodb存储引擎的各种锁,本文介绍一下innodb存储引擎的间隙锁,就以下问题展开讨论 1.什么是间隙锁?间隙锁是怎样产生的? 2.间隙锁有什么作用? 3 ...

  7. Mysql innodb 间隙锁

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

  8. Mysql锁机制--间隙锁的危害

    Mysql 系列文章主页 =============== 1 准备数据 1.1 建表 DROP TABLE IF EXISTS employee; CREATE TABLE IF NOT EXISTS ...

  9. Mysql加锁过程详解(9)-innodb下的记录锁,间隙锁,next-key锁

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

随机推荐

  1. jquery和dom对象相互转化的方法

    jQuery对象转成DOM对象: 两种转换方式将一个jQuery对象转换成DOM对象:[index]和.get(index); (1)jQuery对象是一个数据对象,可以通过[index]的方法,来得 ...

  2. Http缓存知识;HTTPS, HTTP2相关知识;百度统计和即时线上客服。

    安装 : 百度统计 来统计用户流量, Intercom 来做即时线上客服. 这两个是 JavaScript 插件放在 HTML 上的. HTTP缓存: https://developers.googl ...

  3. windows下的IO模型之完成端口

    本文整理于:http://blog.csdn.net/piggyxp/article/details/6922277 一. 完成端口的优点 完成端口会充分利用Windows内核来进行I/O的调度,是用 ...

  4. Coderforce 560B-Gerald is into Art

    题目大意:给了三个矩形的长和宽,问第一个能否把其他两个装在内部,要求内部之间不重叠,不出界(可重边)? 题目分析:这道题...考虑不够全面导致比赛时没有出来...当时,就是觉得自己的代码很完美,不可能 ...

  5. oracle问题集棉

    1. 在未安装orcale客户端时,使用pl/sql登录数据库服务器时,报错ORA -12543:TNSdestination host unreachable 2.无法通过ip地址远程连接ORACL ...

  6. Beta阶段第1周/共2周 Scrum立会报告+燃尽图 03

    作业要求与 [https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284] 相同 版本控制:https://git.coding.net/li ...

  7. Scrum冲刺博客(总)

    一.在 Alpha 阶段认领的任务 二.明日任务安排 成员 任务 任务量/小时 陈伟泽 项目进度把控 1 李嘉廉 24点算法" Stack数据结构实现,生成不重复的算式(考虑结合律和结合律) ...

  8. 2019年微信小程序1月TOP100榜单

  9. C++的explicit关键字

    C++程序员对于explicit这个关键字其实不是很熟悉,至少我是如此:原因在于其使用范围不大,而且作用也没有那么大. 但是这不是说明我们的程序中不需要这个关键字,按Google的C++编程规范和Ef ...

  10. Python学习思维导图

     刚学习Python时,边学边总结的,采用思维导图的形式, 适合回顾使用.内容参考<Python:从入门到实践>一书.   再给出一张Datacamp网站上的一张关于Python基础的总结 ...