InnoDBのロック

5482 ワード

InnoDBには主に以下のロックがあります.
  • 共有ロック(shared lock)および排他ロック(exclusive lock)
  • 意向ロック(intention locks)
  • 行ロック
  • ギャップロック
  • next-key locks
  • 挿入意向ロック(insert intention locks)
  • 自己成長ロック(auto-inc locks)
  • Predicate Locks for Spatial Indexes

  • Shared and Exclusive Locks
    Innodbは標準の行レベルロックをサポートし、共有ロックと排他ロックの2種類があります.
  • 共有ロックは、ロックを保持するトランザクションがローデータを読み出すことを許可する.
  • は、ロックを保持するトランザクションがデータを変更または削除することを許可するロックをたたきます.

  • トランザクションT 1が行rに共有ロックを持っている場合、他の独立したトランザクションT 2が行rにロックをかけることは、次の条件を満たす.
  • は、他のトランザクションT 2が行rに共有ロックをかけることを可能にする.この場合、T 1とT 2は、行rに共有ロック
  • を同時に持つことができる.
  • T 2が行rにそのロックを追加する場合は許可されません.

  • トランザクションT 1が行r上の排他ロックを保持している場合、他のトランザクションT 2は、行r上に共有ロックを付加するか排他ロックを付加するかにかかわらず許可されず、T 2は、T 1が行rに対して保持しているロックを解放するのを待たなければならない.
    Intention Locks
    Innodbは、行ロックとテーブルロックの共存を可能にする複数の粒度ロックをサポートします.例えばLOCK TABLESのように...WRITEのようなSQLは指定されたテーブルに排他ロックをかけます.複数の粒度でロックを実現するために、Innodbは意図ロック(intention locks)を使用する.意向ロックは、トランザクションが後でテーブル内のローに対してどのタイプのロック(共有ロックまたは排他ロック)を使用するかを示すテーブル・レベルのロックです.2つのタイプの意向ロックがあります.
  • 共有意向ロック(intention shared lock)は、トランザクションがテーブル内の個別のローで共有ロックを使用しようとしていることを示す.
  • 排他意向ロック(intentive exclusive lock)は、トランザクションがテーブル内の個別行で排他ロックを使用する予定であることを示す.

  • 例えばSELECT...LOCK IN SHARE MODEこのSQLは共有意向ロックを使用しています.SELECT...FOR UPDATEというSQLは排他的な意向ロックを使用しています.
    意向ロックの協議は以下の通りである.
  • トランザクションは、テーブル内のローの共有ロックを取得する前に、まずテーブル上で共有意向ロックまたはより強いロック(排他ロック)を取得する必要がある.
  • トランザクションは、テーブル内のローの排他ロックを取得する前に、まずテーブル上で排他意向ロックを取得する必要があります.

  • 意向ロックは、全テーブルロック以外の要求(例えば、LOCK TABLE...WRITE)をブロックするものではない.彼の主な目的は、誰かがローをロックしたり、テーブルのローをロックしたりすることです.
    SHOW ENGINE INNODB STATUSまたはinnodbモニタの出力タイプの下にロックすることを意図する
    TABLE LOCK table `test`.`t` trx id 10080 lock mode IX

    行ロック(Record Locks)
    ロー・ロックはインデックス上のロックです.比例SELECT c 1 FROM table WHERE c 1=10 FOR UPDATE;他のトランザクションの挿入を阻止し、c 1=10のレコードを削除または変更します.
    ロー・ロックは常にインデックス内のレコードでロックされます.テーブルにインデックスが指定されていない場合でも、InnoDBは暗黙的にクラスタ・インデックスを作成し、このクラスタ・インデックスを使用してロー・ロックを行います.
    ロー・ロックのトランザクション・データは、SHOW ENGINE INNODB STATUSおよびInnoDBモニタの出力に次のタイプがあります.
    RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t` 
    trx id 10078 lock_mode X locks rec but not gap
    Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
     0: len 4; hex 8000000a; asc     ;;
     1: len 6; hex 00000000274f; asc     'O;;
     2: len 7; hex b60000019d0110; asc        ;;

    ギャツプロック
    ギャップロックは、インデックス間のギャップに対するロック、またはインデックスに対して最初のエントリの前または最後のエントリの後のギャップを記録するロックです.例えばSELECT c 1 FROM t WHERE c 1 BETWEEN 10 and 20 FOR UPDATE;ギャップ内のすべての範囲の値がロックされているため、他のトランザクションがc 1=15のレコードをテーブルに挿入することはできません.
    ギャップは、単一のインデックス値、複数のインデックス値、または空にまたがる場合があります.
    ギャップ・ロックは、すべてではなく、特定のトランザクション・独立性レベルでパフォーマンスと同時実行のバランスです.
    ユニークなインデックスを使用してユニークなローを検索するSQL文では、ギャップインデックスを使用する必要はありません(これは、ユニークなインデックスに一致するカラムが1つしか含まれていない場合ではありません.この場合もギャップインデックスが使用されます).たとえば、id列があり、一意のインデックスが付いています.次のSQLでは、id=100のローレコードをロックするためにローロックのみが使用されます.他のセッションが前のギャップにローを挿入するかどうかは重要ではありません.
    SELECT * FROM child WHERE id = 100;

    id列にインデックスがないか、インデックスが一意でない場合、このSQLは前のギャップをロックします.
    異なるトランザクションが1つのギャップに競合ロックを保持できることに注意してください.たとえば、トランザクションBが排他的なギャップ・ロックを持つと同時にトランザクションAが共有するギャップ・ロックを持つことができ、競合するギャップ・ロックを保存できるのは、インデックスからレコードを消去する場合、異なるトランザクションがレコードに保持するギャップ・ロックをマージする必要があるためです.
    共有ロックはInnoDBでは「純粋に抑制されている」ため、他のトランザクションがギャップにデータを挿入することを防止することが唯一の目的であり、ギャップロックは共存することができることを意味します.1つのトランザクションが取得するギャップロックは、別のトランザクションが同じギャップに対してギャップロックを取得することを阻害するものではありません.共有ギャップロックと排他ギャップロックには違いはありません.他のトランザクションと競合することはありません.同じ機能を持っています.
    クリアランスロックは明示的に無効にできます.トランザクション独立性レベルがread_に設定されている場合commitedまたは有効innodb_locks_unsafe_for_binlog( )  。 , , 。READ_の使用COMMITED独立性レベルまたはinnodb_の有効化locks_unsafe_for_binlogには他にも影響があります.非整合行の行ロックは、MysqlがWHERE条件を評価した後に解放される.UPDATE文の場合、InnoDBは、最後に送信データをMySQLに返し、その行がUPDATEのwhere条件に一致するかどうかを判断するために、「半一致」読み出しを実行する.
    Next-Key Locks(何の名前に訳すべきか分からない)
    next-key lockロックは、コンビネーションロック(インデックス上のローロックとインデックス記録前のギャップ上のギャップロック)です.
    InnoDBは、テーブルインデックスを検索またはスキャンするときに行レベルロックを実行し、遭遇したインデックスレコードに対して共有ロックまたは排他ロックを設定するので、行ロックは実際にはインデックスレコードロックである.インデックスレコードのnext-key lockも、このレコードの前のギャップに影響します.すなわち、next-key lockは、インデックスレコードロックにインデックスレコードの前のギャップを加えたギャップロックです.
    デフォルトでは、InnoDBはREPEATABLE READ , ,InnoDB next-key lock , 。で実行されます.
    意向ロックの挿入(Insert Intention Lock)
    挿入意向ロックは、挿入操作が実行される前に設定されるギャップロックである.同じインデックス・ギャップに挿入された複数のトランザクションがギャップ内の同じ場所に挿入されない場合、このロックは挿入の意図を表し、同じギャップ・ロックに挿入された複数のトランザクションが互いに待つ必要がないようにします.値が4と7のインデックスレコードがあると仮定すると、2つの独立したトランザクションはそれぞれ5と6のレコードを挿入しようとし、挿入ローの排他的なロックを取得する前に、各ロックは4と7の間で挿入意向ロックのギャップを使用しますが、これらのローは競合しないため、互いにブロックされません.
    自己成長ロック(Auto-Inc locks)
    自己成長ロックは特殊な表レベルロックで、トランザクションが自己成長列を持つテーブルを挿入するために使用されます.最も簡単な場合、トランザクションがテーブルを挿入している場合、他のトランザクションは、最初のトランザクションが挿入したローが連続するプライマリ・キー値を受信するように、テーブルを自分で挿入するのを待つ必要があります.
    パラメータinnodb_autoinc_lock_modeは、厳格な秩序化された成長と最大同時挿入性能との間でバランスをとることができる、自己ロックを使用するアルゴリズムを制御することができます.
    Predicate Locks for spatial Index(空間インデックスのロック)
    InnoDBは空間列を含む空間インデックスをサポートする
    空間インデックスに関するロック操作を処理するには、next-key lockはREPEATABLE_をうまくサポートできません.READとSERIALIZABLEトランザクションの独立性レベルは、多次元データに絶対的なソート概念がないため、どのキーが「次」であるかは不明です.
    スペースインデックスを持つテーブル独立性レベルをサポートするために、InnoDBはPredicate Lockを使用し、スペースインデックスは最小境界矩形(MBR)値を含むため、InnodbはクエリのMBR値にPredicate lockを設定することによってインデックスデータの一貫性のある読み取りを強制し、他のトランザクションは一致に関連するローを挿入または変更できません.