婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 一次神奇的MySQL死鎖排查記錄

一次神奇的MySQL死鎖排查記錄

熱門標簽:俄國地圖標注app 百度地圖標注后不顯示 昆明電信400電話辦理 溫州瑞安400電話怎么申請 電銷機器人 行業 南昌高頻外呼系統哪家公司做的好 淄博400電話申請 電銷機器人各個細節介紹 電話機器人市場趨勢

背景

說起Mysql死鎖,之前寫過一次有關Mysql加鎖的基本介紹,對于一些基本的Mysql鎖或者死鎖都有一個簡單的認識,可以看下這篇文章為什么開發人員需要了解數據庫鎖。有了上面的經驗之后,本以為對于死鎖都能手到擒來,沒想到再一個陽光明媚的下午報出了一個死鎖,但是這一次卻沒想象的那么簡單。

問題初現

在某天下午,突然系統報警,拋出個異常:

仔細一看好像是事務回滾異常,寫著的是因為死鎖回滾,原來是個死鎖問題,由于我對Mysql鎖還是有一定了解的,于是開始主動排查這個問題。

首先在數據庫中查找Innodb Status,在Innodb Status中會記錄上一次死鎖的信息,輸入下面命令:

SHOW ENGINE INNODB STATUS 

死鎖信息如下,sql信息進行了簡單處理:

------------------------ 
LATEST DETECTED DEADLOCK 
------------------------ 
2019-02-22 15:10:56 0x7eec2f468700 
*** (1) TRANSACTION: 
TRANSACTION 2660206487, ACTIVE 0 sec starting index read 
mysql tables in use 1, locked 1 
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s) 
MySQL thread id 31261312, OS thread handle 139554322093824, query id 11624975750 10.23.134.92 erp_crm__6f73 updating 
/*id:3637ba36*/UPDATE tenant_config SET 
 open_card_point = 0 
 where tenant_id = 123 
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 1322 page no 534 n bits 960 index uidx_tenant of table `erp_crm_member_plan`.`tenant_config` trx id 2660206487 lock_mode X locks rec but not gap waiting 
 *** (2) TRANSACTION: 
TRANSACTION 2660206486, 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 31261311, OS thread handle 139552870532864, query id 11624975758 10.23.134.92 erp_crm__6f73 updating 
/*id:3637ba36*/UPDATE tenant_config SET 
 open_card_point = 0 
 where tenant_id = 123 
*** (2) HOLDS THE LOCK(S): 
RECORD LOCKS space id 1322 page no 534 n bits 960 index uidx_tenant of table `erp_crm_member_plan`.`tenant_config` trx id 2660206486 lock mode S 
*** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 1322 page no 534 n bits 960 index uidx_tenant of table `erp_crm_member_plan`.`tenant_config` trx id 2660206486 lock_mode X locks rec but not gap waiting 
 *** WE ROLL BACK TRANSACTION (1) 
------------ 

給大家簡單的分析解釋一下這段死鎖日志,事務1執行Update語句的時候需要獲取uidx_tenant這個索引再where條件上的X鎖(行鎖),事務2執行同樣的Update語句,也在uidx_tenant上面想要獲取X鎖(行鎖),然后就出現了死鎖,回滾了事務1。當時我就很懵逼,回想了一下死鎖產生的必要條件:

1、互斥。

2、請求與保持條件。

3、不剝奪條件。

4、循環等待。

從日志上來看事務1和事務2都是取爭奪同一行的行鎖,和以往的互相循環爭奪鎖有點不同,怎么看都無法滿足循環等待條件。經過同事提醒,既然從死鎖日志中不能進行排查,那么就只能從業務代碼和業務日志從排查。這段代碼的邏輯如下:

