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

推薦する

SpringBoot アプリケーションの Docker デプロイメントの実装手順

目次序文DockerファイルDockerfile とは何ですか? Dockerfile 構文Spri...

Tomcat で JNDI データ ソースを構成する 3 つの方法

これまでの仕事では、開発サーバーは一般的にTomcatでした。データソースは、多くの場合、appli...

Docker が MySQL を作成する説明

1. MySQLイメージをダウンロードするコマンド: docker pull mysql 2. コン...

MySqlデータベースをバックアップするいくつかの方法

mysqldump ツールのバックアップデータベース全体をバックアップする $> mysqld...

Windows 10 Home Edition に Docker をインストールする方法

最近、プロジェクトをアップグレードするために Docker を使用しました。これまで使用したことがな...

JavaScript 事前分析、オブジェクトの詳細

目次1. 事前分析1. 変数の事前解析と関数の事前解析1. 変数の事前解析2. 機能事前分析2. 事...

MySQLステートメントを監視する方法の詳細な説明

クイックリーディングSQL ステートメントを監視する必要があるのはなぜか、監視方法と監視手段について...

Vueのキーボードイベントの詳細な説明

目次共通キーエイリアスエイリアスが指定されていないキーシステム修飾キーカスタムキーエイリアス要約する...

CSSはフロートをシミュレートして、画像の左右を囲む中央テキストの効果を実現します。

画像の周囲にテキストを折り返すとは何ですか?これは次の図の効果です。 エフェクトのCSSコードはここ...

MySQLの重複排除方法

MySQLの重複排除方法【初級】繰り返しのセリフが少ないdistinctive を使用してそれらを見...

Reactの状態管理の3つのルールのまとめ

目次序文No.1 焦点No.2 複雑な状態ロジックの抽出No.3 複数状態操作の抽出要約する序文Re...

Linux telnetコマンドの使用

1. はじめにtelnet コマンドは、リモート ホストにログインするために使用されます。これは、T...

フレックスレイアウトは左のテキストオーバーフローを実現し、右のテキストの適応を省略します

テキストの長さに応じて、左側のテキストの幅を自動調整できる状況を実現したい。1行が表示できない場合、...

ubuntu20.04 LTSにdockerをインストールする方法

ゼロ: 古いバージョンをアンインストールするDocker の古いバージョンは、docker、dock...

nginx で Vue プロジェクトをデプロイする方法

今日は nginx サーバーを使用するのですが、vue プロジェクトをサーバーにデプロイする必要もあ...