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

推薦する

イラスト風ウェブサイトホームページデザイン ウェブサイトデザインの新トレンド

視覚効果が非常に美しく、訪問者に強い印象を残すことがわかります。さらに、重要なポイントが強調され、訴...

Oracle10パーティションとMySQLパーティションの違いの詳細な説明

一般的に使用される Oracle10g パーティションは、範囲 (範囲パーティション)、リスト (リ...

MySQL 5.7.18 でパスワードを変更する方法

MySQL 5.7.18 でパスワードを変更する方法: 1. まずMySQLサーバーをシャットダウン...

Ubuntuデュアルシステムが起動時に停止する問題の解決方法の詳細な説明

起動時に Ubuntu デュアル システムが停止する問題の解決方法 (Ubuntu 16.04 およ...

jQueryはシンプルなカルーセル効果を実装します

みなさんこんにちは。今日はカルーセルの実装についてお話しします。私が作成したカルーセルの効果は次のと...

MacにMySQLデータベースをインストールする方法を教えます

Mac 用 MySQL をダウンロード: https://downloads.mysql.com/a...

JavaScriptはブラウザがIEかどうかを判定します

フロントエンド開発者としては、IEの落とし穴は避けて通れません。他のブラウザはいいのにIEは壊れてい...

CSS 疑似要素と疑似クラスの魔法のような使い方についての簡単な説明

CSS は Web ページで非常に重要な役割を果たします。近年の CSS の発展に伴い、疑似要素/疑...

MySQL スケジュールタスク (EVENT イベント) を詳細に設定する方法

目次1. イベントとは何ですか? 2. 「イベント」機能を有効にする1. 機能が有効になっているかど...

MySQL クエリにおける LIMIT の大きなオフセットによって引き起こされるパフォーマンス低下の分析

序文MySQLクエリはselectコマンドを使用し、limitとoffsetパラメータを使用して、指...

Vue で SuperMap を使用する練習

目次序文関連資料Vue プロジェクトが 2 次元ハイパーグラフを導入ハイパーグラフ 2D ケース引用...

NginxはIP経由の直接アクセスを禁止し、カスタム500ページにリダイレクトします

設定ファイルに直接 サーバー{ listen 80 default; # IPへの直接アクセスを禁止...

シンプルな時計を実装するJavaScript

この記事では、JavaScriptでシンプルな時計を実装するための具体的なコードを参考までに紹介しま...

Linux で SSH サーバー エイリアスを作成する 2 つの方法

序文SSH 経由でさまざまなリモート システムに頻繁にアクセスする場合は、このトリックを使用すると時...

Vue.js $refs 使用例の説明

プロパティやイベントがあるにもかかわらず、JavaScript で子コンポーネントに直接アクセスする...