欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL?insert死鎖問題解決詳細(xì)記錄

 更新時間:2022年11月04日 12:01:58   作者:jhgdike  
上周遇到一個因insert而引發(fā)的死鎖問題,其成因比較令人費解,下面這篇文章主要給大家介紹了關(guān)于MySQL?insert死鎖問題解決詳細(xì)記錄的相關(guān)資料,需要的朋友可以參考下

Insert死鎖問題剖析

線上有個批量的insert … on duplicate key update語句引發(fā)的死鎖問題,查過很多資料并且親自嘗試過后,發(fā)現(xiàn)好多博客說的都是錯的,其實本身只跟insert的順序有關(guān),在此記錄一下備忘。

前置知識

X型鎖:排他鎖

S型鎖:共享鎖

行鎖:鎖住一行記錄

Next-Key鎖:左開右閉區(qū)間

Gap鎖:左右開區(qū)間

構(gòu)造死鎖

建表:

CREATE TABLE hero (
    number INT AUTO_INCREMENT,
    name VARCHAR(100),
    country varchar(100),
    PRIMARY KEY (number),
    UNIQUE KEY uk_name (name)
) Engine=InnoDB CHARSET=utf8;

構(gòu)造初始數(shù)據(jù):

INSERT INTO hero VALUES
    (1, 'l劉備', '蜀'),
    (3, 'z諸葛亮', '蜀'),
    (8, 'c曹操', '魏'),
    (15, 'x荀彧', '魏'),
    (20, 's孫權(quán)', '吳');

好了,開始了,下面開始兩個事務(wù),按順序執(zhí)行:

事務(wù)1

begin:
INSERT INTO hero(name, country) VALUES('g關(guān)羽', '蜀');

事務(wù)2

begin:
INSERT INTO hero(name, country) VALUES('g關(guān)羽', '蜀');

事務(wù)1

INSERT INTO hero(name, country) VALUES('d鄧艾', '魏');

來了,它來了,這個時候我們就可以注意到事務(wù)2的死鎖報錯了:

# 事務(wù)T2
mysql> INSERT INTO hero(name, country) VALUES('g關(guān)羽', '蜀');
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

原因

請?zhí)砑訄D片描述

  • T1先插入name值為g關(guān)羽的記錄,可以插入成功,此時對應(yīng)的唯一索引記錄被隱式鎖保護(hù)
  • T2隨后插入name值為g關(guān)羽的記錄(必須為同一條記錄),發(fā)生阻塞,并且T2會想要獲取一把S型next-key鎖(只有唯一索引才會發(fā)生)(左開右閉)。此時T1的隱式鎖轉(zhuǎn)化為顯示鎖(X型行鎖)
  • T1想要插入d鄧艾的記錄,由于T2的next-key鎖(雖然沒被T2持有,但鎖已存在)而進(jìn)入阻塞等待狀態(tài),進(jìn)而發(fā)生死鎖

故死鎖產(chǎn)生的原因

  • T1在等待T2釋放name值為’g關(guān)羽’的二級索引記錄上的gap鎖。
  • T2在等待T1釋放name值為’g關(guān)羽’的二級索引記錄上的X型行鎖。

MySQL 5.7 的死鎖

前提

在比較新的版本中都可以遇見的,只要是insert … on duplicate key update 觸發(fā)了后面的update操作,那么此時其他的insert語句都會被阻塞,這主要是為了解決RR下的一些幻讀問題。

示例

在5.7版本中又有一些特殊情況。還是舉例

假如有如下表和數(shù)據(jù)

demo表

idnamevalue
11112
12222
13332

此時,如果事務(wù)1執(zhí)行了:

insert into demo (name, value) VALUES ("333", 1) ON duplicate KEY UPDATE value = value + 1;

事務(wù)2執(zhí)行了:

insert into demo (name, value) VALUES ("223", 1) ON duplicate KEY UPDATE value = value + 1;

事務(wù)3執(zhí)行了:

insert into demo (name, value) VALUES ("224", 1) ON duplicate KEY UPDATE value = value + 1;

