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 コンテンツ属性を使用して、マウスホバープロンプト (ツールチップ) 効果を実現します。

推薦する

Linux echo テキスト処理コマンドの使用法と例

Linux ヘルプ ドキュメントでの echo の説明は、Python や Java などのプログラ...

Workermanはmysql接続プールのサンプルコードを書きます

まず、接続プールを使用する理由と、接続プールによってどのような問題が解決できるかを理解する必要があり...

Vueルーティングコンポーネントでパラメータを渡す8つの方法の詳細な説明

シングルページアプリケーションを開発する場合、特定のルートを入力し、パラメータに基づいてサーバーから...

私が良いと思うクールなデザインサイトをいくつかまとめてみました。

ウェブサイトをデザインするにはインスピレーションが必要です。良いインスピレーションを得るには、より多...

Vue 父子価値移転、兄弟価値移転、子父価値移転の詳細な説明

目次1. 親コンポーネントが子コンポーネントに値を渡す1. 親コンポーネント.vue 2. サブコン...

MySQL ストアド関数(カスタム関数)の定義と使用方法の詳細な説明

ストアド関数ストアド関数とは: SQL コードの一部をカプセル化し、特定の関数を完了して、結果を返し...

MySQL デッドロック シナリオ例の分析

序文最近、MySQL で RR レベルでデッドロック問題に遭遇しました。興味深いと思ったので、調べて...

JavaScriptのアンチシェイクとスロットリングとは

目次1. 関数デバウンス1. 画像安定化とは何ですか? 2. 関数のスロットリング2.1 タイマーの...

CentOS7にMySQL 8.0.26をインストールする手順

1. まず、お使いのマシンに応じて、MySQL 公式サイトから対応するデータベースをダウンロードしま...

HTML文書の基本構造(Webページ作成の基礎知識)

HTMLの動作原理: 1. ローカル操作: ブラウザでhtmlファイルを開く2. リモートアクセス...

Centos7 システムでの MySQL マスター スレーブ同期構成スキーム

序文最近、高可用性プロジェクトに取り組む際には、データの同期が必要になっています。ノードが 2 つし...

Ubuntu 16.04 サーバーで MySQL を設定し、リモート接続を有効にする方法

背景最近、Node.js を勉強しているのですが、クラウド サーバーがあることを思い出しました。しか...

よく使用される入力テキストボックスの内容は自動的に垂直方向に中央揃えされ、クリックするとデフォルトのプロンプトテキストは空になります。

3つの機能: 1. コンテンツの垂直方向の自動中央揃え2. デフォルトのプロンプトテキストは灰色で表...

MySQL ロックブロッキングの詳細な分析

日常のメンテナンスでは、スレッドがブロックされることが多く、データベースの応答が非常に遅くなります。...

VMware Workstation Pro でサーバー仮想マシンを構築する (グラフィック チュートリアル)

私が使用している VMware Workstation Pro のバージョンは次のとおりです。 1....