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

推薦する

docker コンペ応募でよく使われるコマンドのまとめ

アカウントにログイン DOCKER_REGISTRY=registry.cn-hangzhou.al...

MySQLインデックスを追加する3つの原則を簡単に理解する

1. インデックスの重要性インデックスは、列に特定の値を持つ行をすばやく見つけるために使用されます。...

ページのレンダリング時間を短縮してページの実行速度を速めます

ブラウザでのページのレンダリング時間をできるだけ短縮するにはどうすればよいでしょうか? この記事は、...

CSS テキスト強調を使用してテキストを強調するための実装コード

1. はじめにこれまで、テキストの特定の部分を強調したい場合、通常は太字にしたり明るい色を使用したり...

Vue3 (III) ウェブサイトホームページレイアウト開発

目次1. はじめに2. 実際の事例1. App.vueを変更する2. レイアウトを調整する3. ジャ...

DIV、テーブル、XHTML のウェブサイト構築の違いの分析と説明

簡単に言えば、ウェブサイト構築とは、「この人はどんな外見をしているのか」と「この人はどんな内面を持っ...

Nginx で Basic Auth ログイン認証を設定する方法

nginx でファイルサーバーを構築することもありますが、これは一般に公開されていますが、サーバーが...

プライベートDockerリポジトリであるHarborをインストールするための詳細な手順

Harborのインストールは非常に簡単ですが、Dockerログインで行き詰まってしまいました。このブ...

Vue ベースの要素ボタン権限実装ソリューション

背景要件: ERP システムに「ボタン権限制御」機能を追加する必要があり、権限の制御粒度をボタン レ...

純粋な CSS で実装された 3 つの通知バーのスクロール効果

序文通知バー コンポーネントは、比較的一般的なコンポーネントです。基本的に、すべてのサイトにこのよう...

CocosCreatorでWeChatゲームを作成する方法

目次1. WeChatパブリックプラットフォームからWeChat開発者ツールをダウンロードする2. ...

自動同期テーブル構造のMySql開発

開発の問題点開発プロセスでは、データベース フィールドが頻繁に変更されるため、RD 環境と QA 環...

ElasticSearch と ElasticSearch-Head の Docker デプロイメントの実装

この記事では主にDockerを使ってElasticSearch:バージョン6.8.4をデプロイする方...

Vue3+Vite+TS は、要素プラスビジネスコンポーネントの二次カプセル化を実装します sfasga

目次1. 構造文字列2. タプルを返す3. Dict辞書にアクセスする4. 図書館を利用する5. リ...

MySQLデータベースのマスタースレーブレプリケーションと読み取り書き込み分離に関する詳細なチュートリアル

目次序文1. MySQL マスタースレーブレプリケーション1. サポートされているレプリケーションの...