首頁 資料庫 mysql教程 巧用MySQL InnoDB引擎锁机制解决死锁问题_MySQL

巧用MySQL InnoDB引擎锁机制解决死锁问题_MySQL

Jun 01, 2016 pm 02:00 PM
檢查

案例如下:

在使用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

至此,死锁问题彻底解决

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在Python中檢查應用程式是否開啟? 如何在Python中檢查應用程式是否開啟? Aug 26, 2023 pm 06:49 PM

正在執行的程序稱為進程。進程可以是當前作業系統上運行的應用程序,也可以是與作業系統相關的應用程式。如果一個應用程式與作業系統相關,它首先會創建一個進程來執行自己。其他應用程式依賴作業系統服務來執行。大多數應用程式是作業系統服務以及維護作業系統、軟體和硬體的後台應用程式。在python中,我們有不同的方法來檢查應用程式是否開啟。讓我們一一詳細了解它們。使用psutil.process_iter()函數psutil是python中的一個模組,它為使用者提供一個介面來檢索正在運行的進程和系統利用率的信息

拼字檢查在團隊中不起作用[修復] 拼字檢查在團隊中不起作用[修復] Mar 06, 2024 am 09:10 AM

我們已經開始注意到,有時拼字檢查停止工作的團隊。拼字檢查是有效溝通的基本工具,任何對它的打擊都會對工作流程造成相當大的破壞。在本文中,我們將探討拼字檢查可能無法如預期運作的常見原因,以及如何將其恢復到先前的狀態。所以,如果拼字檢查在團隊中不起作用,請遵循本文中提到的解決方案。為什麼Microsoft拼字檢查不起作用? Microsoft拼字檢查無法正常運作可能有多種原因。這些原因包括不相容的語言設定、拼字檢查功能被停用、MSTeam或MSOffice安裝損壞等。另外,過時的MSTeams和MSOf

如何在Python中檢查一個物件是否可迭代? 如何在Python中檢查一個物件是否可迭代? Aug 25, 2023 pm 10:05 PM

可迭代物件是可以使用循環或可迭代函數迭代其所有元素的物件。列表、字串、字典、元組等都稱為可迭代物件。在Python語言中,有多種方法可以檢查物件是否可迭代。讓我們一一看看。使用循環在Python中,我們有兩種循環技術,一種是使用「for」循環,另一種是使用「while」循環。使用這兩個循環中的任何一個,我們可以檢查給定的物件是否可迭代。範例在這個例子中,我們將嘗試使用“for”循環迭代一個物件並檢查它是否被迭代。以下是代碼。 l=["apple",22,"orang

Windows11中如何檢查 SSD 運作狀況? Win11上檢查 SSD 運作狀況的方法 Windows11中如何檢查 SSD 運作狀況? Win11上檢查 SSD 運作狀況的方法 Feb 14, 2024 pm 08:21 PM

Windows11中如何檢查SSD運作狀況?對於其快速的讀取、寫入和存取速度,SSD正在迅速取代HDD,但即使它們更可靠,您仍然需要在Windows11中檢查SSD的運作狀況。怎麼去操作呢?本篇教學小編就來為大家分享一下方法吧。方法一:使用WMIC1、使用按鍵組合Win+R,鍵入wmic,然後按或按一下「確定」。 Enter2、現在,鍵入或貼上以下命令以檢查SSD運行狀況:diskdrivegetstatus如果您收到「狀態:正常」訊息,則您的SSD驅動器運行正

Java程式用於檢查TPP學生是否有資格參加面試 Java程式用於檢查TPP學生是否有資格參加面試 Sep 06, 2023 pm 10:33 PM

請考慮下表了解不同公司的資格標準-CGPA的中文翻譯為:績點平均成績符合條件的公司大於或等於8谷歌、微軟、亞馬遜、戴爾、英特爾、Wipro大於或等於7教程點、accenture、Infosys 、Emicon、Rellins大於或等於6rtCamp、Cyber​​tech、Skybags、Killer、Raymond大於或等於5Patronics、鞋子、NoBrokers讓我們進入java程式來檢查tpp學生參加面試的資格。方法1:使用ifelseif條件通常,當我們必須檢查多個條件時,我們會使用

如何在Java中檢查ArrayList是否包含某個元素? 如何在Java中檢查ArrayList是否包含某個元素? Sep 03, 2023 pm 04:09 PM

您可以利用List介面的contains()方法來檢查清單中是否存在物件。 contains()方法booleancontains(Objecto)如果此清單包含指定的元素,則傳回true。更正式地說,如果且僅當此列表包含至少一個元素e,使得(o==null?e==null:o.equals(e)),則傳回true。參數c-要測試其在此列表中是否存在的元素。傳回值如果此清單包含指定的元素,則傳回true。拋出ClassCastException-如果指定元素的類型與此清單不相容(可選)。 NullP

Golang中如何檢查字串是否以特定字元開頭? Golang中如何檢查字串是否以特定字元開頭? Mar 12, 2024 pm 09:42 PM

Golang中如何檢查字串是否以特定字元開頭?在使用Golang程式設計時,經常會遇到需要檢查一個字串是否以特定字元開頭的情況。針對這項需求,我們可以使用Golang中的strings套件所提供的函數來實現。接下來將詳細介紹如何使用Golang檢查字串是否以特定字元開頭,並附上具體的程式碼範例。在Golang中,我們可以使用strings套件中的HasPrefix

蘋果有鎖和無鎖的差別是什麼 詳細介紹:iphone有鎖和無鎖的差別對比 蘋果有鎖和無鎖的差別是什麼 詳細介紹:iphone有鎖和無鎖的差別對比 Mar 28, 2024 pm 03:10 PM

蘋果手機是最近大家選擇最廣泛的一款手機,但我們常常在網路上看到大家在討論蘋果手機有鎖與無鎖的差別,會糾結於要購買哪一種。今天陳斯琪就為大家普及一下iphone有鎖和無鎖的差別,為大家排憂解難。其實二者在外觀、功能上並沒有太大差別,關鍵就在價格以及使用上的一些問題。什麼是有鎖版與無鎖版沒有鎖版限制的蘋果手機指不受業者的限制,任何一家業者的SIM卡都可以正常使用。有鎖版是指加了網路鎖,只能使用指定的電信業者提供的SIM卡,不能使用其他的。其實沒有鎖版的蘋果手機就像我們的全網通手機一樣可以使用移動、

See all articles