背景
本番環境でデッドロックが発生しました。デッドロックのログを確認すると、デッドロックの原因は 2 つの同一の更新ステートメント (where 条件の値のみが異なる) であることがわかりました。
は次のとおりです:
UPDATE test_table SET `status` = 1 WHERE `trans_id` = 'xxx1' AND `status` = 0; UPDATE test_table SET `status` = 1 WHERE `trans_id` = 'xxx2' AND `status` = 0;
最初は理解するのが難しかったですが、多くの調査と研究を経て、デッドロック形成の具体的な原理を分析しました。同じ問題を抱えている友人たちに役立つことを願って、この記事をみんなと共有したいと思います。
MySQL には多くの知識ポイントがあるため、多くの名詞はここではあまり紹介しません。興味のある友人は、特別に詳しく学習してフォローしてください。
*** (1) TRANSACTION:
TRANSACTION 791913819, ACTIVE 0 sec starting index read, thread declared inside InnoDB 4999
mysql tables in use 3, locked 3
LOCK WAIT 4 lock struct(s), heap size 1184, 3 row lock(s)
MySQL thread id 462005230, OS thread handle 0x7f55d5da3700, query id 2621313306 x.x.x.x test_user Searching rows for update
UPDATE test_table SET `status` = 1 WHERE `trans_id` = 'xxx1' AND `status` = 0;
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 110 page no 39167 n bits 1056 index `idx_status` of table `test`.`test_table` trx id 791913819 lock_mode X waiting
Record lock, heap no 495 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
*** (2) TRANSACTION:
TRANSACTION 791913818, ACTIVE 0 sec starting index read, thread declared inside InnoDB 4999
mysql tables in use 3, locked 3
5 lock struct(s), heap size 1184, 4 row lock(s)
MySQL thread id 462005231, OS thread handle 0x7f55cee63700, query id 2621313305 x.x.x.x test_user Searching rows for update
UPDATE test_table SET `status` = 1 WHERE `trans_id` = 'xxx2' AND `status` = 0;
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 110 page no 39167 n bits 1056 index `idx_status` of table `test`.`test_table` trx id 791913818 lock_mode X
Record lock, heap no 495 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 110 page no 41569 n bits 88 index `PRIMARY` of table `test`.`test_table` trx id 791913818 lock_mode X locks rec but not gap waiting
Record lock, heap no 14 PHYSICAL RECORD: n_fields 30; compact format; info bits 0
*** WE ROLL BACK TRANSACTION (1)
上記のデッドロック ログを簡単に分析します:
- 1. 最初の内容 (行 1 ~ 9) )、行 6 はトランザクション (1) によって実行される SQL ステートメントで、行 7 と 8 はトランザクション (1) が idx_status インデックスの X ロックを待機していることを意味します;
- 2。コンテンツの 2 番目のブロック (11 行目から 19 行目) では、16 行目はトランザクション (2) によって実行される SQL ステートメントであり、17 行目と 18 行目は、トランザクション (2) が idx_status インデックス X ロック オンを保持していることを意味します。 意味: トランザクション (2) は、PRIMARY インデックスの X ロックの取得を待機しています。 (ただし、ギャップではないということは、ギャップ ロックではないことを意味します)
- 4. 最後の文は、MySQL がトランザクション (1) をロールバックしたことを意味します。
- テーブル構造
CREATE TABLE `test_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `trans_id` varchar(21) NOT NULL, `status` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uniq_trans_id` (`trans_id`) USING BTREE, KEY `idx_status` (`status`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
テーブル構造からわかるように、
trans_id columnuniq_trans_id # に一意のインデックスがあります。 ##,
status 列
idx_status には通常のインデックスがあり、id 列は主キー インデックス
PRIMARY です。
InnoDB エンジンには 2 種類のインデックスがあります:
- クラスター化インデックス:
- データ ストレージとインデックスを配置します。インデックス構造のリーフ ノードは一緒に行データを格納します。
- 補助インデックスのリーフ ノードには、クラスター化インデックスのキー値である主キー値が格納されます。
主キー インデックス
PRIMARY
uniq_trans_id インデックスと
idx_status インデックスは補助インデックスであり、リーフ ノードには主キー値 (id 列の値) が格納されます。
補助インデックスを通じて行データを検索する場合、最初に補助インデックスを通じて主キー ID を見つけ、次に主キー インデックスを通じて二次検索 (これもテーブルに呼び出されます) を実行し、最後に行データを見つけます。
実行計画を見ると、update ステートメントでインデックスのマージが使用されていることがわかります。つまり、このステートメントでは ## の両方が使用されています。 #uniq_trans_id インデックスが再度使用されます
インデックス、 intersect(uniq_trans_id,idx_status)
を使用することは、2 つのインデックスを通じて交差を取得することを意味します。 index_merge が使用される理由
MySQL5.0 より前は、テーブルは一度に 1 つのインデックスしか使用できず、条件付きスキャンで複数のインデックスを同時に使用することはできませんでした。ただし、5.1 からは、
最適化テクノロジが導入され、複数のインデックスを使用して同じテーブルで条件付きスキャンを実行できるようになりました。
たとえば、実行プラン内のステートメント:
UPDATE test_table SET `status` = 1 WHERE `trans_id` = '38' AND `status` = 0 ;
MySQL は、条件 trans_id = ‘38’ に基づいて uniq_trans_id# を使用します。
## インデックスはリーフ ノードに保存されている ID 値を検索します。同時に、条件status = 0 に従って、
idx_status インデックスを使用して、リーフ ノードに保存された ID 値; その後、2 つのグループ ID 値が交差され、最終的に交差 ID がテーブルに返されます、つまり、リーフ ノードに保存された行データが PRIMARY インデックスを通じて検出されます。
多くの人がここで疑問を抱くかもしれません。
uniq_trans_id はすでに一意のインデックスです。このインデックスを通じて見つかるのは最大でも 1 つのデータだけです。では、なぜ MySQL オプティマイザーは 2 つのインデックスを使用するのでしょうか。 2 つのインデックスの共通部分を検索し、クエリのためにテーブルに戻ります。これにより、別の
idx_status
最初の例では、uniq_trans_id インデックスのみを使用します。
##クエリ条件 trans_id = ‘38’ によると、 use
uniq_trans_id- インデックスはリーフ ノードに保存されている ID 値を検索します;
PRIMARY インデックスを使用して、見つかった ID 値を通じてリーフ ノードに保存されている行データを検索します;
次に、見つかった行データを - status = 0
条件でフィルター処理します。
2 番目のタイプはインデックスのマージを使用します。
Using intersect(uniq_trans_id,idx_status)
:
trans_id によると= ‘38’
クエリ条件、
- インデックスを使用して、リーフ ノードに保存されている ID 値を検索します;
-
idx_statusstatus によると = 0
クエリ条件。 インデックスを使用して、リーフ ノードに保存されている ID 値を検索します。 1/2 で見つかった ID 値の共通部分を取得し、PRIMARY インデックスを使用してリーフ ノードに保存されている行データを見つけます
上記の 2 つのケースの主な違いは、1 つ目の方法では最初にインデックスを通じてデータを検索し、次に他のクエリ条件を使用してフィルタリングすること、2 つ目の方法では最初に ID 値の共通部分を取得することです。 2 つのインデックスを通じて見つかりました。交差部分の後に ID 値がまだある場合は、テーブルに戻ってデータを取得します。
オプティマイザが 2 番目のケースの実行コストが最初のケースの実行コストより小さいと判断した場合、インデックスのマージが発生します。 (運用環境のフロー テーブルには status = 0
のデータがほとんどありません。これが、オプティマイザが 2 番目のケースを考慮する理由の 1 つです)。
index_merge
index_merge を使用した後にデッドロックが発生する理由 上記は、2 つの更新トランザクションをロックするプロセスを簡単に示しています。図では、
idx_status
たとえば、次のようなタイミングでデッドロックが発生します。
-
のみを渡します。 、コード レベルでステータスが 0 であるかどうかを判断します。# クエリ条件から、データをクエリするために
trans_id -
を使用するように強制します。 index;Use
force Index(uniq_trans_id)クエリ ステートメントで
uniq_trans_id - ここで、クエリ条件の直後に id フィールドを使用し、主キーを介して更新します。
- idx_status
- インデックスを MySQL レベルから削除するか、これら 2 つの列を含む結合インデックスを作成します。
index merge##MySQL オプティマイザーの
最適化をオフにします。
以上がMySQL 最適化インデックスのマージによって発生するデッドロックを解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

WebアプリケーションにおけるMySQLの主な役割は、データを保存および管理することです。 1.MYSQLは、ユーザー情報、製品カタログ、トランザクションレコード、その他のデータを効率的に処理します。 2。SQLクエリを介して、開発者はデータベースから情報を抽出して動的なコンテンツを生成できます。 3.MYSQLは、クライアントサーバーモデルに基づいて機能し、許容可能なクエリ速度を確保します。

MySQLデータベースを構築する手順には次のものがあります。1。データベースとテーブルの作成、2。データの挿入、および3。クエリを実行します。まず、createdAtabaseおよびcreateTableステートメントを使用してデータベースとテーブルを作成し、InsertINTOステートメントを使用してデータを挿入し、最後にSelectステートメントを使用してデータを照会します。

MySQLは、使いやすく強力であるため、初心者に適しています。 1.MYSQLはリレーショナルデータベースであり、CRUD操作にSQLを使用します。 2。インストールは簡単で、ルートユーザーのパスワードを構成する必要があります。 3.挿入、更新、削除、および選択してデータ操作を実行します。 4. Orderby、Where and Joinは複雑なクエリに使用できます。 5.デバッグでは、構文をチェックし、説明を使用してクエリを分析する必要があります。 6.最適化の提案には、インデックスの使用、適切なデータ型の選択、優れたプログラミング習慣が含まれます。

MySQLは初心者に適しています。1)インストールと構成、2)リッチラーニングリソース、3)直感的なSQL構文、4)強力なツールサポート。それにもかかわらず、初心者はデータベースの設計、クエリの最適化、セキュリティ管理、データのバックアップなどの課題を克服する必要があります。

