MySQL InnoDB ロックの概要

MySQL InnoDB ロックの概要

1. 共有ロックと排他ロック

共有ロック

排他ロック

InnoDB は、共有ロックと排他ロックの 2 種類のロックを含む標準の行レベル ロックを実装します。

共有 (S) ロックは、ロックを保持しているトランザクションが行を読み取ることを許可します。

排他 (X) ロックは、ロックを保持するトランザクションが行を更新または削除することを許可します。

共有ロックにより、ロックを保持しているトランザクションは行を読み取ることができます。

排他ロックにより、ロックを保持しているトランザクションは行を更新または削除できるようになります。

トランザクション T1 が行 r に対して共有ロック (S) を保持している場合、別のトランザクション T2 からの要求は次のように処理されます。

  • T2 の S ロック要求は直ちに許可されます。その結果、T1 と T2 の両方が行 r に対して S ロックを保持します。
  • T2 の X ロック要求はすぐには許可されません。

トランザクション T1 が行 r に対して排他ロック (X) を保持している場合、別のトランザクション T2 からの要求に対して、r に対するどちらのタイプのロックもすぐに付与することはできません。代わりに、トランザクション T2 は、トランザクション T1 が行 r のロックを解除するまで待機する必要があります。

2. 意図ロック

意図ロック

InnoDB はマルチ粒度ロックをサポートしており、行ロックとテーブルロックの共存が可能です。 たとえば、LOCK TABLES ... WRITE などのステートメントは、指定されたテーブルに対して排他ロック (X ロック) を取得します。複数の粒度レベルでロックを実装するために、InnoDB はインテンション ロックを使用します。インテンション ロックは、テーブル レベルのロックであり、トランザクションに対して、後でテーブル内の行に使用する必要があるロックの種類 (共有または排他) を示します。

インテンションロックには 2 つの種類があります。

  • 意図的共有ロック (IS) は、トランザクションがテーブル内の単一行に共有ロックを設定することを意図していることを示します。
  • 意図的排他ロック (IX) は、トランザクションがテーブル内の 1 つの行に排他ロックを設定することを示します。

たとえば、SELECT ... LOCK IN SHARE MODE は IS ロックを設定し、SELECT ... FOR UPDATE は IX ロックを設定します。

意図ロックの合意は次のとおりです。

トランザクションがテーブル内の行に対して共有ロックを取得する前に、まずテーブルに対して IS ロックまたはより強力なロックを取得する必要があります。
トランザクションがテーブル内の行の排他ロックを取得する前に、まずそのテーブルで IX ロックを取得する必要があります。
テーブルレベルのロック タイプの互換性は次のとおりです。

要求元のトランザクションが既存のロックと互換性がある場合はロックが許可されますが、既存のロックと競合する場合はロックは許可されません。トランザクションは、競合する既存のロックが解除されるまで待機します。ロック要求が既存のロックと競合し、デッドロックが発生するため許可できない場合は、エラーが発生します。

意図ロックは、テーブル全体のリクエスト (LOCK TABLES ... WRITE など) 以外をブロックしません。意図的ロックの主な目的は、誰かがテーブル内の行をロックしている、またはロックしようとしていることを示すことです。

3. レコードロック

レコードロック

レコード ロックは、インデックス レコードに対するロックです。

レコード ロックは、インデックス レコードに対するロックです。たとえば、SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; は、t.c1 の値が 10 である行を他のトランザクションが挿入、更新、または削除することを防ぎます。

レコード ロックは、テーブルにインデックスが定義されていない場合でも、常にインデックス レコードをロックします。テーブルにインデックスがない場合、InnoDB は非表示のクラスター化インデックスを作成し、そのインデックスをレコードのロックに使用します。

4. ギャップロック

ギャップロック

ギャップ ロックは、インデックス レコード間のギャップに対するロック、または最初のインデックス レコードの前または最後のインデックス レコードの後のギャップに対するロックです。

