天天看點

14.2.2.4 InnoDB Record, Gap, and Next-Key Locks

14.2.2.4 innodb record, gap, and next-key locks

innodb 有幾種類型的行級鎖 包括record locks, gap locks, and next-key locks.

關于共享鎖,排他鎖和intention locks, see section 14.2.2.1, “innodb lock modes”.

1.record lock: 這個是在index record 鎖

2.gap lock: 間隙鎖 這是一個鎖在一個間隙 在index records之間,

或者一個鎖在一個間隙 在第一個或者而最後一個index record 的後面

3.next-key lock: 這是record lock 在index record 的組合,一個gap lock 在間隙上在index record 之前。

record locks:

record locks 總是lock index records, 即使如果一個表被定義為沒有indexes.

對于這樣的情況,innodb 建立一個隐藏的 clustered index和使用這個索引用于record locking.

see section 14.2.6.2, “clustered and secondary indexes”.

next-key locks

預設的,innodb 操作 在 repeatable read 事務隔離級别 , innodb_locks_unsafe_for_binlog 系統變量禁用。

在這種情況下, innodb 使用 next-key locks用于搜尋和index掃描,

以防止幻影行(見第14.2.2.5,避免“虛位的問題用下鍵鎖定”)。

next-key locking 結合 index-row locking 。

innodb 執行一個row-level locking 以這種方式當它搜尋或者掃描一個表的索引,

它設定共享或者排他鎖在index records.

是以,row-level locks 實際上是index-record locks.

此外,一個 next-key lock 在一個index record 也影響the “gap” .

也就是說, a next-key lock 是一個index-record lock 加上一個gap lock 。

如果一個會話有一個共享的或者排它的鎖在記錄r 在一個索引裡,

另外一個會話不能插入一個新的index record 在gap .

假設 一個index 包含值10, 11, 13, and 20. 可能的next-key locks 對于這個索引副高下面的間隔,

在最後一個區間, next-key lock 鎖住gap 在最大的值上

gap locks

next-key locking 例子在先前的章節 顯示一個gap 可能跨越一個單獨的index value,

多個index value 或者甚至是空的。

區間鎖 對于語句鎖住記錄使用一個唯一的索引是不需要的 來搜尋一個唯一值。

(這個不包括所有條件值隻包含多列唯一索引的一些列,在這種情況下,間隙鎖确實發生)

比如,如果id 列有一個唯一的索引,下面的語句隻使用一個index-record lock 用于記錄id值為100

select * from child where id = 100;

如果id 沒有被索引或者沒有一個 nonunique index, 語句 鎖定前面的gap

一種類型的gap lock 稱為一個insert t intention gap lock 是被設定通過insert 操作優先于行插入。

lock 發信号意圖插入以這樣的方式,多個事務插入相同的index gap 不需要等待對于每個其他的如果它們

它們不是插入在相同的位置。

假設這裡有index records 值為4和7,單獨的事務嘗試插入值5和6 每個lock 間隙在4和7

插入 intention locks 優先的 得到排它鎖在被插入的記錄,但是不堵塞每個其他的因為記錄是不沖突的。

同樣值得注意的是,沖突鎖可以持有在一個gap 通過不同的事務。

比如, 事務a 可以持有一個共享的gap lock(gap s-lock) 在一個gap

當事務b 持有一個排他的gap lock(gap x-lock)在同樣的gap.

disabling gap locking:

gap locking 可以被顯示的禁用, 這個發生在如果你改變了事務的隔離級别為 read committed

或者啟用innodb_locks_unsafe_for_binlog system variable