讀5.7官網文檔之14.7.3 Locks Set by Different SQL Statements in InnoDB 之insert篇

并非翻譯,是看了官網文檔以后的讀書筆記弦聂,如有錯誤,歡迎大家指出揭蜒。

insert加的鎖

insert會分兩步加鎖横浑,先加一個insert intention lock剔桨,第二步會在插入行上面添加一個排他鎖屉更。如果插入的行上已經有了排他鎖,導致獲取不到排他鎖就會轉成請求插入行的share鎖洒缀,繼續(xù)等待瑰谜。如果獲取到share鎖欺冀,再升級為排他鎖。接下來來驗證下是不是這樣的萨脑。

實驗相關背景條件

root@localhost>select @@version,@@transaction_isolation from dual;
+------------+-------------------------+
| @@version  | @@transaction_isolation |
+------------+-------------------------+
| 5.7.22-log | REPEATABLE-READ         |
+------------+-------------------------+

root@localhost [(none)] 14:49:58>show create table test.t;
+-------+-------------------------------------------------+
| Table | Create Table                                    |
+-------+-------------------------------------------------+
| t     | CREATE TABLE `t` (
  `a` int(11) NOT NULL,
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`a`),
  KEY `idx_b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------+
  • 實驗一
root@localhost>begin;
Query OK, 0 rows affected (0.00 sec)
root@localhost>insert into t() values(5,6);
Query OK, 1 row affected (0.01 sec)

在看show engine innodb status

---TRANSACTION 1551519, ACTIVE 47 sec
1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 1
MySQL thread id 24771, OS thread handle 140374083041024, query id 12402642 localhost root
TABLE LOCK table `test`.`t` trx id 1551519 lock mode IX

上面的語句根本看不到插入意向鎖和行的排他鎖隐轩,只能看到一個表級別的意向鎖。

  • 實驗二

既然看不到渤早,就堵塞你职车,看看能不能看到。

先生成一個gap鎖鹊杖。

###會話一
root@localhost>begin;
Query OK, 0 rows affected (0.00 sec)

root@localhost>select * from t;
+----+------+
| a  | b    |
+----+------+
|  1 |    2 |
|  2 |    3 |
|  3 |    4 |
|  4 |    5 |
| 11 |   22 |
+----+------+
5 rows in set (0.01 sec)
root@localhost>update t set b = 10 where a = 5;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

在看show engine innodb status日志

2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 24771, OS thread handle 140374083041024, query id 12409482 localhost root
Trx read view will not see trx with id >= 1551536, sees < 1551536
TABLE LOCK table `test`.`t` trx id 1551536 lock mode IX
RECORD LOCKS space id 1483 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 1551536 lock_mode X locks gap before rec. 
###上面一行顯示在主鍵的某條記錄前面加上了一個排他的gap鎖
###下面這個告知了具體是哪一行
Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 8000000b; asc     ;;  ###獲取hex值的后面四位悴灵,然后轉換為10進制,可以得到值是11骂蓖,也就是說把主鍵值為11前面的gap鎖住了积瞒。這里多謝葉金榮老師
 1: len 6; hex 00000017a692; asc       ;;
 2: len 7; hex fe0000003b0137; asc     ; 7;;
 3: len 4; hex 80000016; asc     ;;

然后我們再執(zhí)行insert語句,照理來說insert語句會因為可重復讀被堵住登下。

###會話二
root@localhost [test] 15:18:38>begin;
Query OK, 0 rows affected (0.00 sec)

root@localhost [test] 15:18:40>insert into t() values(5,6);

會話二如愿被阻塞了茫孔,再來看一下具體什么鎖在等待

---TRANSACTION 1551603, ACTIVE 58 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 24777, OS thread handle 140374067091200, query id 12416225 localhost root update
insert into t() values(5,6)
------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1483 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 1551603 lock_mode X locks gap before rec insert intention waiting
##下面這行具體是指主鍵值是11的行,也就是說是在請求11和4之間的insert intention gap鎖
Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 8000000b; asc     ;;##表示主鍵值是11的行記錄被芳,把hex值的后四位即000b轉換為10進制可得值為11
 1: len 6; hex 00000017a692; asc       ;;
 2: len 7; hex fe0000003b0137; asc     ; 7;;
 3: len 4; hex 80000016; asc     ;;

我把會話一提交了缰贝,照理來說會話二應該接下來持有的是被插入行也就是(5,6)這一行的排他鎖畔濒,但是從innodb status當中沒有看到揩瞪,還是只能看到插入意向鎖。

  • 實驗三

既然看不到行的排他鎖篓冲,只能在試試看別的方法了

###會話一
root@localhost >begin;
Query OK, 0 rows affected (0.00 sec)
root@localhost >insert into t() values(5,6);
###會話二
root@localhost >begin;
Query OK, 0 rows affected (0.00 sec)
root@localhost>insert into t() values(5,6);

同時在兩個會話當中插入同一行數(shù)據李破。再來看看鎖的等待情況。由于會話一沒有提交壹将,所以會話二是不會馬上報重復值的錯的,而是被阻塞住嗤攻。

---TRANSACTION 1551610, ACTIVE 3 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 24771, OS thread handle 140374083041024, query id 12425387 localhost root update
insert into t() values(5,6)
------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:
##下面這個表示正在等待主鍵值為5的這一行的
RECORD LOCKS space id 1483 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 1551610 lock mode S waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000005; asc     ;;
 1: len 6; hex 00000017acf3; asc       ;;
 2: len 7; hex f10000003a0110; asc     :  ;;
 3: len 4; hex 80000006; asc     ;;

---TRANSACTION 1551603, ACTIVE 1001 sec
3 lock struct(s), heap size 1136, 4 row lock(s), undo log entries 1
MySQL thread id 24777, OS thread handle 140374067091200, query id 12419372 localhost root
TABLE LOCK table `test`.`t` trx id 1551603 lock mode IX
RECORD LOCKS space id 1483 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 1551603 lock_mode X locks gap before rec insert intention
##這里還是顯示11之前的gap被插入意向鎖占著呢
Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 8000000b; asc     ;;
 1: len 6; hex 00000017a692; asc       ;;
 2: len 7; hex fe0000003b0137; asc     ; 7;;
 3: len 4; hex 80000016; asc     ;;
##下面表示主鍵值為5的這一行被加上了排他鎖
RECORD LOCKS space id 1483 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 1551603 lock_mode X locks rec but not gap
Record lock, heap no 8 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 80000005; asc     ;; #這里的hex值0005轉換為10進制就是5
 1: len 6; hex 00000017acf3; asc       ;;
 2: len 7; hex f10000003a0110; asc     :  ;;
 3: len 4; hex 80000006; asc     ;;

上面的日志中可以看到會話一在被插入行上加了排他鎖,會話二由于插入的重復數(shù)據诽俯,所以變成了請求插入上的行共享鎖妇菱,和文檔描述一致。

總結

通過三個實驗暴区,終于看到官網文檔所描述的鎖了闯团,先嘗試加插入意向鎖,再加上行的排他鎖仙粱,如果行已經被加上了排他鎖房交,會變成請求行共享鎖繼續(xù)等待。不過要吐槽的還是這個鎖的查看機制伐割,只能通過show engine innodb status才能看的清楚候味。要是通過表的話刃唤,感覺會方便好多。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末白群,一起剝皮案震驚了整個濱河市尚胞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帜慢,老刑警劉巖笼裳,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異粱玲,居然都是意外死亡侍咱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門密幔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來楔脯,“玉大人,你說我怎么就攤上這事胯甩∶镣ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵偎箫,是天一觀的道長木柬。 經常有香客問我,道長淹办,這世上最難降的妖魔是什么眉枕? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮怜森,結果婚禮上速挑,老公的妹妹穿的比我還像新娘。我一直安慰自己副硅,他們只是感情好姥宝,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著恐疲,像睡著了一般腊满。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上培己,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天碳蛋,我揣著相機與錄音,去河邊找鬼省咨。 笑死肃弟,一個胖子當著我的面吹牛,可吹牛的內容都是我干的茸炒。 我是一名探鬼主播愕乎,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼阵苇,長吁一口氣:“原來是場噩夢啊……” “哼壁公!你這毒婦竟也來了感论?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤紊册,失蹤者是張志新(化名)和其女友劉穎比肄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囊陡,經...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡芳绩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了撞反。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妥色。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖遏片,靈堂內的尸體忽然破棺而出嘹害,到底是詐尸還是另有隱情,我是刑警寧澤吮便,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布笔呀,位于F島的核電站,受9級特大地震影響髓需,放射性物質發(fā)生泄漏许师。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一僚匆、第九天 我趴在偏房一處隱蔽的房頂上張望微渠。 院中可真熱鬧,春花似錦咧擂、人聲如沸敛助。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纳击。三九已至,卻和暖如春攻臀,著一層夾襖步出監(jiān)牢的瞬間焕数,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工刨啸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堡赔,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓设联,卻偏偏與公主長得像善已,于是被迫代替她去往敵國和親灼捂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348