那么首先事務(wù)2和事務(wù)3會被阻塞,然后事務(wù)1提交了,事務(wù)2和事務(wù)3就會發(fā)生死鎖,其中一個爆出死鎖的錯誤然后失敗,另一個則成功執(zhí)行。

原因

當(dāng)insert … on duplicate key 執(zhí)行成功之時,會在當(dāng)前唯一鍵和之前唯一鍵之間加一個隱式GAP鎖,如上會在222和333之間加上GAP鎖,此時,事務(wù)2和事務(wù)3想插入新數(shù)據(jù)都會被GAP鎖阻塞,此時GAP鎖轉(zhuǎn)為顯式,事務(wù)2和事務(wù)3同時也分別想要獲取X型的插入意向鎖。

然后事務(wù)1提交,此時GAP鎖并不會被釋放,由于5.7的bug,事務(wù)2和事務(wù)3都會拿到GAP鎖,此時他們?nèi)カ@取插入意向鎖的時候由于GAP鎖被對方拿到而矛盾,進(jìn)而死鎖。

解決方案

網(wǎng)上有很多方法,這里我提出一個另類的想法。

我們可以先用非事務(wù)的insert ignore去初始化數(shù)據(jù),后面在用事務(wù)的update操作去更新。

參考:https://zhuanlan.zhihu.com/p/457191971

總結(jié)

到此這篇關(guān)于MySQL insert死鎖問題的文章就介紹到這了,更多相關(guān)MySQL insert死鎖問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MYSQL Left Join優(yōu)化(10秒優(yōu)化到20毫秒內(nèi))

    MYSQL Left Join優(yōu)化(10秒優(yōu)化到20毫秒內(nèi))

    在實際開發(fā)中,相信大多數(shù)人都會用到j(luò)oin進(jìn)行連表查詢,但是有些人發(fā)現(xiàn),用join好像效率很低,而且驅(qū)動表不同,執(zhí)行時間也不同。那么join到底是如何執(zhí)行的呢,本文就詳細(xì)的介紹一下
    2021-12-12
  • Mysql 5.6.24安裝實例教程

    Mysql 5.6.24安裝實例教程

    這篇文章主要介紹了Mysql 5.6.24安裝實例教程,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-12-12
  • mysql?sock文件存儲了什么信息

    mysql?sock文件存儲了什么信息

    這篇文章主要為大家介紹了mysql?sock文件存儲了什么信息的內(nèi)容詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • mysql運行net start mysql報服務(wù)名無效的解決辦法

    mysql運行net start mysql報服務(wù)名無效的解決辦法

    這篇文章主要為大家詳細(xì)介紹了mysql運行net start mysql報服務(wù)名無效的解決辦法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • mysql中多表刪除其中ID相同記錄的方法

    mysql中多表刪除其中ID相同記錄的方法

    這篇文章主要介紹了mysql中多表刪除其中ID相同記錄的方法,需要的朋友可以參考下
    2014-04-04
  • MySQL?賬號密碼錯誤終極解決方法

    MySQL?賬號密碼錯誤終極解決方法

    這篇文章主要介紹了MySQL?賬號密碼錯誤終極解決方法,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • 詳解MySQL中UNION的用法

    詳解MySQL中UNION的用法

    這篇文章主要介紹了詳解MySQL中UNION的用法,是MySQL入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-05-05
  • MySQL數(shù)據(jù)庫操作DQL正則表達(dá)式

    MySQL數(shù)據(jù)庫操作DQL正則表達(dá)式

    這篇文章主要介紹了MySQL數(shù)據(jù)庫操作DQL正則表達(dá)式,正則表達(dá)式描述了一種字符串匹配的規(guī)則,正則表達(dá)式本身就是一個字符串,使用這個字符串來描述、用來定義匹配規(guī)則,匹配一系列符合某個句法規(guī)則的字符串
    2022-07-07
  • mysql enum字段類型的謹(jǐn)慎使用

    mysql enum字段類型的謹(jǐn)慎使用

    本文主要介紹了mysql enum字段類型使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Mysql的Explain使用方式及索引總結(jié)

    Mysql的Explain使用方式及索引總結(jié)

    這篇文章主要介紹了Mysql的Explain使用方式及索引總結(jié),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評論