故障分析 | MySQL死鎖案例分析
網名“北在南方”,資深 DBA,主要負責資料庫架構設計和運維平臺開發工作,擅長資料庫效能調優、故障診斷。
一 背景
二 案例分析
2.1 業務邏輯
2.2 環境說明
事務隔離級別 REPEATABLE-READ
create table dl(
id int auto_increment primary key,
c1 int not null ,
c2 int not null,
key idx_c1(c1));
insert into dl(c1,c2) values (3,1),(3,2),(3,2),(3,3),(4,4),(5,5);
2.3 測試用例
2.4 死鎖日誌
------------------------
LATEST DETECTED DEADLOCK
------------------------
2022-12-03 16:43:59 140261132850944
*** (1) TRANSACTION:
TRANSACTION 1416764, ACTIVE 15 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1128, 3 row lock(s)
MySQL thread id 15, OS thread handle 140261086668544, query id 283 localhost msandbox updating
update dl set c2=10 where c1=5
*** (1) HOLDS THE LOCK(S):
RECORD LOCKS space id 49 page no 5 n bits 80 index idx_c1 of table `test`.`dl` trx id 1416764 lock_mode X
Record lock, heap no 8 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 49 page no 4 n bits 80 index PRIMARY of table `test`.`dl` trx id 1416764 lock_mode X locks rec but not gap waiting
Record lock, heap no 7 PHYSICAL RECORD: n_fields 5; compact format; info bits 32
*** (2) TRANSACTION:
TRANSACTION 1416759, ACTIVE 23 sec updating or deleting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1128, 2 row lock(s), undo log entries 1
MySQL thread id 16, OS thread handle 140261085611776, query id 286 localhost msandbox updating
delete from dl where id=6
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 49 page no 4 n bits 80 index PRIMARY of table `test`.`dl` trx id 1416759 lock_mode X locks rec but not gap
Record lock, heap no 7 PHYSICAL RECORD: n_fields 5; compact format; info bits 32
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 49 page no 5 n bits 80 index idx_c1 of table `test`.`dl` trx id 1416759 lock_mode X locks rec but not gap waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
*** WE ROLL BACK TRANSACTION (2)
2.5 死鎖分析
sess1 開啟一個事務,在T2 時刻執行 select for update ,持有 id=6 的 lock_mode X record lock.
sess2 在T3 時刻執行根據 c1=5 的更新,但是其加鎖順序是先在索引 idx_c1 上加鎖,順利加鎖,然後到申請加主鍵上 id=6 的鎖,發現 sess1 已經持有主鍵 id=6 的X的鎖,因此需要等待。如日誌中 (1) TRANSACTION: 中 WAITING FOR的提示
RECORD LOCKS space id 49 page no 4 n bits 80 index PRIMARY of table test.dl trx id 1416764 lock_mode X locks rec but not gap waiting
sess1 執行 delete id=6 的操作,由於事務本身已經持有了主鍵上的鎖,刪除記錄同時要對索引
idx_c1
上的記錄加上lock_mode
X record lock,發現該鎖已經被 sess2 持有,形成了死鎖條件,sess1 報錯,發生回滾。
2.6 如何解決
idx_c1上
的加鎖造成迴圈等待產生死鎖。三 小結
原則 1:加鎖的基本單位是 next-key lock。
原則 2:查詢過程中訪問到的物件才會加鎖。
最佳化 1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock 退化為行鎖。
最佳化 2:索引上的等值查詢,向右遍歷時且最後一個值不滿足等值條件的時候,next-key lock 退化為間隙鎖。
在讀提交隔離級別下還有一個最佳化,即:語句執行過程中加上的行鎖,在語句執行完成後,就要把“不滿足條件的行”上的行鎖直接釋放了,不需要等到事務提交
本文關鍵字:#死鎖# #MySQL#
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024924/viewspace-2930951/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL批量更新死鎖案例分析MySql
- 死鎖案例分析
- GreatSQL 死鎖案例分析SQL
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- MySQL 死鎖問題分析MySql
- MySQL 死鎖日誌分析MySql
- MySQL死鎖案例分析一(先delete,再insert,導致死鎖)MySqldelete
- MySQL鎖等待與死鎖問題分析MySql
- 死鎖分析
- MySQL:RR分析死鎖一列MySql
- 線上BUG:MySQL死鎖分析實戰MySql
- MySQL死鎖分析與解決之路MySql
- 故障分析 | MySQL鎖等待超時一例分析MySql
- 故障分析 | 從 Insert 併發死鎖分析 Insert 加鎖原始碼邏輯原始碼
- HashMap死鎖分析HashMap
- 【MySQL】死鎖案例之六MySql
- 【MySQL】死鎖案例之七MySql
- 【MySQL】死鎖案例之八MySql
- 【MySQL】死鎖案例之四MySql
- 【MySQL】死鎖案例之一MySql
- 【MySQL】死鎖案例之二MySql
- 【MySQL】死鎖案例之三MySql
- MySQL死鎖系列-常見加鎖場景分析MySql
- MySQL · 答疑解惑 · 物理備份死鎖分析MySql
- MySQL資料庫故障分析-鎖等待(一)MySql資料庫
- 故障分析 | MySQL 從機故障重啟後主從同步報錯案例分析MySql主從同步
- MySQL:Innodb 一個死鎖案例MySql
- 一次 MySQL 線上死鎖分析實戰MySql
- MySQL死鎖案例一(回滾導致死鎖)MySql
- MySQL死鎖案例二(自增列導致死鎖)MySql
- 一個最不可思議的 MySQL 死鎖分析MySql
- SQLServer的死鎖分析(1):頁鎖SQLServer
- ORACLE 死鎖分析過程Oracle
- Sqlserver分析死鎖問題SQLServer
- 線上死鎖問題分析
- 剖析6個MySQL死鎖案例的原因以及死鎖預防策略MySql
- MySQL鎖分析MySql
- 手把手教你分析解決MySQL死鎖問題MySql