美文网首页
Mysql innodb行锁

Mysql innodb行锁

作者: ugeek | 来源:发表于2020-01-13 10:03 被阅读0次

1、什么时候加锁?

在InnoDb事务中,行锁是在需要的时候加上的,但并不是用完马上释放掉,而是等到事务结束时才释放。这就是两阶段锁协议。
最佳实践:在事务中如果需要加多个锁,尽量将影响并发度的锁往后放,以减少持有锁的时间。

2、InnoDB行锁算法有哪几种?

InnoDB中行锁有三种分别是,

record lock:单个行记录上的锁

gap lock:间隙锁,锁定一个范围,但不锁定记录本身。间隙锁只会阻塞间隙间的数据插入(insert)。多个间隙锁获取操作不冲突。

next-key lock:record lock+gap lock,前开后闭的区间。

3、行锁的实现

加锁的对象是事务。

  • InnoDB通过给索引项上的索引加锁来实现行锁。这也意味着只有通过索引条件检索数据才会被加上行锁,否则InnoDB将使用表锁。
  • 索引不仅包括主键索引,普通索引、唯一索引都可以使用行锁
  • 只有真正执行计划用到的索引才会被加锁,条件里面包含索引列的语句在执行时不一定会用到索引,可使用explain分析具体的执行情况

4、InnoDB是如何加行锁的?

select语句显式加锁:

//共享锁(读锁) select ... lock in share mode

//互斥锁(写锁) select ... for update

更新操作(update)和插入(insert)操作会自动加锁

加锁规则:

1.加锁基本单位是next-key lock,即前开后闭区间

2.查找过程中访问到的对象才会加锁

3.索引上的等值查询,给唯一索引加锁时,next-key lock退化为行锁

4.索引上的等值查询,向右遍历时且最右一个值不满足等值条件的时候,next-key lock退化为间隙锁

示例:在innodb可重复读的隔离级别下

建表语句如下:


CREATE TABLE `t` (

`id` int(11) NOT NULL,

`c` int(11) DEFAULT NULL,

`d` int(11) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `c` (`c`) ) ENGINE=InnoDB;

insert into t values(0,0,0),(5,5,5), (10,10,10),(15,15,15),(20,20,20),(25,25,25);

1)示例1

begin;

update t set d=d+1 where id=7

加锁: id索引的(5,10)间隙锁

2)示例2

image1.png
读锁 索引c (0,5],(5,10)

分析:根据加锁规则2,查找过程中访问到的对象才会加锁,在c=5的等值条件下,会去找索引c, 在索引c上加锁,并不会在主键上加锁.因此sessionB走主键索引更新没问题。注意: 若改成for update,那么系统认为会更新数据,会在主键上满足条件的行也加上锁。

3)示例3

image2.png
加锁:主键索引:[10],(10,15] 扫描到10时按等值加锁,扫描到15按范围加锁

4)示例4


image3.png
索引c:(5,10],(10,15] 主键索引

id:对应行锁(写锁)

5)示例5

insert into t values(30,10,30);


image4.png
加锁:索引c,(5,10],(10,10] ,主键:id对应行锁

分析:加了limit2之后,在查找到第二条满足条件的c之后就停止向后搜索了。因此在在删除 数据的时候尽量加 limit。这样不仅可以控制删除数据的条数,让操作更安全, 还可以减小加锁的范围。

5、不同隔离级别,加锁策略和一致性读区别?

6.png
7.png

6、死锁出现的场景?如何解决?

死锁(Deadlock):死锁是指两个或多个事务执行过程中,因争夺锁资源而造成相互等待的现象。
解决方案:

  • innodb_deadlock_detect:innodb配置开启死锁检测,默认开启。
  • innodb_lock_wait_timeout:配置获取锁的最大等待时间,默认50s
  • 减小锁的范围:在使用有锁的语句时,尽量减少锁的范围,加锁语句使用索引
  • 减少锁的时间:获取锁的语句尽量放到事务后面执行,尽量只把必要的语句放进事务
  • 多个事务尽量按照相同顺序获取锁

参考:1、https://zhuanlan.zhihu.com/p/29150809
2、林晓斌-MySQL实战45讲

相关文章

  • Innodb的锁

    Innodb的锁是行级锁 mysql delete是否会锁表 MySQL的InnoDB存储引擎支持行级锁,Inno...

  • Mysql存储引擎Innodb小结

    innodb是mysql支持事务的存储引擎,也是当前mysql默认的存储引擎。innodb支持行级别锁,对并发性事...

  • InnoDB引擎的行锁和表锁

    在Mysql中,Innodb数据引擎支持行锁和表锁,Myisam数据引擎只支持表锁 1 行锁和表锁 行锁是通过索引...

  • MySQL面试题 | 附答案解析(十)

    接上篇:锁 5. MySQL中InnoDB引擎的行锁是怎么实现的? 答:InnoDB是基于索引来完成行锁 例: s...

  • InnoDB介绍

    InnoDB介绍 InnoDB是事务安全的mysql存储引擎,也是mysql的默认存储引擎,特点是行锁设计、支持M...

  • 淘宝MySQL文档整理

    MySQL · 引擎特性 · InnoDB 事务锁系统简介 MySQL · 引擎特性 · Innodb 锁子系统浅...

  • 总结Mysql中的锁

    MySQL中的锁 概述 MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁 表级锁:开销小,加锁快,不会...

  • 如何解决秒杀场景下的超卖问题

    1、利用排他锁解决超卖问题 MySQL InnoDB存储引擎支持事务和行锁。如果不手动开启事务的话,InnoDB会...

  • MySQL行锁的主要知识点

    1、innoDB行锁的实现方法 innoDB行锁是通过给索引上的索引项加锁来实现的。 这一点MySQL与Oracl...

  • MySQL知识点

    Mysql中有哪几种锁? MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁 表级锁:开销小,加锁快,不...

网友评论

      本文标题:Mysql innodb行锁

      本文链接:https://www.haomeiwen.com/subject/sjfznctx.html