巧用MySQL InnoDB引擎锁机制解决死锁问题_MySQL
案例如下:
在使用Show innodb status检查引擎状态时,发现了死锁问题:
*** (1) TRANSACTION:
TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OS thread id 278546 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 320
MySQL thread id 83, query id 162348740 dcnet03 dcnet Searching rows for update
update TSK_TASK set STATUS_ID=1064,UPDATE_TIME=now () where STATUS_ID=1061 and MON_TIME*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `dcnet_db/TSK_TASK` trx id 0 677833455 lock_mode X locks rec but not gap waiting
Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 75706c6f6164666972652e636f6d2f6 8616e642e706870; asc xxx.com/;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
*** (2) TRANSACTION:
TRANSACTION 0 677833454, ACTIVE 0 sec, process no 11397, OS thread id 344086 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
3 lock struct(s), heap size 320, undo log entries 1
MySQL thread id 84, query id 162348739 dcnet03 dcnet Updating
update TSK_TASK set STATUS_ID=1067,UPDATE_TIME=now () where ID in (9921180)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `dcnet_db/TSK_TASK` trx id 0 677833454 lock_mode X locks rec but not gap
Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 75706c6f6164666972652e636f6d2f6 8616e642e706870; asc uploadfire.com/hand.php;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 843102 n bits 600 index `KEY_TSKTASK_MONTIME2` of table `dcnet_db/TSK_TASK` trx id 0 677833454 lock_mode X locks rec but not gap waiting
Record lock, heap no 395 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 8; hex 8000000000000425; asc %;; 1: len 8; hex 800012412c66d29c; asc A,f ;; 2: len 8; hex 800000000097629c; asc b ;;
*** WE ROLL BACK TRANSACTION (1)
此死锁问题涉及TSK_TASK表,该表用于保存系统监测任务,以下是相关字段及索引:
ID:主键;
MON_TIME:监测时间;
STATUS_ID:任务状态;
索引:KEY_TSKTASK_MONTIME2 (STATUS_ID, MON_TIME)。
分析,涉及的两条语句应该不会涉及相同的TSK_TASK记录,那为什么会造成死锁呢?
查询MySQL官网文档,发现这跟MySQL的索引机制有关。MySQL的InnoDB引擎是行级锁,我原来的理解是直接对记录进行锁定,实际上并不是这样的。
要点如下:
不是对记录进行锁定,而是对索引进行锁定;
在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking;
如语句UPDATE TSK_TASK SET UPDATE_TIME = NOW() WHERE ID > 10000会锁定所有主键大于等于1000的所有记录,在该语句完成之前,你就不能对主键等于10000的记录进行操作;
当非簇索引(non-cluster index)记录被锁定时,相关的簇索引(cluster index)记录也需要被锁定才能完成相应的操作。
再分析一下发生问题的两条SQL语句,就不难找到问题所在了:
当“update TSK_TASK set STATUS_ID=1064,UPDATE_TIME=now () where STATUS_ID=1061 and MON_TIME
假设“update TSK_TASK set STATUS_ID=1067,UPDATE_TIME=now () where ID in (9921180)”几乎同时执行时,本语句首先锁定簇索引(主键),由于需要更新STATUS_ID的值,所以还需要锁定KEY_TSKTASK_MONTIME2的某些索引记录。
这样第一条语句锁定了KEY_TSKTASK_MONTIME2的记录,等待主键索引,而第二条语句则锁定了主键索引记录,而等待KEY_TSKTASK_MONTIME2的记录,在此情况下,死锁就产生了。
笔者通过拆分第一条语句解决死锁问题:
先查出符合条件的ID:select ID from TSK_TASK where STATUS_ID=1061 and MON_TIME
至此,死锁问题彻底解决

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

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

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

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック








