MySQL (InnoDB) がデッドロックを処理する方法の詳細な説明

MySQL (InnoDB) がデッドロックを処理する方法の詳細な説明

1. デッドロックとは何ですか?

正式な定義は次のとおりです: 2 つのトランザクションが相手側で必要なロックを保持し、相手側がロックを解放するのを待機しており、どちらの側も独自のロックを解放しません。

これは、自分と相手が人質を取っていて、二人で人質交換の交渉をするようなものです。あなたは相手にプレーヤーを解放するように求め、相手もあなたにプレーヤーを解放するように求めます。

2. デッドロックはなぜ発生するのでしょうか?

これを見ると、こんな疑問が湧くかもしれません。トランザクションはネゴシエーションとは異なります。トランザクションはロックを使用した後すぐにロックを解除できないのはなぜでしょうか?操作が完了した後もロックを保持する必要がありますか?これには、MySQL の同時実行制御が関係します。

MySQL には同時実行制御の方法が 2 つあります。1 つは MVCC で、もう 1 つは 2 フェーズ ロック プロトコルです。では、なぜ同時実行制御が必要なのでしょうか?これは、複数のユーザーが同時に MySQL を操作する場合、同時実行性能を向上させるために、複数のユーザーからのリクエストをシリアルに実行する必要があるためです (シリアル化可能なスケジューリング)。具体的な同時実行制御についてはここでは説明しません。 2 フェーズ ロック プロトコルについてさらに詳しく説明しましょう。

2 フェーズ ロック プロトコル (2PL)

公式定義:

2 フェーズ ロック プロトコルとは、すべてのトランザクションが 2 フェーズでデータをロックおよびロック解除する必要があることを意味します。データの読み取りまたは書き込みを行う前に、トランザクションはまずデータのロックを取得する必要があります。ロックを解除すると、トランザクションは他のロックを適用したり取得したりできなくなります。

MySQL に対応して、2 つのステージに分かれています。

  1. 拡張フェーズ(トランザクション開始後、コミット前):ロックを取得する
  2. 収縮フェーズ(コミット後):ロックを解除する

つまり、2 段階ロック プロトコルに従うことによってのみ、シリアル化可能なスケジューリングを実現できます。

ただし、2 フェーズ ロック プロトコルでは、トランザクションが使用する必要があるすべてのデータを一度にロックする必要はなく、ロック フェーズでは順序の要件がないため、この同時実行制御方法ではデッドロックが発生します。

3. MySQL はデッドロックをどのように処理しますか?

MySQL には 2 つのデッドロック処理方法があります。

  1. タイムアウトまで待機します (innodb_lock_wait_timeout=50s)。
  2. デッドロック検出を開始し、トランザクションを積極的にロールバックし、他のトランザクションの実行を継続できるようにします (innodb_deadlock_detect=on)。

パフォーマンス上の理由から、デッドロックの処理には通常、デッドロック検出が使用されます。

デッドロック検出

デッドロック検出の原理は、トランザクションを頂点、ロックを辺とする有向グラフを構築し、有向グラフにサイクルがあるかどうかを判断することです。サイクルがある場合は、デッドロックがあります。

ロールバック

デッドロックが検出されると、INFORMATION_SCHEMA.INNODB_TRX テーブルの trx_weight フィールドに基づいて、挿入、更新、または削除された行数が最も少ないトランザクションがロールバック対象として選択されます。

4. デッドロックを回避する方法

デッドロック情報を収集します。

  1. デッドロックの原因を確認するには、SHOW ENGINE INNODB STATUS コマンドを使用します。
  2. デバッグフェーズでは、すべてのデッドロック ログを収集するために innodb_print_all_deadlocks が有効になります。

デッドロックを減らす:

  1. トランザクションを使用し、テーブルをロックしないでください。
  2. 長いトランザクションがないことを確認します。
  3. 特に対話型コマンド ラインでは、操作後すぐにトランザクションをコミットします。
  4. (SELECT ... FOR UPDATE または SELECT ... LOCK IN SHARE MODE) を使用している場合は、分離レベルを下げてみてください。
  5. 複数のテーブルまたは複数の行を変更する場合は、変更順序の一貫性を保ちます。
  6. インデックスを作成すると、ロックが少なくなります。
  7. (SELECT ... FOR UPDATE または SELECT ... LOCK IN SHARE MODE) は使用しないことをお勧めします。
  8. 上記で問題が解決しない場合は、ロックテーブルt1、t2、t3を使用して複数のテーブルをロックしてみてください。

上記は、MySQL (InnoDB) がデッドロックを処理する方法についての詳細な説明です。お役に立てれば幸いです。ご質問がある場合は、メッセージを残していただければ、すぐに返信いたします。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。

以下もご興味があるかもしれません:
  • MySQLデッドロックの原因と解決策
  • MySQLのデッドロックチェック処理の通常の方法
  • MySQL デッドロック問題の分析と解決例
  • Ali インタビュー MySQL デッドロック問題の処理

<<:  Vue は URL に基づいて非同一オリジンのファイルをどのようにダウンロードするのか

>>:  Nginx Rewriteモジュールを使用するいくつかのシナリオ

推薦する

JavaScript のマクロタスクとマイクロタスクの詳細

目次1. マイクロタスクとは何ですか? 2. マクロタスクとは何ですか? 3. 事例3.1 結論4....

MySQL COUNT関数の使用と最適化

目次COUNT 関数は何をするのですか? MyISAMの「魔法」シンプルなCOUNT最適化近似値を使...

クールなページング効果を実現するネイティブJS

この記事では、次のような効果を持つ JS ページング効果の例を紹介します。クールだと思いませんか? ...

ウェブ上でチャートを描くための 9 つの優れた JavaScript フレームワーク スクリプト

ウェブ上でチャートを描くための 9 つの優れた JavaScript フレームワーク スクリプト 1...

React Diff Principle の詳細な分析

目次差分アルゴリズムレイヤーごとの比較同じタイプのコンポーネントを比較する同じタイプの要素の比較子ノ...

docker を使用して Django テクノロジー スタック プロジェクトをデプロイする方法

Docker の人気と成熟に伴い、Docker は徐々にプロジェクトをデプロイするための第一の選択肢...

フォームの「Enter」、「Submit」、「Enter != Submit」を削除する方法

「Enter != Submit」問題を実装するには、通常、「ボタンの種類」と「入力ボックスの数」か...

docker で PostgreSQL データベースをインストールして永続化する方法

Dockerのインストール手順をスキップする1. postgresqlイメージを取得する docke...

MySQL 8.0.22 winx64 のインストールと設定のグラフィックチュートリアル

mysql 8.0.22 winx64のインストールと設定のグラフィックチュートリアルは参考までに、...

Docker を使用した MySQL のデプロイの詳細説明 (データ永続化)

この記事では、Docker を使用して MySQL をデプロイし、データを保持する方法について簡単に...

MySQLの左結合と内部結合について簡単に説明します

序文最近、X 省のコールド チェーン トレーサビリティ システムの開発で忙しくしています。毎日午後 ...

jQueryをベースにカルーセル効果を実現する

この記事では、カルーセルマップの効果を実現するためのjQueryの具体的なコードを参考までに共有しま...

...

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

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

MySQL ジョイントインデックスの使用ルール

結合指数は複合指数とも呼ばれます。複合インデックスの場合: MySQL はインデックス内のフィールド...