Mysql多索引引起死鎖問題

2021-09-24 17:11:18 字數 879 閱讀 9522

之前在資料庫中,發現一條sql語句會導致死鎖,但是其中查詢的鍵都加了索引了,這死鎖從何而來呢?

於是去檢視了sql語句和建表語句,如下:

update eagle_riskcon_third set                 msessage = ?               , time = ?             

where ip_id = ? and type = ?

檢視時,報錯為deadlock found when trying to get lock那麼確實是發生了死鎖,究竟是因為什麼呢?經過查詢和找尋資料,發現了問題所在:

update時,如果where條件裡面涉及多個字段,區分度都比較高且字段都分別建了索引的話,mysql會多個索引各走一遍,然後結果取個交集;

單條記錄更新不會引發問題; 多條記錄併發更新時,如果索引行數有重疊,因加鎖順序可能不同,互相等待可能會導致死鎖,為什麼加鎖順序會不同呢?

我們的sql中where條件的順序是一定的,那麼加鎖順序也應該一定,為什麼會有加鎖順序不同情況。情況是這樣的:因為我們使用的是兩個單值索引,where條件中是復合條件,那麼mysql會使用index merge進行優化,優化過程是mysql會先用索引1進行掃表,在用索引2進行掃表,然後求交集形成乙個合併索引。這個使用索引掃表的過程和我們本身的sql使用索引的順序可能存在互斥,所以造成了死鎖。

一、新增ip_id+type的組合索引,這樣就可以避免掉index merge;

第二、將優化器的index merge優化關閉;

建議選擇第一種方法來避免此問題的發生。

mysql死鎖 非主鍵索引更新引起的死鎖

背景 最近線上經常丟擲mysql的乙個deadlock,細細查來,長了知識!分析 錯誤日誌如下 21 02 02.563 error dao.commondao pool 15 thread 19 jbc.trade.qunar.com 703c9ddbe4b143609035365ca46bff3...

非主索引引起的死鎖

背景 最近線上經常丟擲mysql的乙個deadlock,細細查來,長了知識!分析 錯誤日誌如下 21 02 02.563 error dao.commondao pool 15 thread 19 jbc.trade.qunar.com 703c9ddbe4b143609035365ca46bff3...

Oracle外來鍵不加索引會引起死鎖問題

這篇文章主要介紹了oracle外來鍵不加索引引起死鎖的情況及解決,需要的朋友可以參考下 建立乙個表,此表作為子表 create table fk t as select from user objects delete from fk t where object id is null commit...