死鎖案例分析
錯誤日誌中關於此次死鎖的記錄如下,顯示的是兩個update語句產生了死鎖!
LATEST DETECTED DEADLOCK
------------------------
2021-01-15 18:12:40 7f9c01daf700
*** (1) TRANSACTION:
TRANSACTION 16175364313, ACTIVE 0 sec starting index read
mysql tables in use 3, locked 3
LOCK WAIT 4 lock struct(s), heap size 1184, 3 row lock(s)
MySQL thread id 149648015, OS thread handle 0x7fa255658700, query id 24131125938 10.1.1.1 app_test updating
update image_tmp_liu
SET handle_status = '0'
handle_describe = '系統異常'
where file_name = '2021011110194000010000000000170020723568.htm'
and file_type = 'LOAN_AUTHZ'
and ins_date = '20210115'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6966 page no 1747854 n bits 472 index `idx_ins_date` of table `my_jiebei`.`image_tmp` trx id 16175364313 lock_mode X waiting
*** (2) TRANSACTION:
TRANSACTION 16175364307, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
9 lock struct(s), heap size 1184, 17 row lock(s), undo log entries 1
MySQL thread id 149645724, OS thread handle 0x7f9c01daf700, query id 24131125920 10.1.1.1 app_test updating
update image_tmp_liu
SET handle_status = '1',
handle_describe = '成功'
where file_name = '2021010710194000010000000000950019899845.htm'
and file_type = 'LOAN_AUTHZ'
and ins_date = '20210115'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 6966 page no 1747854 n bits 472 index `idx_ins_date` of table `my_jiebei`.`image_tmp` trx id 16175364307 lock_mode X
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6966 page no 1345962 n bits 144 index `PRIMARY` of table `my_jiebei`.`image_tmp` trx id 16175364307 lock_mode X locks rec but not gap waiting
*** WE ROLL BACK TRANSACTION (1)
image_tmp_liu表的 ins_date列上是索引
一:產生死鎖的原因:
可以參考實戰45講的第21講
加鎖的規則如下:
原則 1:加鎖的基本單位是 next-key lock。希望你還記得,next-key lock 是前開後閉區間。
原則 2:查詢過程中訪問到的物件才會加鎖。
最佳化 1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock 退化為行鎖。
最佳化 2:索引上的等值查詢,向右遍歷時且最後一個值不滿足等值條件的時候,next-key lock 退化為間隙鎖。
一個 bug:唯一索引上的範圍查詢會訪問到不滿足條件的第一個值為止。
根據原則2 查詢過程中訪問到的物件才會加鎖,(給索引加鎖是給索引列上加鎖,不是給整行資料加鎖,也就是隻有訪問到的物件才會加鎖)。事務1更新的時候,透過索引 ins_date來查到主鍵值,然後回表透過主鍵來找到 handle_status和handle_describe的值,訪問到主鍵了,所以會給主鍵加鎖,然而主鍵也就是整行資料了(mysql innodb表是聚簇表,特別像oracle索引組織表),會嘗試給所有 ins_date = '20210115'的主鍵加x鎖,但是這個加鎖過程是一步一步的加的,並不是一次性加上的,又因為ins_date = '20210115'這個有多行資料(15行)。然後事務2也是會加這幾行的主鍵,同時又因為這兩個事務加鎖的步驟不通,也就是事務1加了部分的ins_date = '20210115'(例如主鍵為1 和2 的加上了x鎖)事務2加上部分ins_date = '20210115'(例如主鍵為3 和4加上x鎖 ),這樣當事務1又想去加主鍵為3 和4的資料,就需要等待,同理事務2也需要等待!
二:
可以藉助mysql 5.6的MRR特性來緩解此類的死鎖問題:
2.1 mrr緩解此案例死鎖的原理:
這裡的關鍵點在於回表訪問主鍵是一行一行的去回表的,所以給那需要加鎖的行加主鍵x鎖也不是原子的,而是一步一步的加的,如果能把這個回表的速度提升,那鎖定主鍵的時間便會降低,那產生死鎖的機率就會降低了,
MRR的最佳化在於,
並不是每次透過輔助索引就回表去取記錄,
而是將其rowid主鍵給快取起來,然後對rowid主鍵進行排序後,再去訪問記錄,這樣就能將隨機I/O轉化為順序I/O,從而大幅地提升效能。這個過程如下所示:
2.2 開啟MRR的新特性
然而,在MySQL當前版本中,基於成本的演算法過於保守,導致大部分情況下最佳化器都不會選擇MRR特性。為了確保最佳化器使用mrr特性,請執行下面的SQL語句:
set optimizer_switch='mrr=on,mrr_cost_based=off';
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29654823/viewspace-2750536/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- GreatSQL 死鎖案例分析SQL
- 故障分析 | MySQL死鎖案例分析MySql
- MySQL批量更新死鎖案例分析MySql
- 死鎖案例二
- 死鎖案例三
- MySQL死鎖案例分析一(先delete,再insert,導致死鎖)MySqldelete
- 【MySQL】死鎖案例之六MySql
- 【MySQL】死鎖案例之七MySql
- 【MySQL】死鎖案例之八MySql
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- MySQL:Innodb 一個死鎖案例MySql
- MySQL死鎖案例一(回滾導致死鎖)MySql
- MySQL死鎖案例二(自增列導致死鎖)MySql
- 剖析6個MySQL死鎖案例的原因以及死鎖預防策略MySql
- SQLServer的死鎖分析(1):頁鎖SQLServer
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- MySQL 死鎖問題分析MySql
- MySQL鎖等待與死鎖問題分析MySql
- MySQL死鎖案例 – Learn. Write. Repeat.MySql
- MySQL死鎖系列-常見加鎖場景分析MySql
- MySQL死鎖分析與解決之路MySql
- MySQL:RR分析死鎖一列MySql
- 死鎖
- 線上BUG:MySQL死鎖分析實戰MySql
- 故障分析 | 從 Insert 併發死鎖分析 Insert 加鎖原始碼邏輯原始碼
- 什麼是死鎖?如何解決死鎖?
- 面試官:什麼是死鎖?怎麼排查死鎖?怎麼避免死鎖?面試
- 死鎖概述
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法
- 例項詳解 Java 死鎖與破解死鎖Java
- 檢視oracle死鎖程式並結束死鎖Oracle
- MySQL 死鎖和鎖等待MySql
- 死鎖和可重入鎖
- 面試:什麼是死鎖,如何避免或解決死鎖;MySQL中的死鎖現象,MySQL死鎖如何解決面試MySql
- 一次 MySQL 線上死鎖分析實戰MySql
- 死鎖是什麼?如何預防和避免死鎖?
- MySQL死鎖系列-線上死鎖問題排查思路MySql
- 死鎖-舉例