ギャップ ロックは、インデックス レコード間のギャップに対するロック、または最初のインデックス レコードの前または最後のインデックス レコードの後のギャップに対するロックです。

たとえば、SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; は、範囲内のすべての既存の値間のギャップがロックされるため、列に既にそのような値があるかどうかに関係なく、他のトランザクションが t.c1 列に値 15 を挿入することを防ぎます。

ギャップは、単一のインデックス値、複数のインデックス値にまたがる場合があり、空になる場合もあります。

ギャップ ロックは、パフォーマンスと同時実行性のトレードオフの一部であり、一部のトランザクション分離レベルで使用されますが、他のレベルでは使用されません。

一意の行を検索するために一意のインデックスを使用して行をロックするステートメントの場合、ギャップ ロックは必要ありません。

たとえば、id 列に一意のインデックスがある場合、次のステートメントは、他のセッションが前のギャップに行を挿入するかどうかに関係なく、id 値が 100 の行に対してのみインデックス レコード ロックを取得します。

SELECT * FROM child WHERE id = 100;

id 列にインデックスがないか、一意でないインデックスがある場合、ステートメントは先頭のギャップをロックします。

ここで注目すべき点は、異なるトランザクションがギャップに対して競合するロックを保持する可能性があることです。

たとえば、トランザクション A はギャップに対して共有ギャップ ロック (ギャップ S ロック) を保持し、トランザクション B は同じギャップに対して排他ギャップ ロック (ギャップ X ロック) を保持できます。競合するギャップ ロックを許可する理由は、レコードがインデックスから削除された場合、異なるトランザクションによって保持されているレコードのギャップ ロックをマージする必要があるためです。

InnoDB におけるギャップ ロックの唯一の目的は、他のトランザクションがギャップに挿入されるのを防ぐことです。ギャップロックは共存できます。あるトランザクションによって取得されたギャップ ロックは、別のトランザクションが同じギャップに対してギャップ ロックを取得することを妨げるものではありません。共有間隔ロックと排他間隔ロックの間に区別はありません。それらは互いに競合せず、同じ機能を実行します。

5. ネクストキーロック

ネクストキー ロックは、インデックス レコードに対するレコード ロックと、インデックス レコードの前のギャップに対するギャップ ロックの組み合わせです。

ネクストキー ロックは、インデックス レコードのレコード ロックとインデックス レコードの前のギャップ ロックの組み合わせです。

InnoDB が行レベルのロックを行う方法は、テーブル インデックスを検索またはスキャンするときに、検出されたインデックス レコードに共有ロックまたは排他ロックを設定するというものです。したがって、行レベルのロックは実際にはインデックス レコード ロックです。インデックス レコードの次のキー ロックは、そのインデックス レコードの前の「ギャップ」にも影響します。つまり、次のキー ロックは、インデックス レコード ロックと、インデックス レコードの前のギャップ ロックを組み合わせたものになります。セッションがインデックス内のレコード R に対して共有ロックまたは排他ロックを持っている場合、別のセッションはインデックス順序で R の前のギャップに新しいインデックス レコードを挿入できません。

インデックスに値 10、11、13、20 が含まれているとします。このインデックスの可能な次のキー ロックは、次の範囲をカバーします。

(負の無限大、10]
(10、11]
(11、13)
(13、20)
(20、正の無限大)

デフォルトでは、InnoDB は REPEATABLE READ トランザクション分離レベルを使用します。この場合、InnoDB はファントム行を防ぐために、検索とインデックス スキャンに次のキー ロックを使用します。

6. 意図ロックを挿入する

意図ロックを挿入する

挿入意図ロックは、行が挿入される前に INSERT 操作によって設定されるギャップ ロックです。このロックは、複数のトランザクションが同じインデックス ギャップに挿入する場合、ギャップ内の同じ位置に挿入していない限り、トランザクションが互いに待機する必要がないことを意味します。値が4と7のインデックスレコードがあると仮定します。別々のトランザクションが値 5 と 6 を挿入しようとします。各トランザクションは、挿入された行の排他ロックを取得する前に、挿入意図ロックを使用して 4 と 7 の間のギャップをロックしますが、行は競合しないため、互いにブロックされません。

