小編給大家分享一下MySQL中如何排查并發(fā)插入引起的死鎖問題,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
專注于為中小企業(yè)提供網(wǎng)站設計制作、成都網(wǎng)站建設服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)黃埔免費做網(wǎng)站提供優(yōu)質的服務。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設實現(xiàn)規(guī)模擴充和轉變。
掛著VPN排查問題,不過當時并沒有排查出原因
上班之后,發(fā)現(xiàn)是客戶端的一個bug.本來應該發(fā)送一個請求,但是卻發(fā)送了大量的請求,應用層面又沒有做冪等設計,所以所有的請求都落到了數(shù)據(jù)庫層面。
數(shù)據(jù)庫是一個過程
環(huán)境
MySQL 5.6.14
事務隔離級別 讀提交
引起問題的邏輯大致如下:
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
Now suppose that three sessions perform the following operations in order:
Session 1:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Session 2:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Session 3:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Session 1:
ROLLBACK;
The first operation by session 1 acquires an exclusive lock for the row. The operations by sessions 2 and 3 both result in a duplicate-key error and they both request a shared lock for the row. When session 1 rolls back, it releases its exclusive lock on the row and the queued shared lock requests for sessions 2 and 3 are granted. At this point, sessions 2 and 3 deadlock: Neither can acquire an exclusive lock for the row because of the shared lock held by the other.
A similar situation occurs if the table already contains a row with key value 1 and three sessions perform the following operations in order:
Session 1:
START TRANSACTION; DELETE FROM t1 WHERE i = 1;
Session 2:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Session 3:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Session 1:
COMMIT;
The first operation by session 1 acquires an exclusive lock for the row. The operations by sessions 2 and 3 both result in a duplicate-key error and they both request a shared lock for the row. When session 1 commits, it releases its exclusive lock on the row and the queued shared lock requests for sessions 2 and 3 are granted. At this point, sessions 2 and 3 deadlock: Neither can acquire an exclusive lock for the row because of the shared lock held by the other.
可以看到,Insert的時候,對記錄上排它鎖和插入意向鎖.
并發(fā)的情況下,如果這個記錄已經(jīng)上了排它鎖,則會嘗試給這個記錄上共享鎖.
如果有三個以上的并發(fā)線程,
第一個線程上了排它鎖,第二和第三個線程,看到該記錄有排他鎖,則嘗試給這個記錄上共享鎖。
一旦第一個線程回滾,則第二,第三線程擁有共享鎖的同時,都在申請排它鎖.這時候就出現(xiàn)了死鎖.
需要注意的是,假如第一個線程提交了,則第二個,第三個線程會報重復主鍵的錯誤,但是這時候,第二個,第三個線程,還是擁有這個記錄的共享鎖.第二,第三線程必須回滾.否則他們擁有的共享鎖不釋放.
回到最開始的問題.
三個線程同時insert award_free_firecracker_watch_common表,一個線程成功獲取排它鎖,其他兩個線程上共享鎖.
等獲取排他鎖的線程提交,兩個上共享鎖的線程,最后一步 update award_free_firecracker_watch_common表,則產(chǎn)生了死鎖。
他們都是在獲取了共享鎖的同時,申請排它鎖.
以上是“mysql中如何排查并發(fā)插入引起的死鎖問題”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!