Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • GAP LOCK

    Section

    间隙锁是锁在index records之间间隙上的锁,或者第一个index record之前的间隙、最后一个index record之后的间隙。

    例如: SELECT c1 FROM t where c1 BETWEEN 10 and 20  FOR UPDATE ; 这句SQL会阻止其他事务插入c1为15的记录, 

    根据index record的记录来确定间隙锁的范围

    如果10 和 20 都有具体的index record , 那么锁住的范围是10-20 ; 

    如果10 和 20 没有具体的index record , 那么锁住的范围是  10之前的index record  - 20 之后的index record 。

    不管是否有这条记录都会阻止插入,因为这个间隙都被锁住了。

    一个间隙可能跨越一个单一的索引值、多个索引值、甚至是空。

    间隙锁需要综合考虑性能和并发,只在某些事务隔离级别(RR)中才会使用。

    对于使用唯一索引查找唯一行、然后进行锁定的语句来说,不需要间隙锁。

    (如果查询条件只包含唯一索引的部分列,这种情况仍需要间隙锁)。

    例:

    Code Block
    languagesql
    SELECT * FROM child WHERE id = 100 ;

    如果id列是唯一索引,那么上面的语句将只持有id等于100这一行的record lock,并不阻止其他事务插入数据到该条记录前面的间隙中。
    (假设表记录有两条,id为 50 和 100 ,那么这里说的该条记录前面的间隙即表示(50,100] )。

    如果id列上没有索引,或不是唯一索引,那么这条语句会锁住该条记录之前的间隙。

    需要注意的是,不同的事务可以在一个gap上持有冲突的锁。
    例如,当事务B持有排他gap lock(gap X-lock)锁,事务A可以同时持有共享gap lock(gap S-lock) 锁。
    这种情况的原因是因为,如果一条记录从index中被purge时,在这条记录上,当前事务gap锁和其他事务上的gap锁必须被merged。

    Gap lock是抑制性的,这表示gap lock只会阻止其他事务插入新的记录到这个gap中。
    不会阻止其他的事务在相同gap上获取gap locks。因此,gap x-lock 和 gap s-lock的影响是相同的。

    gap lock 可以被显式的禁止。
    在事务级别更改为read commited committed , 或innodb_locks_unsafe_for_binlog变量(已废弃)被启用的情况下。
    在这种情况,gap locking在查询、索引扫描时会被禁用,只会用来做外键约束检查和重复键检查。


...