MySqlステップ-ギャップロック(gap-key)

1651 ワード

参考『InnoDBストレージエンジン』
tips:SELECT...FOR UPDATEは読み出した行レコードにXロックを追加し、他のトランザクションはロックされた行にロックを追加できません.SELECT…LOCK IN SHARE MODEは読み出した行レコードにSロックをかけ、他のトランザクションはロックされた行にSロックをかけることができるが、Xロックをかけるとブロックされる.この2つのコンシステンシロックリードを使用すると、トランザクションを開き、トランザクションをコミットしてロックをロックおよび解放することに注意します.
Innodbロックアルゴリズム
  • Record Lock:単一行レコード上のロック
  • Gap Lock:ギャップロック、1つの範囲をロックするが、記録自体を含まない
  • Next-Key Lock:Gap Lock+Record Lock、1つの範囲をロックし、記録自体
  • をロックする
    Record Lockではインデックスがロックされません.テーブルが確立されたときにインデックスが設定されていない場合、innodbhuiは暗黙的なプライマリ・キーを使用してインデックスをロックします.
    Gap Lockの役割は、複数のトランザクションが同じ範囲にレコードを挿入することを阻止することです.
    InnoDBストレージエンジンは、Next-Key Lockを最適化し、範囲ではなくインデックス自体をロックするRecord Lockに降格します.この場合、クエリのカラムが一意のインデックスである場合に発生します.一意のインデックスが複数のカラムで構成され、クエリが複数の一意のインデックス列のうちの1つのみを検索する場合、クエリが正確なタイプのクエリではなく範囲タイプのクエリである場合、InnoDBストレージエンジンはNext-KeyLockを使用してロックされます.
    InnoDBストレージエンジンでは、INSERTの操作に対して、挿入レコードの次のレコードがロックされているかどうかをチェックし、ロックされている場合はクエリーは許可されません.
    Gap Lockを閉じる
  • トランザクションの独立性レベルをREAD COMMITTED
  • に設定
  • パラメータinnodb_locks_unsafe_for_binlogは1
  • に設定
    Gap-keyが解決した問題
    デフォルトのトランザクション独立性レベル、すなわちREPEATABLE READでは、InnoDBストレージエンジンは、 を回避するためにNext-Key Lockingメカニズムを採用しています.
    同じトランザクションで同じSQL文を2回連続して実行すると、異なる結果が得られ、2回目のSQL文は以前に存在しなかったローを返す可能性があります.
    例(詳細):
    トランザクション1
    トランザクション2
    select * from table where int>2 for update
    結果3 5
    insert into table (4)
    select * from table where int >2 for update
    結果3 4 5
    同じトランザクション内で、同じsql文を前後2回実行し、結果は異なります.一方,Gap-keyを使用する場合,(2,+∞)に鍵をかけ,他のトランザクションの挿入を禁止することができる.
    InnoDBストレージエンジンのデフォルトのトランザクション独立性レベルはREPEATABLE READであり、この独立性レベルではNext-Key Locking方式でロックされている.