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モジュールを使用するいくつかのシナリオ

推薦する

Linuxのpasswdコマンドの使用

1. コマンドの紹介passwd コマンドは、ユーザー パスワード、アカウント ロック、パスワードの...

Docker コマンドラインの完全ガイド (知っておくべき 18 のこと)

序文Docker イメージは Dockerfile といくつかの必要な依存関係で構成され、Docke...

MySQL SQL文の特殊処理文のまとめ(必読)

1.テーブル全体を更新します。データ行の列の値が空の場合は、別の列フィールドの値と同じにします。 ...

ウェブサイトのデザインを改善するための役立つ提案を提供します

<br />ウェブサイトを科学的にデザインする: アイトラッキング研究から学ぶ 23 の...

Vue3 の組み合わせ API における setup、ref、reactive の完全な使用方法

1. セットアップを始める次のコード関数を簡単に紹介します。 ref 関数を使用して変数の変更を監視...

JS 1次元配列を3次元配列に変換する例

今日、CSDN の Q&A セクションで友人が質問をしているのを見ました。彼は 1 次元配列...

Linux でファイアウォールがオフになっているかどうかを確認する方法

1. サービス方法ファイアウォールのステータスを確認します。 [root@centos6 ~]# サ...

React Hooksの使用例

目次簡単なコンポーネントの例より複雑な親子コンポーネントのケースオンセレクトの書き方反応する子供Re...

Js でオブジェクトのディープ オブジェクトを安全に取得するメソッドの例

目次序文文章パラメータ例Lodash 実装:トーキー機能: castPath関数: stringTo...

ウェブ クラスターの Docker Stack 展開方法の手順

Docker はますます成熟し、その機能もますます強力になっています。 Docker Stack を...

Linux exa コマンド (ls よりも優れたファイル表示エクスペリエンス)

インストールREADMEに従ってインストールしてくださいドキュメントには、exa は Rust で実...

パスワードログインなしのLinux構成スタンドアロンおよびフルディストリビューションの詳細なチュートリアル

目次1: 単一マシンのパスワードフリーログイン構成1. 仮想マシンのホスト名を設定する2. 仮想マシ...

通知メッセージカルーセルを実装するための CSS3 トランジション

Vueバージョンをファイルにコピーして使用します <テンプレート> <!-- カル...

Ubuntu 18.04.4 に MySQL をインストールするプロセスの詳細な説明

Ubuntu 18.04.4 に MySQL をインストールするプロセスを見てみましょう。内容は次の...