INNODB存储索引中的锁

MYISAM只支持表锁

INNODB既支持表锁也支持行锁

 

lock的对象是事务,用来锁定的是数据库中的对象,比如表、页、行。

INNODB的表锁

     意向锁是INNODB自动加上去的,不需要用户干预。

     意向锁即为表锁,目的:是为了在一个事务中揭示下一行被请求的锁类型。

有两种意向锁:

     意向共享锁,事务想要获得一张表中某个行的共享锁;

     意向排他锁,事务想要获得一张表中某个行的排他锁;

INNODB的行锁

      InnoDB是通过搜索或者扫描表中索引来完成加锁操作,InnoDB会为遇到的每一个索引数据加上共享锁或排他锁。InnoDB中是存在行级别锁

  • 锁类型

两种标准的行级别的锁

共享锁(S锁):允许事务读一行数据;

排他锁(X锁):允许事务删除或者更新一行数据

 

两种锁在多个事务之间的影响:

  1. 一个事务获得行的S锁,另一个事务也可以获得该行的S锁,但是不能获得该行的X锁。
  2. 一个事务获得行的X锁,另一个事务既不能获得该行的S锁也不能获得该行X锁。
  • 行锁的算法
  1. 三种算法(确定锁的范围)

假设表t中索引列有3、5、8、9四个记录,

·  记录锁,锁定的是单独的索引列记录,就是3、5、8、9这四行数据。

·  间隙锁,锁定的是一个不含包记录列本身的范围,,用集合表示为(-∞,3)、(3,5)、(5,8)、(8,9)、(9,+∞)。

·  Next-Key,记录锁+间隙锁,所以锁定的是包含记录本身的一个范围,用集合的方式表示为(-∞,3]、(3,5]、(5,8]、(8,9]、(9,+∞)

间隙锁和记录锁为了解决幻读现象。

  1. 加锁语句
  1. select ... from语句:InnoDB引擎采用多版本并发控制(MVCC)的方式实现了非阻塞读,所以对于普通的select读语句,InnoDB并不会加锁【注1】。
  2. select ... from lock in share mode语句:这条语句和普通select语句的区别就是后面加了lock in share mode,通过字面意思我们可以猜到这是一条加锁的读语句,并且锁类型为共享锁(读锁)。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描的唯一索引的唯一行,next-key降级为索引记录锁。
  3. select ... from for update语句:和上面的语句一样,这条语句加的是排他锁(写锁)。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描唯一索引的唯一行,next-key降级为索引记录锁。
  4. update ... where ...语句:。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描唯一索引的唯一行,next-key降级为索引记录锁。【注2】
  5. delete ... where ...语句:。InnoDB会对搜索的所有索引记录加next-key锁,但是如果扫描唯一索引的唯一行,next-key降级为索引记录锁。
  6. insert语句:InnoDB只会在将要插入的那一行上设置一个排他的索引记录锁。

总结:

  1. 对于查询操作,如果不指定锁,默认是不加锁。
  2. 对于更新和删除操作,默认加排他锁,
  3. 如果不是唯一索引,锁定的范围是包含索引所在记录本身的一个范围(Next-key),但是如果是唯一索引,那么是锁定索引所在行记录(记录锁)。
  1. SQL加锁分析

想要确定InnoDB的加锁情况,需要知道很多前提条件,

  1. id列是不是主键?
  2. 事务的隔离级别是什么?
  3. id非主键的话,其上有建立索引吗?
  4. 建立的索引是唯一索引吗?
  5. 该SQL的执行计划是什么?索引扫描?全表扫描?

在读取已提交的隔离级别下

  1. 当id是主键的时候,我们只需要在该id=10的记录上加上x锁即可。
  2. 当id列为辅助唯一索引时,辅助索引和聚集索引,都会加X锁
  3. 如果id是非唯一索引,那么所对应的 所有的辅佐索引和聚集索引记录 上都会上x锁。
  4. 由于id列上没有索引,因此只能走聚簇索引,进行全表扫描。因此聚集索引上的每条记录,无论是否满足条件,都会被加上X锁。但是,为了效率考量,MySQL做了优化,对于不满足条件的记录,会在判断后放锁,最终持有的,是满足条件的记录上的锁,但是不满足条件的记录上的加锁/放锁动作不会省略。

在可重复读的隔离级别下

  1. 与id列是主键,RC隔离级别的情况,完全相同。因为只有一条结果记录,只能在上面加锁。
  2. 与id列是辅助唯一索引,RC隔离级别的情况,完全相同。因为只有一条结果记录,只能在上面加锁。
  3. 在RR隔离级别下,为了防止幻读的发生,会使用范围锁(GAP锁)。这里,可以把范围锁理解为,不允许在数据记录前面插入数据。首先,通过辅助索引定位到第一条满足查询条件的记录,加记录上的X锁,加GAP上的GAP锁,然后加聚簇索引上的记录X锁,然后返回;然后读取下一条,重复进行。直至进行到第一条不满足条件的记录[11,f],此时,不需要加记录X锁,但是仍旧需要加GAP锁,最后返回结束。
  • 死锁
  1. 死锁的概念

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

  1. 解决死锁的方案
  1. 超时回滚

当两个事务相互等待时,当等待时间超过设置的某个阀值的时候,其中一个事务回滚,一个事务继续执行。但是会出现选择哪个事务进行回滚的问题,如果先进先出,可能会导致选择回滚的事务权重较大(更新较多,占用较多undo log)。

  1. 等待图

主动监测的机制,包含两种信息:锁的信息链表和事务等待链表。通过这些链表构造一张图,然后采用深度优先的算法,查找图中是否存在回路,如果存在回路说明存在死锁。选择回滚undo量最小的事务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值