Inno DB分離レベルとロック
-
28-10-2019 - |
質問
InnoDBトランザクションについてのマニュアルを読んでいますが、それでも私には不明確なものがたくさんあります。たとえば、私は次の動作をよく理解していません。
-- client 1 -- client 2
mysql> create table simple (col int)
engine=innodb;
mysql> insert into simple values(1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into simple values(2);
Query OK, 1 row affected (0.00 sec)
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update simple set col=10 where col=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update simple set col=42 where col=2;
-- blocks
ここで、最後の更新コマンド(クライアント2)が待機します。行1のみがロックされていると思われるため、コマンドが実行されると期待します。クライアント2の2番目のコマンドがあっても、動作は同じです insert
. 。この例の背後にあるロックの背景を誰でも説明できますか(どこで、なぜロックがありますか)?
解決
INNODBは、特定の種類のロックを次のように設定します。
Select ... fromは一貫した読み取りであり、データベースのスナップショットを読み取り、トランザクションの分離レベルがシリアル化可能に設定されていない限り、ロックを設定しません。シリアル化可能なレベルの場合、検索は、遭遇するインデックスレコードで次のキーロックを共有します。
Select ... from ...ロックインシェアモードセットは、すべてのインデックスレコードの共有ネクストキーロックを検索エンカウンターに記録します。
インデックスレコードの検索エンカウンターの場合、... from ... from ... updateの場合、他のセッションを選択することをブロックします。一貫した読み取りは、読み取りビューに存在するレコードに設定されたロックを無視します。
更新...ここで...検索の出会いのすべてのレコードに排他的な次のキーロックを設定します。
削除...ここから...検索の出会いのすべてのレコードに排他的な次のキーロックを設定します。
挿入挿入行に排他的ロックを設定します。このロックはインデックスレコードロックであり、次のキーロックではなく(つまり、ギャップロックはありません)、挿入された行の前に他のセッションがギャップに挿入することを妨げません。
INNODBには、いくつかのタイプのレコードレベルのロックがあります。
レコードロック:これはインデックスレコードのロックです。
ギャップロック:これは、インデックスレコードの間のギャップのロック、または最初のインデックスレコード前または最後のインデックスレコードの前のギャップのロックです。
次のキーロック:これは、インデックスレコードのレコードロックと、インデックスレコードの前のギャップのギャップロックの組み合わせです。
続きを見る :
他のヒント
ypercubeには正しいです。具体的には、この条件で使用される一意のインデックスがなければ、影響を受ける単一の行よりもロックされます。
あなたが期待する動作を見るために、あなたのテーブルの作成をこれに変更してください:
create table simple (col int unique) ENGINE=InnoDB;
の一意のインデックス col
フィールドは、影響を受ける行のみをロックすることができます。
「インデックスレコードの検索エクセントの場合、Select ... from ... Update Blocks from Select ... from ... from ... lock in shareモードまたは特定のトランザクション分離レベルで読み取ります。一貫した読み取りはロックを無視します読み取りビューに存在するレコードに設定します」
他のセッションがロックされたレコードを読み取ることができないように、更新用にSELECTで適用できる特定のロックは何ですか?