InnoDB Next-Key Lock

 

InnoDB有三種行鎖的算法:html

1,Record Lock:單個行記錄上的鎖mysql

2,Gap Lock:間隙鎖,鎖定一個範圍,但不包括記錄自己算法

3,Next-Key Lock:Record Lock + Gap Lock,鎖定一個範圍,而且鎖定記錄自己sql

 

1、在RR隔離級別測試

SELECT @@global.tx_isolation, @@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation |
+-----------------------+-----------------+
| REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)測試

 

create table t(a int,key idx_a(a))engine =innodb;

insert into t values(1),(3),(5),(8),(11);

 

上面索引值有1,3,5,8,11,其記錄的GAP的區間以下:(-∞,1],(1,3],(3,5],(5,8],(8,11],(11,+∞)優化

 

--鎖定存在的值
select * from t where a = 8 for update;

--鎖定不存在的值
select * from t where a = 9 for update;

 

 插入5,6,7,8,9,10 會被鎖住, 其餘正常。spa

 

 

2、關閉Gap Lock的方式

1. RC隔離級別

mysql> set global transaction isolation level read committed;

 

 

2. innodb_locks_unsafe_for_binlog=ON

SHOW VARIABLES LIKE '%innodb_locks_unsafe_for_binlog%';

 

3、總結

InnoDB對於行的查詢都是採用了Next-Key Lock的算法,鎖定的不是單個值,而是一個範圍。code

當查詢的條件含有惟一索引時,Next-Key Lock 會進行優化,將其降級爲Record Lock。htm

 啓用innodb_locks_unsafe_for_binlog或read-committed後,能夠使得InnoDB gap鎖最小化,可是在兩種場景(外鍵約束和惟一索引)中,仍然不可避免的存在gap鎖。blog

 

 

 

出處:

InnoDB 行鎖

參考:

14.5.3 Locks Set by Different SQL Statements in InnoDB

next-key lock 引起的死鎖

相關文章
相關標籤/搜索