public int saveTenantConfig(PoiContext poiContext, TenantConfigDO tenantConfig) { 
 try { 
  return tenantConfigMapper.saveTenantConfig(poiContext.getTenantId(), poiContext.getPoiId(), tenantConfig); 
 } catch (DuplicateKeyException e) { 
  LOGGER.warn("[saveTenantConfig] 主鍵沖突,更新該記錄。context:{}, config:{}", poiContext, tenantConfig); 
  return tenantConfigMapper.updateTenantConfig(poiContext.getTenantId(), tenantConfig); 
 } 
 } 

這段代碼的意思是保存一個配置文件,如果發生了唯一索引沖突那么就會進行更新,當然這里可能寫得不是很規范,其實可以用

insert into ... 
on duplicate key update 

也可以達到同樣的效果,但是就算用這個其實也會發生死鎖。看了代碼之后同事又給我發了當時業務日志,

可以看見這里有三條同時發生的日志,說明都發生了唯一索引沖突進入了更新的語句,然后發生的死鎖。到這里答案終于稍微有點眉目了。

這個時候再看我們的表結構如下(做了簡化處理):

CREATE TABLE `tenant_config` ( 
 `id` bigint(21) NOT NULL AUTO_INCREMENT, 
 `tenant_id` int(11) NOT NULL, 
 `open_card_point` int(11) DEFAULT NULL, 
 PRIMARY KEY (`id`), 
 UNIQUE KEY `uidx_tenant` (`tenant_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT 

我們的tenant_id是用來做唯一索引,我們的插入和更新的where條件都是基于唯一索引來操作的。

UPDATE tenant_config SET 
 open_card_point = 0 
 where tenant_id = 123 

到了這里感覺插入的時候對唯一索引加鎖有關系,接下來我們進行下一步的深入剖析。

深入剖析

上面我們說有三個事務進入update語句,為了簡化說明這里我們只需要兩個事務同時進入update語句即可,下面的表格展示了我們整個的發生過程:

小提示:S鎖是共享鎖,X鎖是互斥鎖。一般來說X鎖和S,X鎖都互斥,S鎖和S鎖不互斥。

我們從上面的流程中看見發生這個死鎖的關鍵需要獲取S鎖,為什么我們再插入的時候需要獲取S鎖呢?因為我們需要檢測唯一索引?在RR隔離級別下如果要讀取那么就是當前讀,那么其實就需要加上S鎖。這里發現唯一鍵已經存在,這個時候執行update就會被兩個事務的S鎖互相阻塞,從而形成上面的循環等待條件。

小提示: 在MVCC中,當前讀和快照讀的區別:當前讀每次需要加鎖(可以使共享鎖或者互斥鎖)獲取到最新的數據,而快照讀是讀取的是這個事務開始的時候那個快照,這個是通過undo log去進行實現的。

這個就是整個死鎖的原因,能出現這種死鎖的還有一個情況,就是同一時間來三個插入操作,其中先插入的那個事務如果最后回滾了,其余兩個事務也會出現這種死鎖。

解決方案

這里的核心問題是需要把S鎖給干掉,這里有三個可供參考的解決方案:

  •  將RR隔離級別,降低成RC隔離級別。這里RC隔離級別會用快照讀,從而不會加S鎖。
  •  再插入的時候使用select * for update,加X鎖,從而不會加S鎖。
  •  可以提前加上分布式鎖,可以利用Redis,或者ZK等等,分布式鎖可以參考我的這篇文章。聊聊分布式鎖

第一種方法不太現實,畢竟隔離級別不能輕易的修改。第三種方法又比較麻煩。所以第二種方法是我們最后確定的。

總結

說了這么多,最后做一個小小的總結吧。排查死鎖這種問題的時候有時候光看死鎖日志有時候會解決不了問題,需要結合整個的業務日志,代碼以及表結構來進行分析,才能得到正確的結果。當然上面有一些數據庫鎖的基本知識如果不了解可以查看我的另一篇文章為什么開發人員需要了解數據庫鎖。

最后這篇文章被我收錄于JGrowing-CaseStudy篇,一個全面,優秀,由社區一起共建的Java學習路線,如果您想參與開源項目的維護,可以一起共建,github地址為:https://github.com/javagrowing/JGrowing

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

您可能感興趣的文章:
  • Mysql查看死鎖與解除死鎖的深入講解
  • MySQL死鎖檢查處理的正常方法
  • MySQL死鎖的產生原因以及解決方案
  • 關于MySQL死鎖問題的深入分析
  • MySQL死鎖套路之唯一索引下批量插入順序不一致
  • 一個mysql死鎖場景實例分析
  • MySQL數據庫之Purge死鎖問題解析
  • 詳解通過SQL進行分布式死鎖的檢測與消除

標簽:葫蘆島 海口 洛陽 安徽 甘南 嘉峪關 拉薩 吐魯番

巨人網絡通訊聲明:本文標題《一次神奇的MySQL死鎖排查記錄》,本文關鍵詞  一次,神奇,的,MySQL,死鎖,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《一次神奇的MySQL死鎖排查記錄》相關的同類信息!
  • 本頁收集關于一次神奇的MySQL死鎖排查記錄的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    国产精品免费观看视频| 欧美日本国产视频| 91在线视频免费91| 中文字幕的久久| 国产69精品久久777的优势| 久久这里都是精品| 日韩精品一区第一页| 欧美肥大bbwbbw高潮| 首页国产欧美久久| 91精品国产高清一区二区三区 | 亚洲成人免费视频| 欧美男男青年gay1069videost| 亚洲一区在线观看免费| 制服丝袜成人动漫| 国产成a人亚洲精品| 国产精品成人免费| 欧美一级免费大片| 国产精品亚洲成人| 亚洲另类在线视频| 精品久久一区二区三区| 国产成人综合亚洲网站| 一区二区三区四区在线免费观看| 欧美日韩一区三区| 国产成人av资源| 亚洲mv大片欧洲mv大片精品| 精品国产三级a在线观看| 国产成人自拍高清视频在线免费播放| 亚洲视频一区在线| 精品日产卡一卡二卡麻豆| 国产精品中文字幕日韩精品| 精品国产一区二区三区久久久蜜月| 久久成人免费网| 亚洲乱码一区二区三区在线观看| 欧美亚洲国产怡红院影院| 久久国产人妖系列| 亚洲成人资源在线| 国产亚洲一区二区在线观看| 91美女片黄在线观看91美女| 蜜臀av一区二区| 亚洲综合丁香婷婷六月香| 精品国产区一区| 欧美精选一区二区| 国产丶欧美丶日本不卡视频| 国产精品盗摄一区二区三区| 欧美mv日韩mv国产| 欧美三级电影一区| gogogo免费视频观看亚洲一| 久久精品99久久久| 日本中文字幕一区| 亚洲二区视频在线| 一区二区三区在线观看网站| 日本一区二区动态图| 欧美在线高清视频| 91麻豆高清视频| 99精品1区2区| av电影天堂一区二区在线观看| 黑人精品欧美一区二区蜜桃| 午夜精品在线视频一区| 亚洲精品国产a| 伊人婷婷欧美激情| 亚洲女厕所小便bbb| 一区在线中文字幕| 日韩一区欧美小说| 一区二区三区日本| 亚洲国产综合色| 亚洲1区2区3区4区| 日本不卡一区二区三区高清视频| 午夜免费欧美电影| 美女免费视频一区二区| 久久99九九99精品| 精品综合久久久久久8888| 免费日本视频一区| 久久精品国产久精国产爱| 激情久久五月天| 国产成人精品午夜视频免费| 国产寡妇亲子伦一区二区| 成人毛片老司机大片| 91福利在线看| 91麻豆精品国产91久久久资源速度| 欧美一级一区二区| 国产视频一区二区在线观看| 久久久不卡网国产精品二区| 中文字幕永久在线不卡| 亚洲一区二区黄色| 免费观看日韩电影| 成人动漫av在线| 欧美性感一类影片在线播放| 日韩午夜在线观看| 国产精品毛片久久久久久 | 久久免费的精品国产v∧| 国产日产欧美精品一区二区三区| 成人欧美一区二区三区视频网页| 亚洲激情五月婷婷| 久久国产尿小便嘘嘘| 不卡的av在线播放| 91精品国产免费久久综合| 国产日韩欧美一区二区三区乱码 | 99久久精品情趣| 欧美色老头old∨ideo| 欧美精品在线一区二区三区| 欧美一区二区视频观看视频| 久久久精品国产免费观看同学| 亚洲精品videosex极品| 麻豆91在线播放| 91小视频免费观看| 欧美mv日韩mv| 婷婷中文字幕一区三区| 成人免费视频免费观看| 欧美高清视频一二三区 | 亚洲国产三级在线| 国产一区二区伦理片| 欧美视频中文字幕| 中文文精品字幕一区二区| 天天综合日日夜夜精品| av中文字幕亚洲| 久久精品一区二区三区不卡| 日本色综合中文字幕| 日本精品视频一区二区| 国产日韩欧美精品一区| 蜜臀91精品一区二区三区| 欧美日韩日日摸| 亚洲码国产岛国毛片在线| 秋霞av亚洲一区二区三| 欧美午夜精品一区| 亚洲线精品一区二区三区八戒| 不卡av在线网| 精品久久久久久久人人人人传媒| 久久精品亚洲乱码伦伦中文| 性做久久久久久免费观看欧美| 国产一区二区三区免费播放| 精品噜噜噜噜久久久久久久久试看| 亚洲在线视频免费观看| 91久久精品国产91性色tv| 最新不卡av在线| av电影在线观看一区| 日韩伦理免费电影| 91网站最新网址| 亚洲人123区| 91麻豆国产自产在线观看| 亚洲欧洲美洲综合色网| av一区二区三区| 尤物av一区二区| 欧美日韩国产片| 美女一区二区三区| 精品久久久久久久人人人人传媒| 久久国产成人午夜av影院| 久久亚洲春色中文字幕久久久| 久久精品国产亚洲高清剧情介绍| 精品日韩一区二区| 国产很黄免费观看久久| 亚洲视频图片小说| 欧美片网站yy| 国产精品69毛片高清亚洲| 国产精品成人免费在线| 欧美在线小视频| 国内精品国产成人国产三级粉色| 国产色产综合色产在线视频| 国v精品久久久网| 亚洲国产视频直播| 久久久精品免费观看| 色综合久久中文综合久久97| 亚洲综合激情网| 亚洲精品一区二区三区在线观看| 福利电影一区二区| 夜夜操天天操亚洲| 精品久久久久久久久久久久久久久 | 欧美一级免费观看| 国产999精品久久久久久绿帽| 中文字幕一区二区日韩精品绯色| 欧美在线观看你懂的| 九九国产精品视频| 洋洋av久久久久久久一区| 久久综合久久综合九色| 日本道色综合久久| 国产一区二区看久久| 亚洲第一激情av| 国产欧美日本一区视频| 欧美精品在线观看播放| av动漫一区二区| 国产剧情一区在线| 亚洲高清一区二区三区| 中文av字幕一区| 久久亚洲捆绑美女| 日韩一区二区精品| 95精品视频在线| 国产成人综合自拍| 国产尤物一区二区在线| 午夜精品久久久久影视| 亚洲视频在线一区二区| 国产欧美一区二区三区沐欲| 欧美精品aⅴ在线视频| 欧美在线视频日韩| 色悠悠亚洲一区二区| 成人ar影院免费观看视频| 国产在线播放一区| 麻豆精品一区二区三区| 日韩精品高清不卡| 亚洲成人精品一区二区| 中文字幕在线观看不卡视频| 久久精品水蜜桃av综合天堂|