死鎖案例三
1、環境說明
MySQL5.6.33,隔離級別是RR。表結構及資料:
create table t2 (id int primary key auto_increment ,c1 int ,c2 int ,key (c1)) engine=innodb ; insert into t2 values(24,3,4),(25,3,4),(26,3,4),(30,5,8);
2、測試用例
session1 | session2 |
begin; | begin; |
select *from t2 where id=30 for update; |
|
|
update t2 set c2=8 where c1=5; |
delete from t2 where id=30; |
|
|
deadlock |
3、死鎖日誌
LATEST DETECTED DEADLOCK ------------------------ 2018-07-14 06:45:32 a3522b90 *** (1) TRANSACTION: TRANSACTION 8976, ACTIVE 104 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 3 lock struct(s), heap size 320, 2 row lock(s) MySQL thread id 2, OS thread handle 0xa34f1b90, query id 28 localhost root Searching rows for update update t2 set c2=8 where c1=5 *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 19 page no 3 n bits 72 index `PRIMARY` of table `yzs`.`t2` trx id 8976 lock_mode X locks rec but not gap waiting Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 0: len 4; hex 8000001e; asc ;; 1: len 6; hex 00000000230f; asc # ;; 2: len 7; hex 0d000001410943; asc A C;; 3: len 4; hex 80000005; asc ;; 4: len 4; hex 80000008; asc ;; *** (2) TRANSACTION: TRANSACTION 8975, ACTIVE 251 sec updating or deleting mysql tables in use 1, locked 1 3 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1 MySQL thread id 1, OS thread handle 0xa3522b90, query id 29 localhost root updating delete from t2 where id=30 *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 19 page no 3 n bits 72 index `PRIMARY` of table `yzs`.`t2` trx id 8975 lock_mode X locks rec but not gap Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 32 0: len 4; hex 8000001e; asc ;; 1: len 6; hex 00000000230f; asc # ;; 2: len 7; hex 0d000001410943; asc A C;; 3: len 4; hex 80000005; asc ;; 4: len 4; hex 80000008; asc ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 19 page no 4 n bits 72 index `c1` of table `yzs`.`t2` trx id 8975 lock_mode X locks rec but not gap waiting Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 80000005; asc ;; 1: len 4; hex 8000001e; asc ;;
4、分析死鎖日誌
TRANSACTION 8975:
執行完delete from t2 where id=30後,擁有的鎖是聚集索引記錄(30,5,8)的X型別的記錄鎖lock_mode X locks rec but not gap,申請等待的鎖是二級索引記錄(5,30)的X型別的記錄鎖lock_mode X locks rec but not gap waiting。
TRANSACTION 8976:
執行完update t2 set c2=8 where c1=5語句時,顯示申請等待的鎖是聚集索引記錄(30,5,8)的X型別的記錄鎖lock_mode X locks rec but not gap waiting。
只從死鎖日誌上看不出造成死鎖的原因。未提交的事務中,有已執行過但未提交的SQL語句鎖造成擁有的鎖沒有顯示出來。
5、加鎖原理
update加鎖原理見之前部落格:
https://blog.csdn.net/yanzongshuai/article/details/80872095
https://blog.csdn.net/yanzongshuai/article/details/80870957
https://blog.csdn.net/yanzongshuai/article/details/80870949
delete加鎖原理見之前部落格:
https://blog.csdn.net/yanzongshuai/article/details/79243727
https://blog.csdn.net/yanzongshuai/article/details/79222041
6、解析
session1執行完select *from t2 where id=30 for update;後,搜尋到主鍵30,即對(30,5,8)加上X型別的記錄鎖
session2執行完update t2 set c2=8 where c1=5;後,在search階段先搜尋二級索引,搜尋到(5,30),對此記錄加X型別的next-key鎖 lock_mode X;然後搜尋聚集索引記錄30,需要對聚集索引記錄(30,5,8)加X型別記錄鎖,因為和session1互斥,所以鎖等待。
session1再次執行delete from t2 where id=30;,對記錄鎖聚集索引記錄(30,5,8)申請X型別的記錄鎖,因為事務前面已申請過,所以不再申請;再對二級索引記錄(5,30)加X型別的記錄鎖,和session2互斥。
這樣彼此發生鎖等待,造成死鎖。
7、解決方法
楊奇龍兄建議可以將session2的update t2 set c2=8 where c1=5改成按主鍵更新 update tx set c2=x where id=30。這樣加鎖順序都是先聚集再二級索引,避免主鍵和二級索引加鎖順序交叉造成死鎖。
8、參考
http://blog.itpub.net/22664653/viewspace-2152274/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2157867/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 死鎖案例分析
- 死鎖案例二
- GreatSQL 死鎖案例分析SQL
- 【MySQL】死鎖案例之六MySql
- 【MySQL】死鎖案例之七MySql
- 【MySQL】死鎖案例之八MySql
- 故障分析 | MySQL死鎖案例分析MySql
- MySQL:Innodb 一個死鎖案例MySql
- MySQL批量更新死鎖案例分析MySql
- MySQL死鎖案例一(回滾導致死鎖)MySql
- MySQL死鎖案例二(自增列導致死鎖)MySql
- 剖析6個MySQL死鎖案例的原因以及死鎖預防策略MySql
- MySQL死鎖案例分析一(先delete,再insert,導致死鎖)MySqldelete
- MySQL死鎖案例 – Learn. Write. Repeat.MySql
- 死鎖
- 什麼是死鎖?如何解決死鎖?
- MySQL強人“鎖”難《死磕MySQL系列 三》MySql
- 面試官:什麼是死鎖?怎麼排查死鎖?怎麼避免死鎖?面試
- 死鎖概述
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法
- 例項詳解 Java 死鎖與破解死鎖Java
- 檢視oracle死鎖程式並結束死鎖Oracle
- MySQL 死鎖和鎖等待MySql
- 死鎖和可重入鎖
- 面試:什麼是死鎖,如何避免或解決死鎖;MySQL中的死鎖現象,MySQL死鎖如何解決面試MySql
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- 死鎖是什麼?如何預防和避免死鎖?
- MySQL死鎖系列-線上死鎖問題排查思路MySql
- 死鎖-舉例
- 併發:死鎖
- 遭遇ITL死鎖
- GCD 死鎖原因GC
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- Mysql 兩階段鎖和死鎖MySql
- 鎖的使用與死鎖的避免
- SQLServer的死鎖分析(1):頁鎖SQLServer
- mysql行鎖和死鎖檢測MySql
- 如何避免死鎖和活鎖? - simar