mysql innodb 并发 插入 慢_Innodb 锁机制——一次插入慢查询的排查
慢查詢日志中,發下有一條插入語句慢查詢出現的概率比較高,一個簡單插入需要消耗4-10s,很不尋常。附上插入語句,省略了一些字段
INSERT INTO `fc_pay_out_trade_log` (`out_trade_no`,`dateline`) VALUES ('191120093724940457',1574185044) [ RunTime:4.176669s ]
fc_pay_out_trade_log 表除了主鍵,out_trade_no字段為普通索引,沒有其他索引。
mysql5.7版本,innodb引擎,默認RR級別。
業務流程:
1.生成訂單流水id(out_trade_no),寫入訂單流水日志表fc_pay_out_trade_log,就是發送阻塞的語句
2.組合參數,調用微信統一下單接口->微信操作支付然后回調回調接口
3.回調接口全部放到一個事務中處理,有個操作是更新訂單流水日志表fc_pay_out_trade_log對應的訂單流水id的支付狀態
UPDATE `fc_pay_out_trade_log` SET `pay_status`=1,`pay_time`=1574221674 WHERE `out_trade_no` = '191120194747307594' [ RunTime:0.000716s ]
訂單流水out_trade_no生成規則
$out_trade_no = date(‘YmdHis’).rand(1000,9999);
對innodb鎖機制比較了解的人應該發現了問題所在,這是因為update操作把innodb的間隙鎖把fc_pay_out_trade_log表的部分區域鎖住了,導致插入操作阻塞,必須等update操作的那個事務提交后才會釋放這個間隙鎖。
分析過程
1.前一個支付操作發生,支付成功后回調接口,執行上面的update語句,更新的條件是WHERE out_trade_no = ‘191120194747307594’,為了保證不出現幻讀現象,innodb會使用next-key鎖,就是鎖住這行和間隙。
2.后一個支付發生,創建一個訂單流水,插入到fc_pay_out_trade_log表,發現插入的區域已經被鎖住,阻塞等待
3.前一個支付處理完其他事情,提交事務,釋放fc_pay_out_trade_log表的next-key鎖
4.后一個支付流水插入成功
下面這條語句會鎖定哪些區域?鎖多久才會釋放?
UPDATE `fc_pay_out_trade_log` SET `pay_status`=1,`pay_time`=1574221674 WHERE `out_trade_no` = '191120194747307594' [ RunTime:0.000716s ]
innodb鎖類型
S-共享鎖:又叫讀鎖,其他事務可以繼續加共享鎖,但是不能繼續加排他鎖。
X-排他鎖: 又叫寫鎖,一旦加了寫鎖之后,其他事務就不能加鎖
IS意向共享鎖:表達一個事務想要獲取一張表中某幾行的共享鎖。
IX意向排他鎖:表達一個事務想要獲取一張表中某幾行的共享鎖。
InnoDB鎖算法
記錄鎖
記錄鎖是鎖住記錄的,這里要說明的是這里鎖住的是索引記錄,而不是我們真正的數據記錄。
如果鎖的是非主鍵索引,會在自己的索引上面加鎖之后然后再去主鍵上面加鎖鎖住.
如果表上沒有索引(包括沒有主鍵),則會使用隱藏的主鍵索引進行加鎖。
如果要鎖的列沒有索引,則會進行全表記錄加鎖。
例如:select * from user where id= 1 for update; 會給user表加上IX,在主鍵索引1加上X鎖。
間隙鎖
鎖間隙的意思就是鎖定某一個范圍,間隙鎖又叫gap鎖,其不會阻塞其他的gap鎖,但是會阻塞插入間隙鎖,這也是用來防止幻讀的關鍵。
我們來分析一下fc_pay_out_trade_log,out_trade_no字段是一個普通索引,并且新增的數據都是有順序的,所以WHERE out_trade_no = ‘191120194747307594’ 鎖住的間隙會包括[191120194747307594,~),而新插入的值一定會在這個間隙區域中,所以會產出阻塞。
next-key鎖
這個鎖本質是記錄鎖加上gap鎖。在RR隔離級別下(InnoDB默認),Innodb對于行的掃描鎖定都是使用此算法,但是如果查詢掃描中有唯一索引會退化成只使用記錄鎖。
解決辦法:修改fc_pay_out_trade_log表的out_trade_no字段設置為唯一索引即可
本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
用過哪些工具?為啥用這個工具(速度快,支持高并發...)?底層如何實現的?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的mysql innodb 并发 插入 慢_Innodb 锁机制——一次插入慢查询的排查的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何正确使用烤箱,避免食物烤糊?
- 下一篇: 有没有那种适合和好姐妹一起喝的奶茶啊?