innodb的记录锁、gap锁、next-key锁

事务 acid 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)a : commit  等c : redoLog undoLogi : 锁d : 磁盘对事务而言, 锁的存在目的是为了事务的隔...

事务 acid 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

a : commit  等

c : redoLog undoLog

i : 锁

d : 磁盘

对事务而言, 锁的存在目的是为了事务的隔离性.

    当然广义上,锁的存在还是为了控制并发. 控制并发某种意义是就是控制多个线程的隔离.


不同的角度.

一般锁: 可重复读

间隙锁: 防止幻读.

从这个根本出发. 哪些情况会导致幻读,就需要间隙锁. 

普通的select 是不锁的.(快照读

只有 select for update 才锁,  或者 delete ,update里的where条件

1. 区间条件

2. 命中一行,且是非unique

3. 不命中一行,不管是不是unique .


无间隙锁:

1. 命中一行且unique

2. 读提交级别

3. 

一般锁:  等价性 a 锁 b, b也锁 a

特殊锁: 间隙锁.  

对文章的总结如下:

(1)记录锁:在行相应的索引记录上的锁

(2)gap锁:是在索引记录间歇上的锁

(3)next-key锁:是记录锁和在此索引记录之前的gap上的锁的结合

(4)innodb行锁的加锁方式: 当根据innodb表的索引搜索时, 设置共享锁和排它锁在索引记录上

(5)行锁实际上是索引锁

(6)innodb_locks_unsafe_for_binlog:

当为0时 (disabled), 这个开启了gap锁;设置为1,关闭gap锁(这会导致幻读,引起主从同步不一致)。例子见http://book.51cto.com/art/200803/68129.htm

(7)开启这个选项innodb_locks_unsafe_for_binlog并不关闭gap锁在外键检查方面的作用

(8)在UPDATE和DELETE时,innodb首先对遇到的每一行加行锁;如果innodb_locks_unsafe_for_binlog开启,那么不匹配的行上的锁将被释放;如果未开启,不匹配的行上的锁也不释放,直到事务结束

(9)即使innodb表上没有索引,也会使用内部的clustered index来进行锁定;

(10)innodb除主键的索引之外的其他索引和clustered index在内部是建立一张索引对应表;当利用其他索引扫描记录时,对其他索引加的锁最后都转换为对clustered index加的锁

(11)在UPDATE模式下,对检索中遇到的记录加排它锁;在INSERT...SELECT模式下,对检索中遇到的记录加共享锁;在INSERT模式下,对检索中遇到的记录加排它锁;在DELETE模式下,对检索中遇到的记录加排它锁

(12)在使用unique index进行搜索,并且只返回一行时,不使用gap锁

(13)next-key锁举例:假设索引包括10,11,13,20,则next-key锁为:(negative infinity, 10], (10, 11], (11, 13], (13, 20], (20, positive infinity)

(14)使用next-key锁可以预防幻读

(15)gap锁在read_committed下或当 innodb_locks_unsafe_for_binlog=on时被关闭;当在这种情况下时,不匹配的行上的锁将被释放


InnoDB支持行锁(锁定字段含有索引的情况下,否则走表锁),但锁定方式并非简单的锁定指定行上的索引,而是分为3种锁定算法:
1)记录锁(Record Locks):锁定指定行的索引项
2)Gap Locks:锁定某一个范围内的索引,但不包括记录本身
3)间隙锁定(Next-Key Locks):锁定一个范围内的索引,并且锁定记录本身   Next-Key Locks = Record Locks + Gap Locks
A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record


InnoDB在默认配置下(隔离级别:可重复读;innodb_locks_unsafe_for_binlog=OFF:采用gap locking),对于索引的查询采用 next-key locks。这样做避免了幻读现象的产生。
By default, InnoDB operates in REPEATABLE READ transaction isolation level and with the innodb_locks_unsafe_for_binlog system variable disabled. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows
特别的,
1、当锁定的索引项含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围。
2、当唯一索引是由多个列组成,而query仅查询多个列中的其中一个,则依然使用 Next-key lock。
3、通过主键或者唯一索引来锁定不存在的值,则依然使用 Next-key lock。

强制关闭Gap Lock,仅使用记录锁从而避免阻塞(有幻读的风险):配置参数 innodb_locks_unsafe_for_binlog = 1 或者隔离级别设为 READ COMMITTED
By default, the value of innodb_locks_unsafe_for_binlog is 0 (disabled), which means that gap locking is enabled: InnoDB uses next-key locks for searches and index scans. To enable the variable, set it to 1. This causes gap locking to be disabled: InnoDB uses only index-record locks for searches and index scans.

The effects of enabling innodb_locks_unsafe_for_binlog are the same as setting the transaction isolation level toREAD COMMITTED


 

  • 发表于 2018-09-06 01:56
  • 阅读 ( 44 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
石天
石天

437 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章