![Teams でスペルチェックが機能しない [修正済み]](https://img.php.cn/upload/article/000/887/227/170968741326618.jpg?x-oss-process=image/resize,m_fill,h_207,w_330)
Teams でスペルチェックが機能しなくなる場合があることに気づき始めました。スペル チェックは効果的なコミュニケーションに不可欠なツールであり、これに対する攻撃はワークフローに重大な混乱を引き起こす可能性があります。この記事では、スペル チェックが期待どおりに機能しない一般的な理由と、スペル チェックを以前の状態に戻す方法について説明します。そのため、Teams でスペル チェックが機能しない場合は、この記事で説明されている解決策に従ってください。 Microsoft のスペルチェックが機能しないのはなぜですか? Microsoft のスペル チェックが正しく機能しない理由はいくつか考えられます。これらの理由には、互換性のない言語設定、スペルチェック機能の無効化、MSTeam または MSOffice のインストールの破損などが含まれます。また、古い MSTeam と MSOf

実行されるプログラムをプロセスと呼びます。プロセスは、現在のオペレーティング システム上で実行されているアプリケーション、またはオペレーティング システムに関連するアプリケーションです。アプリケーションがオペレーティング システムに関連付けられている場合、アプリケーションは最初にそれ自体を実行するプロセスを作成します。他のアプリケーションは実行のためにオペレーティング システム サービスに依存します。ほとんどのアプリケーションは、オペレーティング システム サービスと、オペレーティング システム、ソフトウェア、およびハードウェアを維持するバックグラウンド アプリケーションです。 Python では、アプリケーションが開いているかどうかを確認するさまざまな方法があります。一つずつ詳しく見ていきましょう。 psutil.process_iter() 関数の使用 psutil は、実行中のプロセスとシステム使用率に関する情報を取得するインターフェイスをユーザーに提供する Python のモジュールです。

反復可能オブジェクトは、ループまたは反復可能関数を使用してすべての要素を反復できるオブジェクトです。リスト、文字列、辞書、タプルなどはすべて反復可能オブジェクトと呼ばれます。 Python 言語では、オブジェクトが反復可能かどうかを確認するさまざまな方法があります。一つずつ見ていきましょう。ループの使用 Python には 2 つのループ手法があります。1 つは「for」ループを使用し、もう 1 つは「while」ループを使用します。これら 2 つのループのいずれかを使用して、特定のオブジェクトが反復可能かどうかを確認できます。例 この例では、for ループを使用してオブジェクトを反復し、反復されているかどうかを確認します。以下はコードです。 l=["リンゴ",22,"オレンジ

Windows 11 で SSD の健康状態を確認するにはどうすればよいですか? SSD は読み取り、書き込み、アクセス速度が速いため、急速に HDD に取って代わりつつありますが、たとえ信頼性が高くても、Windows 11 で SSD の状態をチェックする必要があります。操作方法は?このチュートリアルでは、エディターがその方法を共有します。方法 1: WMIC1 を使用し、Win + R キーの組み合わせを使用して「wmic」と入力し、[OK] を押すかクリックします。 Enter2. 次に、次のコマンドを入力または貼り付けて、SSD の健全性ステータスを確認します: diskdrivegetstatus 「ステータス: OK」メッセージが表示された場合、SSD ドライブは正常に動作しています。

List インターフェイスの contains() メソッドを使用して、リストにオブジェクトが存在するかどうかを確認できます。 contains() メソッド booleancontains(Objecto) このリストに指定された要素が含まれる場合、true を返します。より正式には、このリストに (o==null?e==null:o.equals(e)) のような要素 e が少なくとも 1 つ含まれる場合にのみ true を返します。パラメータ c - このリスト内の存在がテストされる要素。戻り値 このリストに指定された要素が含まれている場合は true を返します。 ClassCastException をスローします - 指定された要素の型がこのリストと互換性がない場合 (オプション)。 NullP

最近の携帯電話はAppleの携帯電話が最も多く選ばれていますが、ネット上ではAppleの携帯電話のロック付きとロック解除の違いについて議論しているのをよく見かけ、どちらを買うべきかでもつれています。今日は、Chen Siqi がロックされた iPhone とロックされていない iPhone の違いを共有し、問題の解決に役立ちます。実は両者に見た目や機能に大きな違いはなく、鍵となるのは価格と用途です。ロック版とロック解除版とは何ですか? ロック制限なしの iPhone とは、通信事業者の制限を受けず、どの通信事業者の SIM カードも正常に使用できることを意味します。ロック版とは、ネットワークロックがかかっており、指定事業者が提供するSIMカードのみを使用でき、他のSIMカードは使用できないことを意味します。実際、ロックを解除した Apple 携帯電話はモバイルを使用できます。

Golang で文字列が特定の文字で始まるかどうかを確認するにはどうすればよいですか? Golang でプログラミングする場合、文字列が特定の文字で始まるかどうかを確認する必要がある状況によく遭遇します。この要件を満たすために、Golang の strings パッケージによって提供される関数を使用してこれを実現できます。次に、Golangを使って文字列が特定の文字で始まるかどうかを確認する方法を、具体的なコード例とともに詳しく紹介します。 Golang では、strings パッケージの HasPrefix を使用できます。

さまざまな企業の適格性基準を知るには、以下の表を参照してください。CGPA の中国語訳は次のとおりです。 GPA 8 つ以上の適格企業 Google、Microsoft、Amazon、Dell、Intel、Wipro 7 つ以上のチュートリアル ポイント、アクセンチュア、 Infosys 、 Emicon、6rtCamp 以上の Rellins、Cybertech、Skybags、Killer、Raymond 以上 5Patronics、Shoes、NoBrokers Java プログラムに入って、tpp 学生の面接適格性を確認しましょう。方法 1: ifelseif 条件を使用する 通常、複数の条件をチェックする必要がある場合に使用します。
