浅谈InnoDB的next-key locking策略


InnoDB 存储引擎默认隔离级别为可重复读(Repeatable Read),该隔离级别下加行锁采用的是next-key locking 策略。

浅谈InnoDB的next-key locking策略_第1张图片

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



(1)采用next-key locks的InnoDB无法插入除了锁定行外的其他行的测试案例:

http://www.cnblogs.com/zhoujinyi/p/3435982.html

(2)何登成 --- MySQL加锁处理分析

http://hedengcheng.com/?p=771

(3)《深入浅出MySQL数据库开发优化与管理维护》开发篇

(4)https://dev.mysql.com/doc/refman/5.5/en/innodb-locking.html

(5)https://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html




你可能感兴趣的:(MySQL)