国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

MYSQL INNODB replace into 死鎖 及 next key lock 解析

2024-07-24 12:34:46
字體:
來源:轉載
供稿:網友
  全文帶入了大量自我認知和理解,可能錯誤,因為水平有限,但是代表我努力分析過。
 
  一、問題提出
  問題是由姜大師提出的、問題如下:
  表:
  mysql> show create table c /G
  *************************** 1. row ***************************
         Table: c
  Create Table: CREATE TABLE `c` (
    `a` int(11) NOT NULL AUTO_INCREMENT,
    `b` int(11) DEFAULT NULL,
    PRIMARY KEY (`a`),
    UNIQUE KEY `b` (`b`)
  ) ENGINE=InnoDB
  1 row in set (0.01 sec)
  開啟兩個會話不斷的執行
  replace into c values(NULL,1);
  會觸發死鎖。問死鎖觸發的原因。
 
  我使用的環境:
  MYSQL 5.7.14 debug版本、隔離級別RR、自動提交,很顯然這里的c表中的可以select出來的記錄始終是1條
  只是a列不斷的增大,但是這里實際存儲空間確不止1條,因為從heap no來看二級索引中,heap no 已經到了
  7,也就是有至少7(7-1)條記錄,只是其他記錄標記為del并且被purge線程放到了page free_list中。
 
  二、準備工作和使用方法
  1、稍微修改了源碼關于鎖的打印部分,我們知道每個事物下顯示鎖內存結構lock
     struct會連接成一個鏈表,只要按照順序打印出內存lock struct就打印出了
     所有關于這個事物顯示鎖全部信息和加鎖順序如下:
 
  點擊(此處)折疊或打開
 
  ---TRANSACTION 184771, ACTIVE 45 sec
  4 lock struct(s), heap size 1160, 3 row lock(s)
  MySQL thread id 2, OS thread handle 140737154311936, query id 642 localhost root cleaning up
  ---lock strcut(1):(Add by gaopeng) In modify Version I force check all REC_LOCK/TAB_LOCK for this Trx
  TABLE LOCK table `test`.`c4` trx id 184771 lock mode IX
  ---lock strcut(2):(Add by gaopeng) In modify Version I force check all REC_LOCK/TAB_LOCK for this Trx
  RECORD LOCKS space id 413 page no 4 n bits 72 index id2 of table `test`.`c4` trx id 184771 lock_mode X(LOCK_X)
  Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
   0: len 4; hex 80000014; asc ;;
   1: len 4; hex 80000014; asc ;;
  ---lock strcut(3):(Add by gaopeng) In modify Version I force check all REC_LOCK/TAB_LOCK for this Trx
  RECORD LOCKS space id 413 page no 3 n bits 72 index PRIMARY of table `test`.`c4` trx id 184771 lock_mode X(LOCK_X) locks rec but not gap(LOCK_REC_NOT_GAP)
  Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
   0: len 4; hex 80000014; asc ;;
   1: len 6; hex 00000002d1bd; asc ;;
   2: len 7; hex a600000e230110; asc # ;;
   3: len 4; hex 80000014; asc ;;
  ---lock strcut(4):(Add by gaopeng) In modify Version I force check all REC_LOCK/TAB_LOCK for this Trx
  RECORD LOCKS space id 413 page no 4 n bits 72 index id2 of table `test`.`c4` trx id 184771 lock_mode X(LOCK_X) locks gap before rec(LOCK_GAP)
  Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
   0: len 4; hex 8000001e; asc ;;
   1: len 4; hex 8000001e; asc ;;
  
  點擊(此處)折疊或打開
 
  ---TRANSACTION 184771, ACTIVE 45 sec
  4 lock struct(s), heap size 1160, 3 row lock(s)
  MySQL thread id 2, OS thread handle 140737154311936, query id 642 localhost root cleaning up
  部分后面的都是我加上的,其實修改很簡單,innodb其實自己寫好了只是沒有開啟,我開啟后加上了序號來表示順序。
  上面是一個 select * from c where  id2= 20 for update; b列為輔助索引的所有4 lock struct(s),可以看到有了這些信息分析
  不那么難了。
  這里稍微分析一下
  表結構為:
  mysql> show create table c4;
  +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | Table | Create Table                                                                                                                                                  |
  +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
  | c4    | CREATE TABLE `c4` (
    `id1` int(11) NOT NULL,
    `id2` int(11) DEFAULT NULL,
    PRIMARY KEY (`id1`),
    KEY `id2` (`id2`)
  ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
  +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
  1 row in set (0.00 sec)
  數據為:
  mysql> select * from c4;
  +-----+------+
  | id1 | id2  |
  +-----+------+
  |   1 |    1 |
  |  10 |   10 |
  |  20 |   20 |
  |  30 |   30 |
  +-----+------+
  4 rows in set (0.00 sec)
 
  2、在死鎖檢測回滾前調用這個打印函數打印到err日志文件中,打印出全部的事物的顯示內存lock struct如下,這里就
  不給出了,后面會有replace觸發死鎖千事物鎖結構的一個輸出
  
  3、使用MYSQL TRACE SQL語句得到大部分的函數調用來分析replace的過程
 
  修改出現的問題:修改源碼打印出所有lock struct 在線上顯然是不能用的。因為打印出來后show engine innodb status 會非常
  長,甚至引發其他問題,但是測試是可以,其次修改了打印死鎖事物鎖鏈表到日志后,每次只要遇到死鎖信息可以打印
  到日志,但是每次MYSQLD都會掛掉,但是不影響分析了。

(編輯:武林網)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 郴州市| 筠连县| 阳新县| 康乐县| 广元市| 兰考县| 西城区| 石棉县| 清苑县| 江安县| 武城县| 连城县| 遂川县| 苏尼特左旗| 文登市| 榆社县| 台中市| 木里| 常德市| 临泉县| 基隆市| 东宁县| 拉萨市| 葵青区| 大城县| 芮城县| 西藏| 布拖县| 申扎县| 彝良县| 乌兰县| 六枝特区| 甘泉县| 曲阜市| 龙州县| 兰西县| 江阴市| 章丘市| 沂南县| 兰西县| 新竹县|