はい、sqlisaprogramginglanguagespecializedfordatamanamanagement.1)それはdeclarative、focusingonwhattoachieveratherthanhow.2)

酸性属性には、原子性、一貫性、分離、耐久性が含まれ、データベース設計の基礎です。 1.原子性は、トランザクションが完全に成功するか、完全に失敗することを保証します。 2.一貫性により、データベースがトランザクションの前後に一貫性を保証します。 3.分離により、トランザクションが互いに干渉しないようにします。 4.永続性により、トランザクションの提出後にデータが永久に保存されることが保証されます。

MySQLは、データベース管理システム(DBMS)であるだけでなく、プログラミング言語にも密接に関連しています。 1)DBMSとして、MySQLはデータを保存、整理、取得するために使用され、インデックスを最適化するとクエリのパフォーマンスが向上する可能性があります。 2)SQLとPythonに埋め込まれたプログラミング言語とSQLalchemyなどのORMツールを使用すると、操作を簡素化できます。 3)パフォーマンスの最適化には、インデックス、クエリ、キャッシュ、ライブラリ、テーブル分割、およびトランザクション管理が含まれます。

MySQLはSQLコマンドを使用してデータを管理します。 1.基本コマンドには、select、挿入、更新、削除が含まれます。 2。高度な使用には、参加、サブクエリ、および集計関数が含まれます。 3.一般的なエラーには、構文、ロジック、パフォーマンスの問題が含まれます。 4。最適化のヒントには、インデックスの使用、Select*の回避、制限の使用が含まれます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

ドリームウィーバー CS6
ビジュアル Web 開発ツール
