前言:由於以爲這個案例頗有意思,由於決定今天分享一下。昨晚在我收拾東西準備回家的時候,忽然,收到線上業務報警,有大量的DeadLock產生,而後就開始打開服務器。。。(全部信息已經通過脫敏處理)html
問題現象:
mysql
排查過程:sql
查看mysql 服務器當時的狀態,是發現有不少的死鎖信息的,以下所示:服務器
------------------------ LATEST DETECTED DEADLOCK ------------------------ 2017-12-18 22:05:17 7f3550209700 *** (1) TRANSACTION: TRANSACTION 27707529, ACTIVE 75 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 6 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 1 MySQL thread id 372227, OS thread handle 0x7f3520da8700, query id 48360426 xx update INSERT INTO xxxx values(xxxxx) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 631 page no 59 n bits 440 index xxxx of table xxxx trx id 27707529 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 219 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 8; hex 2c0d3e08bbab9816; asc , > ;; 1: len 8; hex 000000000000091b; asc ;; *** (2) TRANSACTION: TRANSACTION 27705830, ACTIVE 77 sec inserting mysql tables in use 1, locked 1 53 lock struct(s), heap size 13864, 2 row lock(s), undo log entries 1 MySQL thread id 371954, OS thread handle 0x7f3550209700, query id 48352484 xxxx xxxx update INSERT INTO xxxxx *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 631 page no 59 n bits 440 index xxxx of table xxxx trx id 27705830 lock mode S locks gap before rec Record lock, heap no 219 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 8; hex 2c0d3e08bbab9816; asc , > ;; 1: len 8; hex 000000000000091b; asc ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 631 page no 59 n bits 440 index xxxx of table xxxx trx id 27705830 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 219 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 8; hex 2c0d3e08bbab9816; asc , > ;; 1: len 8; hex 000000000000091b; asc ;; *** WE ROLL BACK TRANSACTION (1)
納尼?insert產生的死鎖?再仔細一看,insert竟然產生了gap lock?T2怎麼會在等待本身的鎖?一條insert怎麼會有兩行被鎖住?微信
先分析一下上面的這個監控信息吧,第一個事物等待的是一個帶有gap的意向排他鎖,第二個事物持有一個帶有gap的共享鎖,在等待一個帶有gap的意向排他鎖。好像根據上面的內容不能判斷具體的產生這個問題的緣由,而後我就着手開始分析mysql的現場監控日誌。網站
------------ TRANSACTIONS ------------ ---TRANSACTION 27711843, ACTIVE 190 sec inserting mysql tables in use 1, locked 1 1 lock struct(s), heap size 360, 0 row lock(s), undo log entries 1 MySQL thread id 781310, OS thread handle 0x7f2f3b2ca700, query id 48377233 xxxx xxxx update INSERT INTO xxxx values xxxxxx ---TRANSACTION 27711842, ACTIVE 195 sec inserting mysql tables in use 1, locked 1 1 lock struct(s), heap size 360, 0 row lock(s) MySQL thread id 775682, OS thread handle 0x7f35206f5700, query id 48377231 xxxx xxxx update INSERT INTO xxxx values xxxxx ---TRANSACTION 27711841, ACTIVE 195 sec inserting mysql tables in use 1, locked 1 1 lock struct(s), heap size 360, 0 row lock(s), undo log entries 1 MySQL thread id 775681, OS thread handle 0x7f3520a98700, query id 48377229 xxxx xxxx update INSERT INTO xxxxx values xxxxx ---TRANSACTION 27711840, ACTIVE 200 sec rollback ROLLING BACK 2 lock struct(s), heap size 360, 1 row lock(s) MySQL thread id 770360, OS thread handle 0x7f3521b0e700, query id 48377227 xxxx xxxx Trx read view will not see trx with id >= 27711841, sees < 27705729 ---TRANSACTION 27711839, ACTIVE 200 sec inserting mysql tables in use 1, locked 1 1 lock struct(s), heap size 360, 0 row lock(s), undo log entries 1 MySQL thread id 770258, OS thread handle 0x7f3522caa700, query id 48377224 xxxx xxxx update INSERT INTO xxxx values xxxxx
這裏面能夠很明顯的看到幾個信息:spa
一、有事物執行失敗回滾了;日誌
二、有大量不一樣的事物,在操做同一條記錄信息;code
三、有不少大事物。orm
個人猜想:
是有大量的不一樣的事物去同時操做同一行記錄,致使的死鎖
驗證猜想:
同時執行上面的三個事物,因爲其餘緣由第一個事物實行失敗回滾,在mysql裏面,rollback的時候,實際上是執行了一個delete的操做,T2繼承了T1的鎖,所以鎖隊列應該是這樣的:T1回滾->T2 S鎖->T3 S鎖->T2意向插入鎖->T3意向插入鎖。也就是T2在等待T3的S鎖,T3又在等待T2的意向排查鎖,T3的意向排他鎖,又在等待本身的S鎖,T3太燒腦,因此報Deadlock,回滾T3。
看下咱們的監控輸出
------------------------ LATEST DETECTED DEADLOCK ------------------------ 2017-12-19 15:09:22 7f61206a0700 *** (1) TRANSACTION: TRANSACTION 13155, ACTIVE 7 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 4 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 1 MySQL thread id 23, OS thread handle 0x7f61206d1700, query id 170 127.0.0.1 root update insert into t1(id_card) values(7) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 13 page no 4 n bits 80 index `uniq_card` of table `tom`.`t1` trx id 13155 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 80000008; asc ;; 1: len 4; hex 80000003; asc ;; *** (2) TRANSACTION: TRANSACTION 13154, ACTIVE 10 sec inserting mysql tables in use 1, locked 1 4 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 1 MySQL thread id 24, OS thread handle 0x7f61206a0700, query id 169 127.0.0.1 root update insert into t1(id_card) values(7) *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 13 page no 4 n bits 80 index `uniq_card` of table `tom`.`t1` trx id 13154 lock mode S locks gap before rec Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 80000008; asc ;; 1: len 4; hex 80000003; asc ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 13 page no 4 n bits 80 index `uniq_card` of table `tom`.`t1` trx id 13154 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 80000008; asc ;; 1: len 4; hex 80000003; asc ;; *** WE ROLL BACK TRANSACTION (2)
OK,至此問題找到,我能夠退下了。官網介紹就不貼了,能夠點擊下面的連接去看
官方網站相關介紹:https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html
具體鎖分析參考:http://mysqllover.com/?p=431
爲了方便你們交流,本人開通了微信公衆號(關注看更多精彩)和QQ羣,QQ羣1(291519319)和QQ羣2(659336691)。喜歡技術的一塊兒來交流吧