成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實戰分享 | 你知道這個死鎖是怎么產生的嗎?

數據庫 MySQL
鎖沖突中,有一類很經典的場景經常會拿出來討論:死鎖。最近剛好也遇到了一個典型的死鎖案例,本文會基于這個案例,做一次詳細的分析與拆解。

Part1 背景

鎖作為 MySQL 知識體系的主要部分之一,是每個 DBA 都需要學習和掌握的知識。鎖保證了數據庫在并發的場景下數據的一致性,同時鎖沖突也是影響數據庫性能的因素之一。而鎖沖突中,有一類很經典的場景經常會拿出來討論:死鎖。最近剛好也遇到了一個典型的死鎖案例,本文會基于這個案例,做一次詳細的分析與拆解。

Part2 問題

由于innodb engine status會記錄最近一次死鎖的細節信息,因此案例現場的信息是可以完整拿到的。用戶針對這個死鎖的問題,提出了疑問:數據更新的并不是同一行,使用的也是不同的索引,為什么會發生死鎖?(以下細節信息均已脫敏)

死鎖的兩個語句如下: 

  1. UPDATE tbl_deadlock SET col1 = 1, col2 = 1update_time = 1603685523 WHERE (id1 = 6247476) AND (id2 = 74354 
  2. UPDATE tbl_deadlock SET col1 = 1, col2 = 1update_time = 1603685523 WHERE (id1 = 6249219) AND (id2 = 74354

精簡之后的 MySQL 死鎖信息如下: 

  1. =====================================  
  2. 2020-10-26 12:14:30 7fd2642f5700 INNODB MONITOR OUTPUT  
  3. =====================================  
  4. ...省略...  
  5. ------------------------  
  6. LATEST DETECTED DEADLOCK  
  7. ------------------------  
  8. 2020-10-26 12:12:03 7fd2846ed700  
  9. *** (1) TRANSACTION:  
  10. TRANSACTION 1795660514, ACTIVE 0 sec starting index read  
  11. mysql tables in use 3, locked 3  
  12. LOCK WAIT 4 lock struct(s), heap size 1184, 3 row lock(s)  
  13. MySQL thread id 21829887, OS thread handle 0x7fd28d14a700, query id 178279444 172.21.0.15 username updating  
  14. UPDATE tbl_deadlock SET col1= 1, col2 = 1update_time = 1603685523 WHERE (id1 = 6247476) AND (id2 = 74354 
  15. *** (1) WAITING FOR THIS LOCK TO BE GRANTED:  
  16. RECORD LOCKS space id 8575 page no 286947 n bits 1048 index `id2` of table `deadlock`.`tbl_deadlock` trx id 1795660514 lock_mode X waiting  
  17. Record lock, heap no 429 PHYSICAL RECORD: n_fields 2; compact format; info bits 0  
  18.  0: len 4; hex 00012272; asc   "r;;  
  19.  1: len 4; hex 00721f45; asc  r E;;  
  20. *** (2) TRANSACTION:  
  21. TRANSACTION 1795660513, ACTIVE 0 sec fetching rows  
  22. mysql tables in use 3, locked 3  
  23. 20 lock struct(s), heap size 2936, 40 row lock(s)  
  24. MySQL thread id 21905203, OS thread handle 0x7fd2846ed700, query id 178279443 172.21.0.15 username updating 
  25. UPDATE tbl_deadlock SET col1 = 1, col2 = 1update_time = 1603685523 WHERE (id1 = 6249219) AND (id2 = 74354 
  26. *** (2) HOLDS THE LOCK(S):  
  27. RECORD LOCKS space id 8575 page no 286947 n bits 1048 index `id2` of table `deadlock`.`tbl_deadlock` trx id 1795660513 lock_mode X  
  28. Record lock, heap no 429 PHYSICAL RECORD: n_fields 2; compact format; info bits 0  
  29.  0: len 4; hex 00012272; asc   "r;;  
  30.  1: len 4; hex 00721f45; asc  r E;;  
  31. Record lock, heap no 430 PHYSICAL RECORD: n_fields 2; compact format; info bits 0  
  32.  0: len 4; hex 00012272; asc   "r;;  
  33.  1: len 4; hex 00721fe3; asc  r  ;;   
  34. Record lock, heap no 431 PHYSICAL RECORD: n_fields 2; compact format; info bits 0  
  35.  0: len 4; hex 00012272; asc   "r;;  
  36.  1: len 4; hex 0072218f; asc  r! ;; 
  37. ...省略很多 Record lock...  
  38. *** (2) WAITING FOR THIS LOCK TO BE GRANTED:  
  39. RECORD LOCKS space id 8575 page no 344554 n bits 120 index `PRIMARY` of table `deadlock`.`tbl_deadlock` trx id 1795660513 lock_mode X locks rec but not gap waiting 
  40. Record lock, heap no 9 PHYSICAL RECORD: n_fields 44; compact format; info bits 0  
  41.  0: len 4; hex 00722663; asc  r&c;;  
  42. ...省略無關的兩行...  
  43.  3: len 4; hex 005f5434; asc  _T4;;  
  44.  4: len 4; hex 00012272; asc   "r;;  
  45.  ...省略很多行...  
  46. *** WE ROLL BACK TRANSACTION (1)  
  47. ...省略... 

Part3 原因分析

首先簡單了解一下死鎖的幾個要素:

1. 互斥條件:一個資源每次只能被一個進程占用。

  •  MySQL 的鎖機制天然具備這個條件。

2. 請求與保持條件:資源請求被阻塞時,已持有的資源不會被釋放。

  •  MySQL 不觸發死鎖回滾,且未進入 lockwait_timeout 的時候,具備這個條件。

3. 不剝奪條件:已獲得的資源,在末使用完之前,不能強行剝奪。

  •  MySQL 的鎖機制天然具備這個條件。

4. 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系,通常會表現為有向環。

由于 MySQL 的鎖機制的原因,只需要判斷出兩個 SQL 語句的鎖存在循環等待,那么死鎖的條件就會成立了。

接下來對 MySQL 記錄的死鎖信息進行詳細的分析,首先觀察死鎖的事務詳情這一部分信息: 

  1. LOCK WAIT 4 lock struct(s), heap size 1184, 3 row lock(s)。......  
  2. 20 lock struct(s), heap size 2936, 40 row lock(s) 

可以很明顯可以發現,這兩個語句涉及到的數據行還是比較多的,用戶的疑問:數據更新的并不是同一行,其實是個誤解。那么理論上,“循環等待:互相持有對方需要的鎖”,這種典型的死鎖場景是可能會存在的。

接下來,重點放在更細節的信息上: 

  1. *** (1) WAITING FOR THIS LOCK TO BE GRANTED:  
  2. RECORD LOCKS space id 8575 page no 286947 n bits 1048 index `id2` of table `deadlock`.`tbl_deadlock` trx id 1795660514 lock_mode X waiting  
  3. Record lock, heap no 429 PHYSICAL RECORD: n_fields 2; compact format; info bits 0  
  4.  0: len 4; hex 00012272; asc   "r;;  
  5.  1: len 4; hex 00721f45; asc  r E;;  
  6. ......  
  7. *** (2) WAITING FOR THIS LOCK TO BE GRANTED:  
  8. RECORD LOCKS space id 8575 page no 344554 n bits 120 index `PRIMARY` of table `deadlock`.`tbl_deadlock` trx id 1795660513 lock_mode X locks rec but not gap waiting 
  9. Record lock, heap no 9 PHYSICAL RECORD: n_fields 44; compact format; info bits 0  
  10.  0: len 4; hex 00722663; asc  r&c;;  
  11. ...省略無關的兩行...  
  12.  3: len 4; hex 005f5434; asc  _T4;;  
  13.  4: len 4; hex 00012272; asc   "r;;  
  14.  ...省略很多行... 

用戶提出的疑問:使用的也是不同的索引,為什么會發送死鎖?實際上二級索引上的記錄鎖,最終也會加到主鍵上。

這個很好理解,如果二級索引上,通過搜索商品表的商品名稱索引(二級索引)搜索“iphone12”,并給這一行數據加上了鎖,鎖住了“iphone12”這個商品的詳情數據行,如果別的事務可以通過搜索主鍵來修改這一行數據,明顯是不行的。

因此本案例中,雖然死鎖信息中記錄的索引名稱不一樣,但是鎖爭用的條件是成立的,即:trx1 通過二級索引向主鍵上執行了加鎖操作,而 trx2 在其他的二級索引上拿到了鎖,但是主鍵鎖拿不到,因此進入了等待狀態。所以只需要定位到具體鎖的數據,找到循環等待的邏輯關系,就可以完成整個案例分析了。

參考上文引用的信息,具體發生死鎖的行的信息都記錄在類似0: len 4; hex 00722663; asc r&c;;的信息中。

trx1 記錄的鎖等待信息是二級索引 id2,因為 id2 是一個單行索引,因此只會有 0 和 1 兩行信息,0 代表的就是具體的行 id2,1 即為主鍵。通過 16 進制轉換工具,轉成 10 進制,可以發現對應的數據如下:

pk = 7479109 and id2 = 74354

那么再看看 trx2 記錄的信息,鎖等待方面,記錄的信息是主鍵,所以這個地方會有完整的表數據,過濾掉無效的數據之后,留下了三行:0 為主鍵,3 為 id1,4 為 id2。轉換進制之后,對應的數據如下:

pk = 7480931 and id1 = 6247476 and id2 = 74354

可以看到,trx2 等待的鎖,id1 和 id2 剛好滿足 trx1 的查詢條件。而 trx2 持有的鎖信息中,第一個剛好就是 trx1 等待的:

trx2 持有的鎖

那么關于這個死鎖案例的具體場景,就可以用下有向環的圖例進行說明:

死鎖圖例

至此為止,這個死鎖的案例分析就完成了,從最初的死鎖成立條件分析,到解讀具體的鎖內容,最終完成了死鎖的有向環圖例。

實際上,自己觀察一下這個死鎖的有向環圖例,會發現這兩個語句用到了兩個單列索引,那么進一步思考的話,如果這兩個列建成了聯合索引,這個死鎖的案例是不是就可能不會發生了?

Part4 總結

對于死鎖的問題,只需要根據四個條件,一步一步過濾與分析,通過解讀死鎖現場的詳細內容,就可以準確的還原整個死鎖的發生原因以及涉及到的數據行。當然,在實際的業務環境中,可能還會有更復雜和隱蔽的死鎖案例,但是不論多么隱蔽和復雜,死鎖分析的思路和步驟都是相似的。

關于專欄

《騰訊云數據庫專家服務》是由騰訊云數據庫技術服務團隊維護的社區專欄,涵蓋了各類數據庫的實際案例,最佳實踐,版本特性等內容。

 

責任編輯:龐桂玉 來源: 楊建榮的學習筆記
相關推薦

2023-01-09 08:00:41

JavaScript閉包

2013-02-27 10:27:44

GitHub

2024-12-04 08:40:19

2024-02-19 00:00:00

Docker輕量級容器

2024-11-26 00:45:29

free區域字段

2023-02-08 07:04:20

死鎖面試官單元

2010-11-23 10:21:53

跳槽

2024-12-11 08:19:34

2024-04-08 00:00:00

asyncawaiPromise

2022-02-10 09:04:50

架構

2022-09-28 18:16:34

JavaJDK

2022-11-16 08:43:30

Node.js模塊

2014-08-22 10:14:27

2017-06-23 15:45:09

AndroidThread

2024-06-20 08:06:30

2015-09-11 15:56:52

內核構建Linux

2019-05-20 13:45:15

MySQL新特性數據庫

2023-12-20 08:23:53

NIO組件非阻塞

2015-12-01 13:33:51

UnikernelLinux運維

2021-11-12 05:59:23

容災備份5G
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品一区二区三区中文字幕 | 免费一区 | 久久精品视频免费看 | 午夜精品久久久久久 | 欧美日韩一区二区视频在线观看 | 日韩欧美精品一区 | 国产亚洲精品久久午夜玫瑰园 | 日本中文字幕在线观看 | www.性色| 96国产精品久久久久aⅴ四区 | 高清av一区 | 国产精品一区二区三区在线 | 日本久久一区二区三区 | 久久成人午夜 | 日韩在线视频一区 | 正在播放国产精品 | 天天拍天天操 | 欧美一级视频在线观看 | 国产精品久久久久免费 | 欧美精品在线播放 | 91一区二区在线观看 | 亚洲精品乱码久久久久久黑人 | 色婷婷综合网站 | 午夜久久久久 | av av在线| 在线播放国产一区二区三区 | 国产露脸国语对白在线 | 国产高清在线 | 黄色在线免费观看 | 久久久久网站 | 久久国产综合 | 久久久美女 | 亚洲最大av网站 | 成人免费影院 | 日本中文在线 | 国际精品鲁一鲁一区二区小说 | 综合色在线 | 欧美aⅴ | 一区二区三区av夏目彩春 | 成人乱人乱一区二区三区软件 | 日本a v在线播放 |