美文网首页
理解innodb的锁(record,gap,Next-Key l

理解innodb的锁(record,gap,Next-Key l

作者: wuyuan0127 | 来源:发表于2018-03-30 16:53 被阅读0次

    行锁 [ Record lock ]:

    单条索引记录上加锁,record lock锁住的永远是索引,而非记录本身,即使该表上没有任何索引,那么innodb会在后台创建一个隐藏的聚集主键索引,那么锁住的就是这个隐藏的聚集主键索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。

    间隙锁 [  Gap lock  ]: (可重复读隔离级别来解决幻读的问题)

    在索引记录之间的间隙中加锁,或者是在某一条索引记录之前或者之后加锁,并不包括该索引记录本身。gap lock的机制主要是解决可重复读模式下的幻读问题,关于幻读的演示和gap锁如何解决了幻读。

    MDL锁:

    一个session会话开启事务,查询数据.没有 commit或者 callback

    另一个会话 开启事务 修改这个表的 表结构 ,这个时候就是 锁等待 也就是 MDL锁.

    意向锁: 

    innodb的意向锁主要用户多粒度的锁并存的情况。比如事务A要在一个表上加S锁,如果表中的一行已被事务B加了X锁,那么该锁的申请也应被阻塞。如果表中的数据很多,逐行检查锁标志的开销将很大,系统的性能将会受到影响。为了解决这个问题,可以在表级上引入新的锁类型来表示其所属行的加锁情况,这就引出了“意向锁”的概念。举个例子,如果表中记录1亿,事务A把其中有几条记录上了行锁了,这时事务B需要给这个表加表级锁,如果没有意向锁的话,那就要去表中查找这一亿条记录是否上锁了。如果存在意向锁,那么假如事务A在更新一条记录之前,先加意向锁,再加X锁,事务B先检查该表上是否存在意向锁,存在的意向锁是否与自己准备加的锁冲突,如果有冲突,则等待直到事务A释放,而无须逐条记录去检测。事务B更新表时,其实无须知道到底哪一行被锁了,它只要知道反正有一行被锁了就行了。

    说白了意向锁的主要作用是处理行锁和表锁之间的矛盾,能够显示“某个事务正在某一行上持有了锁,或者准备去持有锁”

    幻读: (间隙锁避免幻读)

    指的是在一个事务A中执行了一个当前读操作,而另外一个事务B在事务A的影响区间内insert了一条记录,这时事务A再执行一个当前读操作时,出现了幻行。这和不可重复读的主要区别就在与事务A中一个是快照读,一个当前读;并且事务B中一个是任何的dml操作,一个只是insert。比如在A中select * from test where id<10 lock in share mode结果集为(1,2,3),这时在B中对test表插入了一条记录4,这时在A中重新查询结果集就是(1,2,3,4),和事务A在第一次查询出来的结果集不一致,这里的4就是幻行。

    由于可重读的隔离级别下,默认采用Next-Key Locks,就是Record lock和gap lock的结合,即除了锁住记录本身,还要再锁住索引之间的间隙,所以这个gap lock机制默认打开,并不会产生幻行,那么我们要演示幻行的话,要么将隔离级别改为read-commited(会产生幻读),要么在REPEATABLE-READ模式下禁用掉gap lock(不禁用gap lock,不会产生幻读)

    脏读,幻读,可重复读 定义:

    mysql 查看锁等待的参数: show variable like '%innodb_lock_wait%%'

    死锁通过 show full processlist 和 show engine innodbstatus 判断 事务中锁问题的情况.

    也可以通过  information_schema 库下的  INNODB_TRX, INNODB_LOCKS,INNODB_LOCK_WAITS 来分析 事务锁的问题.

    相关文章

      网友评论

          本文标题:理解innodb的锁(record,gap,Next-Key l

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