MYSQL-InnoDB存储引擎--- 锁

目录

锁的类型  行级锁 / 意向锁 (一种表级锁)

一致性非锁定读(InnoDB存储引擎的默认设置)

行锁的3种算法

死锁


锁的类型  行级锁 / 意向锁 (一种表级锁)

 

InnoDB存储引擎实现了如下两种标准的行级锁 

1)共享锁(S Lock),允许事务读一行数据。(SELECT column FROM table ... LOCK IN SHARE MODE)

2)排他锁(X Lock),允许事务删除或更新一行数据。 (SELECT column FROM table ... FOR UPDATE)

为了支持多粒度加锁,还引入了意向锁的概念,其意向锁即为表级别的锁

3)意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁

4)意向排他锁(IX Lock),事务想要获得一张表中某几行的排他锁

 

由于InnoDB存储引擎支持的是行级别的锁,因此意向锁其实不会阻塞除全表扫以外的任何请求。故表级意向锁与表级锁的兼容性如下表所示:

 

 

一致性非锁定读(InnoDB存储引擎的默认设置)

之所以称其为非锁定读,因为不需要等待访问的行上X锁的释放  而是去读取一份快照数据,快照数据是指该行的之前版本的数据,该实现是通过undo段来完成。而undo用来在事务中回滚数据,因此快照数据本身是没有额外的开销。此外,读取快照数据是不需要上锁的,因为没有事务需要对历史的数据进行修改操作。

mvcc(多版本并发控制)

在事务隔离级别READ COMMITTED和REPEATABLEREAD(InnoDB存储引擎的默认事务隔离级别)下,InnoDB存储引擎使用非锁定的一致性读。然而,对于快照数据的定义却不相同。在READ COMMITTED事务隔离级别下,对于快照数据,非一致性读总是读取被锁定行的最新一份快照数据。而在REPEATABLE READ事务隔离级别下,对于快照数据,非一致性读总是读取事务开始时的行数据版本

如果需要一致性锁定读可以采用加锁的方式。

 

 

行锁的3种算法

InnoDB存储引擎有3种行锁的算法,其分别是:

  1. Record Lock:单个行记录上的锁
  2. Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
  3. Next-Key Lock∶Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身

 

在默认的事务隔离级别下,即REPEATABLE READ下,InnoDB存储引擎采用Next-Key Locking机制来避免Phantom Problem(幻像问题)。这点可能不同于与其他的数据库,如Oracle数据库,因为其可能需要在SERIALIZABLE的事务隔离级别下才能解决Phantom Problem。

Phantom Problem是指在同一事务下,连续执行两次同样的SQL语句可能导致不同的结果,第二次的SQL语句可能会返回之前不存在的行。

 

 

死锁

死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象。

当前数据库还都普遍采用wait-for graph(等待图)的方式来进行死锁检测

1.AB-BA死锁

2.此外还存在另一种死锁,即当前事务持有了待插入记录的下一个记录的X锁,但是在等待队列中存在一个S锁的请求,则可能会发生死锁

这个问题的产生是由于会话B中请求记录4的S锁而发生等待,但之前请求的锁对于主键值记录1、2都已经成功,若在事件点5能插入记录,那么会话B在获得记录4持有的S锁后,还需要向后获得记录3的记录,这样就显得有点不合理。因此InnoDB存储引擎在这里主动选择了死锁

 

 

 

 

 

 

 

 

 

 

注:图片来自于《MySQL技术内幕》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值