zoukankan      html  css  js  c++  java
  • 【innoDB】加锁案例分析

    分析一条语句的加锁行为,我们需要知道:

    • 当前隔离级别是什么?
    • 语句是快照读还是当前读?
    • 是不是走的索引?
    • 索引是不是主键?
    • 索引唯一吗?

    快照读默认不加锁,走mvcc,下面分析一下当前读的常见场景,sql语句是:update t1 set name='xx' where id=10;

    RR隔离级别级别:

    可重复读通常需要加间隙锁保证不出现幻读。

    • 情形1- id是主键索引

      这种情况下只会在id=10的主键索引上加X锁

    • 情形2-id是非主键唯一索引

      唯一索引id=10上先被加X锁;还要在该记录的主键索引上加X锁;

      如果不存在id=10的记录,则要在id索引上加间隙锁,锁住id=10其前一条记录到其后一条记录这整个区间。

    • 情形3- id是非唯一索引

      所有索引到的记录都加上X锁,并在其主键索引上也加上X锁,并且要在锁住所有间隙。

      image-20211212203545964
    • 情形4-id不是索引

      因为id不是索引,所以该语句需要进行全表扫描,这种情况下会对主键索引的所有记录和间隙都加锁。这种情况并发度就很低了,而且如果记录很多锁的开销还非常大。

      似乎进行扫描时只要对满足条件的加锁即可,但实际上innodb会先对所有的记录加锁,然后在mysql server层会进行过滤,对不满足条件的记录释放锁(但这违背了2PL原则)。

    RC隔离级别下:

    基本和RR一样,不过不考虑幻读问题,不需要加间隙锁。

    • id是主键,同RR
    • id是唯一索引,同RR,不需要加间隙锁
    • id是非唯一索引,同RR,不需要加间隙锁
    • id不是索引,同RR,不需要加间隙锁

    串行化隔离级别:

    在串行化下,上述的当前读语句加锁行为和RR级别一样。

    不同的是串行化级别下所有读都是当前读,不走快照读,因此原本的快照读语句会加读锁。MVCC并发控制降级为Lock-Based CC。

  • 相关阅读:
    java 之 File类
    java 之 内部类
    java 之 泛型
    如何生成随机码
    sql中getdate()&convert的使用
    sql中Distinct&Count的用法
    C#中如何使用正则表达式
    Sql按照字段分组,选取其他字段最值所在的行记录
    为什么在属性中设置private set
    基本Sql语句汇总
  • 原文地址:https://www.cnblogs.com/cpcpp/p/15684239.html
Copyright © 2011-2022 走看看