7. AUTO-INCロック

AUTO-INC ロックは、AUTO_INCREMENT 列を持つテーブルに挿入するトランザクションによって取得される特別なテーブル レベルのロックです。最も単純なケースでは、1 つのトランザクションがテーブルに値を挿入している場合、他のトランザクションは、最初のトランザクションによって挿入された行が連続した主キー値を受け取るように、そのテーブルへの独自の挿入を待機する必要があります。

ロックの適用

上記はMySQL InnoDBロックの詳細な概要です。MySQL InnoDBロックの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL InnoDB トランザクション ロック ソースコード分析
  • MySQL InnoDB のロック機構の詳細な説明
  • MySQL の InnoDB ストレージ エンジンのロックの基本的な使用方法のチュートリアル
  • MySQL の InnoDB のギャップロック問題
  • MySQL InnoDB のロック分類の紹介
  • MySQL InnoDB トランザクションとロックの詳細な説明
  • MySQLのInnoDBストレージエンジンにおけるさまざまなロックの詳細な説明

<<:  Webフロントエンド開発CSS関連チームコラボレーション

>>:  CSS コンテンツ属性を使用して、マウスホバープロンプト (ツールチップ) 効果を実現します。

推薦する

dockerでlnmp環境を構築する方法

プロジェクトディレクトリを作成する php ディレクトリをコピーする次のプロジェクト構造を作成します...

Ubuntu 20.04 中国語入力方法のインストール手順

この記事では、Google 入力方法をインストールします。実は以前はSogou入力方式を使っていたの...

TCPパフォーマンスチューニングの実装原理とプロセス分析

3ウェイハンドシェイクフェーズクライアントSYNパケットの再試行回数sysctl -w net.ip...

TCPソケットSYNキューとAcceptキューの差異分析

まず、「LISTENING」状態の TCP ソケットには 2 つの独立したキューがあることを理解する...

MySQL PXC は IST 送信のみで新しいノードを構築します (推奨)

需要シナリオ: 既存の PXC 環境には大量のデータがあります。新しく購入したサーバーをこのクラスタ...

Vueベースのビデオプレーヤーの実装例

既存のビデオ プレーヤーがニーズを満たせない場合は、ビデオを自分でカプセル化する必要があります。ビデ...

nginx + セカンダリドメイン名 + https サポートを使用する

ステップ1: Alibaba Cloudプライマリドメイン名にセカンダリドメイン名を追加する2 番目...

Django は Pillow を使用して検証コード機能を簡単に設定します (Python)

1. モジュールをインポートし、検証状態を定義する PIL から Image、ImageDraw、...

スライドボタン効果を実現するネイティブJS

Jsで作ったスライドボタンの具体的なコードは参考までに。具体的な内容は以下のとおりですまずエフェク...

MySQL データベース グループ クエリの group by ステートメントの詳細な説明

1: グループ化関数の記述順序 1 選択 ... 2 から ... 3 どこで ... 4 グループ...

MYSQL スロークエリとログ設定とテスト

1. はじめにスロークエリログを有効にすると、MySQL は指定された時間を超えるクエリステートメン...

開発をスピードアップできる VueUse ライブラリ 5 つ (まとめ)

目次VueUse にはどのようなユーティリティがありますか? VueUseをVueプロジェクトにイン...

Linuxファイル削除後にスペースが解放されない問題の詳しい説明

序文システム領域の使用量が大きすぎて消去する必要がある場合、または特定のファイルを消去する必要がある...

MySQL監視ツールmysql-monitorの詳細な説明

1. 概要mysql-monitor MYSQL 監視ツール、最適化ツール、1 つの Java Sp...

Vue+video.jsはビデオプレイリストを実装します

この記事では、ビデオプレイリストを実装するためのvue + video.jsの具体的なコードを参考ま...