关闭

MySQL间隙锁问题

1377人阅读 评论(1) 收藏 举报
分类:

间隙锁(Gap Lock):锁加在不存在的空闲空间,可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间。

最近用户反馈说系统老是出现insert时,等待超时了,最后发现是insert间隙锁!间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围。间隙锁的主要作用是为了防止出现幻读,但是它会把锁定范围扩大,

有时候也会给我们带来麻烦,我们就遇到了。 在数据库参数中, 控制间隙锁的参数是:innodb_locks_unsafe_for_binlog,

这个参数默认值是OFF, 也就是启用间隙锁, 他是一个bool值, 当值为true时表示disable间隙锁。

那为了防止间隙锁是不是直接将innodb_locaks_unsafe_for_binlog设置为true就可以了呢? 不一定!

而且这个参数会影响到主从复制及灾难恢复, 这个方法还尚待商量。

间隙锁的出现主要集中在同一个事务中先delete后 insert的情况下, 当我们通过一个参数去删除一条记录的时候, 

如果参数在数据库中存在,那么这个时候产生的是普通行锁,锁住这个记录, 然后删除, 然后释放锁。如果这条记录不存在,

问题就来了, 数据库会扫描索引,发现这个记录不存在, 这个时候的delete语句获取到的就是一个间隙锁,

然后数据库会向左扫描扫到第一个比给定参数小的值,向右扫描扫描到第一个比给定参数大的值, 然后以此为界,

构建一个区间, 锁住整个区间内的数据, 一个特别容易出现死锁的间隙锁诞生了。

举个例子:
表testLock,有两个属性id,和name.有如下数据。



开启一个会话: session 1


 

sql> set autocommit=0;                 ##取消自动提交
sql> delete from testLock where id =
‘6’;

在开启一个会话: session 2


sql> set autocommit=0;##取消自动提交
sql> insert into testLock(id,name) values(‘6’,’hahaha’);
在没有并发,或是极少并发的情况下, 这样会可能会正常执行,在Mysql中, 事务最终都是穿行执行,
但是在高并发的情况下, 

执行的顺序就极有可能发生改变, 变成下面这个样子:

sql> delete from testLock where id = ‘6’;
sql> insert into testLock(id,name) values(‘6’, ‘hahaha’);
这个时候最后一条语句:insert into testLock(id,name) values(‘6’, ‘hahaha’); 执行时就会爆出死锁错误。因为删除id = 6这条记录的时候,

id为6之后的部分都被锁住了, 他们都取得了这一个数据段的共享锁, 所以在获取这个数据段的排它锁时出现死锁。
这种问题的解决办法:前面说了, 通过修改数据库的参数innodb_locaks_unsafe_for_binlog来取消间隙锁从而达到避免

这种情况的死锁的方式尚待商量, 那就只有修改代码逻辑, 存在才删除,尽量不去删除不存在的记录。


1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Mysql innodb 间隙锁

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

MySQL中的锁(表锁、行锁,共享锁,排它锁,间隙锁)

本文参考: http://mysqlpub.com/thread-5383-1-1.html http://blog.csdn.net/c466254931/article/details/534...
  • soonfly
  • soonfly
  • 2017-04-20 10:54
  • 5950

谈谈Mysql之间隙锁

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

MySQL详解--锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数...
  • xifeijian
  • xifeijian
  • 2014-03-06 23:45
  • 107916

间隙锁(Next-Key锁)

20.3.5 间隙锁(Next-Key锁) 2008-03-27 22:22 唐汉明 翟振兴 兰丽华 关宝军 申宝柱 人民邮电出版社 字号:T | T 综合评级: 想读(11)  在读(4)  已...
  • xiaobluesky
  • xiaobluesky
  • 2015-12-27 13:07
  • 1679

MySQL的GAP LOCK(间隙锁) 的陷阱

http://fucheng.blog.51cto.com/2404495/1619359  mysql(innodb storage engine)的行锁主要是通过在相应的索引记录来实现,作为...
  • bigtree_3721
  • bigtree_3721
  • 2017-06-26 14:36
  • 1247

推荐:mysql锁 innodb下的记录锁,间隙锁,next-key锁

你需要知道的 之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁。 行锁 记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁。 生活中的...
  • bigtree_3721
  • bigtree_3721
  • 2017-06-26 01:06
  • 275

MySQL中的锁(表锁、行锁,共享锁,排它锁,间隙锁)

本文参考: http://mysqlpub.com/thread-5383-1-1.html http://blog.csdn.net/c466254931/article/details/534...
  • soonfly
  • soonfly
  • 2017-04-20 10:54
  • 5950

死锁问题分析(个人认为重点讲到了gap间隙锁,解决了我一些不明报死锁的问题)

线上某服务时不时报出如下异常(大约一天二十多次):“Deadlock found when trying to get lock;”。       Oh, My God! 是死锁问题。尽管报错不多,...
  • zhongyangjian
  • zhongyangjian
  • 2016-07-20 15:21
  • 2258

mysql之锁表机制与死锁浅谈

MySQL锁定机制简介 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则。对于任何一种数据库来说都需要有相应的锁定机制,所以MyS...
  • u010391029
  • u010391029
  • 2015-08-27 12:01
  • 1816
    个人资料
    • 访问:76611次
    • 积分:1071
    • 等级:
    • 排名:千里之外
    • 原创:47篇
    • 转载:6篇
    • 译文:0篇
    • 评论:1条
    最新评论