秒懂InnoDB的锁

栏目: 数据库 · 发布时间: 5年前

内容简介:我们通常讲的MySQL的“锁”,一般就是说的lock。

latchMySQL 中是用来保证并发多线程操作操作临界资源的 ,锁定的对象线程,是和咱们使用的 Java 等传统语言中的锁意义相近,而且没有死锁检测的机制。

lock

lock 是MySQL中在事务中使用的 ,锁定的对象是事务,来锁定数据库中表、页、行;通常只有在事务commit或者rollback后进行释放。lock是有死锁机制的,当出现死锁时,lock有死锁机制来解决死锁问题:超时时间(参数 innodb_lock_wait_timeout )、 wait-for graph

我们通常讲的MySQL的“锁”,一般就是说的lock。

以下就是InnoDB中“锁”的大分类:

秒懂InnoDB的锁

lock的种类

MySQL Lock大体上可以分为:表锁、行锁、意向锁三种。

秒懂InnoDB的锁

共享/排他锁

行锁分为: S LockX LockS Lock :读锁; X Lock :写锁。

两锁之间的兼容性如下。

       X         S
X     不兼容     不兼容
S     不兼容     不兼容

简单总结为: 读锁可以读,读锁不可写;写锁不可读也tm不可写。

意向锁

InnoDB支持多粒度的锁,即:允许表锁和行锁同时存在。

但是,假如表锁覆盖了行锁的数据,所以表锁和行锁也会产生冲突。如:

trx1 BEGI

trx1 给 T1 加X锁修改数据。

trx2 BEGIN

trx2 给 T1 加表锁修改表结构

这样,表锁和行锁之间就产生了冲突,为了解决这种表锁和行锁共存的问题,就产生了 意向锁 这个东西。

意向锁:从字面意思也很好理解,就是提前表明一个“意向”。

意向锁分为:

  • 意向共享锁 。它预示着,事务有意向对表中的”某些行”加S锁。 select xxxx lock in share mode ,要设置 IS 锁。
  • 意向排他锁 。它预示着,事务有意向表中的“某些行”加X锁。 select xxx for update ,要设置 IX 锁。

但意向锁仅仅是表明意向,它其实非常弱,意向锁之间可以相互并行,并不是排斥的:

意向锁之间的兼容性问题:

      IS     IX

IS   兼容    兼容

IX   兼容    兼容

但是,意向锁可以和行锁互斥。

        S                X

IS     兼容           互斥不兼容

IX    互斥不兼容        互斥不兼容

于是,上述现象就变为了:

trx1 BEGIN

trx1 给 T1 先加IX ,然后在某一行记录加X锁。

trx2 BEGIN

trx2 给 T1 加表锁(事务被阻塞,等待加锁成功)

trx2 修改表结构

主键自增锁

自增锁( auto-inc Locks )是一种特殊的表级锁,专门针对事务插入 AUTO_INCREMENT 类型的列,往往就是主键列。可以保证主键的值自增是“原子操作”,不会出现一致性、唯一性问题。

行锁的具体分类

秒懂InnoDB的锁

InnoDB存储引擎有以上3种行锁算法。以上3种,都是实现在索引上的。

记录锁(Record Lock)

记录锁(Record Lock)总是会去锁住索引记录。

假如没有任何一个索引,那么InnoDB会锁住隐形创建的那个主键。

注意:这里锁的是索引,不一定只是主键索引哦,还可能是二级普通索引。

间隙锁(Gap Lock)

顾名思义,它会封锁索引记录中的“缝隙”,让制其他事务在“缝隙”中插入数据。

它锁定的是一个不包含索引本身的范围。

例如以下索引数据:

秒懂InnoDB的锁

间隙锁(Gap Lock) 可以锁的将是以下范围

秒懂InnoDB的锁

具体的范围还要根据查询条件不同而定。

间隙锁开启的事务隔离级别是 Repeatable Read ,如果把数据库事务级别降为 Read Committed (默认是 Repeatable Read ),间隙锁则会自动失效。

临键锁(Next-Key Lock)

Next-Key Lock 可以说是记录锁( Record Lock )和间隙锁( Gap Lock )的组合,既封锁了”缝隙”,又封锁了索引本身。

还是上面的索引数据:

秒懂InnoDB的锁

临键锁(Next-Key Lock) 锁住的范围将是:

秒懂InnoDB的锁

Next-key Lock 在索引具有唯一性的时候,例如主键索引的数据,将会降级为 记录锁(Read Lock) ,以增加并发性。

例如:

        T1                                     T2
        BEGIN;                   |            
   select * From T               |           
   where id = 5 for update       |
---------------------------------------------------------------
                                 |            BEGIN; 
                                 |          Insert into t (4, xx);
---------------------------------------------------------------              
                                 |          COMMIT
                                 |             
----------------------------------------------------------------
     COMMIT                      |                            
                                 |
                                 |
-----------------------------------------------------------------

以上情况,就会把 Next-key Lock 降级为 记录锁(Read Lock)

再谈不可重复读( No Reaptable Read )和幻读( Phantom Problem )

有些很权威的书中认为这俩是同一个概念,例如:<<MySQL技术内幕 InnoDB存储引擎>>。

但是就目前网络上的众多总结和个人看法,认为区别如下:

不可重复读 :修改。在同一个事务中,主要是说多次读取一条记录, 发现该记录中某些列值被修改过。

幻读 :增加或者删除。在同一个事务中,同一条完全相同的查询语句返回的结果集行数不同。

参考: https://stackoverflow.com/questions/11043712/what-is-the-difference-between-non-repeatable-read-and-phantom-read

认真的说, 多版本并发控制 MVCC (读)和 临键锁 Next-Key Lock (写)共同解决了 幻读 问题。

关于MVCC的原理,就是每份数据会有快照,事务中读取数据(简单的 select xxx fromselect xx from xx for update 或者 select xx from xxx in share mode 不行)的时候,如果数据被锁住了,就读以前留下的快照数据。在此不过多赘述了。

以下为多版本并发控制原理图

秒懂InnoDB的锁

MVCC 只在 Read CommittedRepeatable Read 下会开启。但是在这两种隔离级别下对于快照指定的数据定义不同。

Read Committed 下, MVCC 读取的是被锁定数据的最新的一份数据。

Repeatable Read 下, MVCC 读取的是事务刚开始时候的数据。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

引爆点

引爆点

[美] 马尔科姆·格拉德威尔 / 钱清、覃爱冬 / 中信出版社 / 2009-8 / 27.00元

我们的世界看上去很坚固,但在《纽约客》怪才格拉德威尔的眼里,只要你找到那个点,轻轻一触,这个世界就会动起来:一位满意而归的顾客能让新开张的餐馆座无虚席,一位涂鸦爱好者能在地铁掀起犯罪浪潮,一位精明小伙传递的信息拉开了美国独立战争的序幕——这个看起来不起眼的点,却是任何人都不能忽视的引爆点。 《引爆点》是一本谈论怎样让产品发起流行潮的专门性著作。书中将产品爆发流行的现象归因为三种模式:个别人物......一起来看看 《引爆点》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具