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

解決MySQL共享鎖引發(fā)的死鎖問題

 更新時間:2023年11月08日 09:22:04   作者:程序員清風(fēng)  
這篇文章主要給大家介紹了MySQL共享鎖引發(fā)的死鎖問題的原因和解決辦法,文中通過代碼示例和圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下

死鎖問題 → 共享間隙鎖引起的死鎖 → 如何產(chǎn)生共享間隙鎖 → 何時產(chǎn)生的隱式鎖轉(zhuǎn)換

問題現(xiàn)象

在一個事務(wù)內(nèi)只會鎖一行的數(shù)據(jù),沒有鎖多行數(shù)據(jù)才會出現(xiàn)的順序問題,但是會偶爾報個Deadlock

事務(wù)內(nèi)sql執(zhí)行順序如下:

前提

數(shù)據(jù)庫隔離級別 為 RC

建表語句:

CREATE TABLE `user_money_account_test` (
  `id` bigint(20) NOT NULL COMMENT '主鍵',
  `userId` bigint(20) NOT NULL COMMENT '用戶id',
  `accountTypeId` int(11) NOT NULL COMMENT '賬戶類型id',
  `currencyId` int(11) NOT NULL COMMENT '貨幣id',
  `moneyBalance` decimal(30,4) NOT NULL COMMENT '貨幣余額',
  `createdTime` bigint(20) NOT NULL,
  `updatedTime` bigint(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `userId_accountTypeId` (`userId`,`accountTypeId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4  dbpartition by hash(`userId`) tbpartition by hash(`userId`) tbpartitions 4;

問題初探之一 —— 死鎖日志

------------------------ LATEST DETECTED DEADLOCK ------------------------ 2023-11-03 15:54:57 0x7f556ddca700
*** (1) TRANSACTION: TRANSACTION 7103074779, ACTIVE 0 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s) MySQL thread id 1528, OS thread handle 140005316216576, query id 109102299 100.104.192.64 athyxrnr statistics /*DRDS /10.11.43.140/117db74e43c34001-4/ */SELECT `user_money_account`.`id`, `user_money_account`.`userId`, `user_money_account`.`accountTypeId`, `user_money_account`.`currencyId`, `user_money_account`.`moneyBalance`, `user_money_account`.`createdTime`, `user_money_account`.`updatedTime` FROM `user_money_account_eGz3_008` AS `user_money_account` WHERE ((`user_money_account`.`userId` = 474232840) AND (`user_money_account`.`accountTypeId` = 202)) FOR UPDATE
?
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 526 page no 8711 n bits 704 index userId_accountTypeId of table `bolt_money_account_e5l6_0001`.`user_money_account_egz3_008` trx id 7103074779 lock_mode X locks rec but not gap waiting Record lock, heap no 318 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 8; hex 800000001c443808; asc D8 ;; 1: len 4; hex 800000ca; asc ;; 2: len 8; hex 8139b4e738c01045; asc 9 8 E;;
?
?
?
?
*** (2) TRANSACTION: TRANSACTION 7103074777, ACTIVE 0 sec starting index read mysql tables in use 1, locked 1 3 lock struct(s), heap size 1136, 2 row lock(s) MySQL thread id 6870, OS thread handle 140004892124928, query id 109102300 100.104.192.122 athyxrnr statistics /*DRDS /10.11.107.138/117db74e42312000-4/ */SELECT `user_money_account`.`id`, `user_money_account`.`userId`, `user_money_account`.`accountTypeId`, `user_money_account`.`currencyId`, `user_money_account`.`moneyBalance`, `user_money_account`.`createdTime`, `user_money_account`.`updatedTime` FROM `user_money_account_eGz3_008` AS `user_money_account` WHERE ((`user_money_account`.`userId` = 474232840) AND (`user_money_account`.`accountTypeId` = 202)) FOR UPDATE
?
*** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 526 page no 8711 n bits 704 index userId_accountTypeId of table `bolt_money_account_e5l6_0001`.`user_money_account_egz3_008` trx id 7103074777 lock mode S Record lock, heap no 318 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 8; hex 800000001c443808; asc D8 ;; 1: len 4; hex 800000ca; asc ;; 2: len 8; hex 8139b4e738c01045; asc 9 8 E;;
?
*** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 526 page no 8711 n bits 704 index userId_accountTypeId of table `bolt_money_account_e5l6_0001`.`user_money_account_egz3_008` trx id 7103074777 lock_mode X locks rec but not gap waiting Record lock, heap no 318 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 8; hex 800000001c443808; asc D8 ;; 1: len 4; hex 800000ca; asc ;; 2: len 8; hex 8139b4e738c01045; asc 9 8 E;

問題一:

答:Tx1獲取到了某行數(shù)據(jù)的間隙共享鎖,之后Tx1和Tx2都去獲取該行的排他行鎖導(dǎo)致的死鎖

問題探究之二:沒有顯式地lock in share mode 為什么會有共享間隙鎖?

問題2.1 同時進(jìn)行的只有兩個事務(wù)嗎?

問題2.1:答:第三個事務(wù)可能是產(chǎn)生共享間隙鎖的關(guān)鍵

事務(wù)內(nèi)sql語句還原:

時間點1時的鎖狀態(tài):

select * from information_schema.innodb_trx;

select * from information_schema.innodb_locks;

select * from information_schema.innodb_lock_waits;

時間點2時的鎖狀態(tài):

select * from information_schema.innodb_trx;

select * from information_schema.innodb_locks;

select * from information_schema.innodb_lock_waits;

問題二:答:同時進(jìn)行的兩個事務(wù)同時insert帶來的共享間隙鎖

問題追問之三 —— 為什么同時進(jìn)行的兩個事務(wù)同時insert會產(chǎn)生共享間隙鎖

問題三 答 ——

INSERT操作在插入或更新記錄時,檢查到Duplicate key(或者有一個被標(biāo)記刪除的duplicate key),對于普通的INSERT/UPDATE,會加LOCK_S鎖,而對于類似REPLACE INTO或者INSERT ..ON DUPLICATE這樣的SQL加的是X鎖。而針對不同的索引類型也有所不同:

  • 對于聚集索引(參閱函數(shù)row_ins_duplicate_error_in_clust),隔離級別小于等于RC時,加的是LOCK_REC_NOT_GAP類似的S或者X記錄鎖。否則加LOCK_ORDINARY類型的記錄鎖(NEXT-KEY LOCK)
  • 對于二級唯一索引,若檢查到重復(fù)鍵,當(dāng)前版本總是加LOCK_ORDINARY類型的記錄鎖(函數(shù) row_ins_scan_sec_index_for_duplicate)。實際上按照RC的設(shè)計理念,不應(yīng)該加GAP鎖(bug#68021),官方也事實上嘗試修復(fù)過一次,即對于RC隔離級別加上LOCK_REC_NOT_GAP,但卻引入了另外一個問題,導(dǎo)致二級索引的唯一約束失效(bug#73170),由于這個嚴(yán)重bug,官方很快又把這個fix給revert掉了。

問題擴展之四 —— sql執(zhí)行時機發(fā)生變化時的效果

會產(chǎn)生什么結(jié)果呢??

一句話結(jié)論

Tx1和Tx2兩個事務(wù)并行insert相同唯一索引的數(shù)據(jù),導(dǎo)致先執(zhí)行insert的Tx1獲得了排他鎖,Tx2等待獲得共享鎖;

在Tx1釋放排他鎖的時候,Tx2拿到了共享間隙鎖,但此時另一個事務(wù)Tx3請求該行的排他鎖,被阻塞;

之后Tx2也去請求該行的排他鎖,至此,形成了Tx2和Tx3組成的環(huán)形等待,形成死鎖

解決辦法

將長事務(wù)拆分成多個小事務(wù),不要在一個事務(wù)內(nèi)對同一行數(shù)據(jù)既insert,又select ... for update

其他擴展問題

隔離級別為RR會有什么不同嗎?

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

相關(guān)文章

  • mysql啟動時報錯:error while loading shared libraries: libncurses.so.5: cannot open shared object file的解決辦法

    mysql啟動時報錯:error while loading shared li

    這篇文章主要給大家介紹了解決mysql啟動時報錯:error while loading shared libraries: libncurses.so.5: cannot open shared object file的方法,需要的朋友可以參考下
    2023-08-08
  • mysql表類型查詢示例詳解

    mysql表類型查詢示例詳解

    這篇文章主要介紹了mysql表類型查詢示例詳解,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-04-04
  • Mysql鎖內(nèi)部實現(xiàn)機制之C源碼解析

    Mysql鎖內(nèi)部實現(xiàn)機制之C源碼解析

    數(shù)據(jù)庫之所以要加鎖,因為數(shù)據(jù)庫是一個多用戶使用的共享資源。當(dāng)多個用戶并發(fā)地存取數(shù)據(jù)時,在數(shù)據(jù)庫中就會產(chǎn)生多個事務(wù)同時存取同一數(shù)據(jù)的情況。若對并發(fā)操作不加控制就可能會讀取和存儲不正確的數(shù)據(jù),破壞數(shù)據(jù)庫的一致性
    2022-08-08
  • MySQL創(chuàng)建唯一索引時報錯Duplicate?entry?*?for?key問題

    MySQL創(chuàng)建唯一索引時報錯Duplicate?entry?*?for?key問題

    這篇文章主要介紹了MySQL創(chuàng)建唯一索引時報錯Duplicate?entry?*?for?key問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • MySQL存儲引擎應(yīng)用場景MyISAM?vs?InnoDB優(yōu)勢選擇

    MySQL存儲引擎應(yīng)用場景MyISAM?vs?InnoDB優(yōu)勢選擇

    這篇文章主要為大家介紹了MySQL存儲引擎應(yīng)用場景MyISAM?vs?InnoDB優(yōu)勢選擇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 使用SQL實現(xiàn)小計,合計以及排序

    使用SQL實現(xiàn)小計,合計以及排序

    本篇文章是對SQL實現(xiàn)小計,合計以及排序進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • mysql 實現(xiàn)互換表中兩列數(shù)據(jù)方法簡單實例

    mysql 實現(xiàn)互換表中兩列數(shù)據(jù)方法簡單實例

    這篇文章主要介紹了mysql 實現(xiàn)互換表中兩列數(shù)據(jù)方法簡單實例的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • MySQL函數(shù)與存儲過程字符串長度限制的解決

    MySQL函數(shù)與存儲過程字符串長度限制的解決

    本文主要介紹了MySQL函數(shù)與存儲過程字符串長度限制的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • MySQL排序與分頁講解

    MySQL排序與分頁講解

    這篇文章主要介紹了MySQL排序與分頁講解,使用 ORDER BY 對查詢到的數(shù)據(jù)進(jìn)行排序操作,按照dept_id的降序排列,salary的升序排列相關(guān)展開文章,需要的小伙伴可以參考一下
    2022-01-01
  • MySQL索引下推(ICP)的簡單理解與示例

    MySQL索引下推(ICP)的簡單理解與示例

    大家應(yīng)該都知道索引下推可以提高查詢效率,所以下面這篇文章主要給大家介紹了關(guān)于MySQL索引下推(ICP)的簡單理解與示例的相關(guān)資料,需要的朋友可以參考下
    2021-09-09

最新評論