一起聊聊Mysql兩階段鎖和死鎖

藏色散人
發布: 2022-12-05 19:20:58
轉載
2136 人瀏覽過

這篇文章為大家帶來了關於mysql鎖的相關知識,其中主要介紹了Mysql 兩階段鎖和死鎖,下面一起來看一下,希望對大家有幫助。

兩階段鎖定

概念

講的是InnoDB如何處理行鎖的上鎖,釋放鎖定的行為。

交易使用過程中,對記錄以主鍵為條件刪改時,會立刻加上排他鎖,這完成了上鎖階段。

當刪改動作完成後,這個鎖定並不會立即釋放,需要等至交易提交時,才會釋放鎖定

引發的問題-阻塞

begin;update t set k=k 1 where id=1;update t set k=k 2 where id=1;
#交易A
交易B


update t set k=k 1 where id= 2;

#begin;
commit;

根據兩階段鎖定協議,事務B將會因為id=1的資料被

事務A

上了鎖,而阻塞,因為交易B要拿到鎖後才能進行下一步操作。 上述這個問題,可能看起來問題不大,但是如果不只事務B,還有

事務C

事務D

,等等很多,做的是跟事務B一樣的事,問題就大了,被阻塞的執行緒就會多了起來。 【推薦學習:MySQL影片教學如何處理上述問題我們應該盡量將可能會引起阻塞的語句,放到交易的最後面操作,例如上述

事務A

範例中的id=1的語句,它和第二句的執行並沒有什麼關聯關係,可是它是容易造成阻塞的語句,因為在

在事務B

中也要對這一行資料做鎖定作業(在各類事務中頻繁使用的,如公司的收付款帳號餘額記錄,即

**熱點行**

),但是卻在事務一開始就拿到鎖了。

本質上,是縮短了拿鎖時間和釋放鎖之間的時間。即持有鎖的時間縮短,以此減少鎖所造成的阻塞。

死鎖

  • 概念

    兩個線程,互相在等待對方釋放資源。 在兩個事務A,B。

  • 交易 A拿到了資源 A的鎖定。

  • 交易 B拿到了資源 B的鎖定。

  • 交易 A去拿資源 B的鎖定。

交易 B

去拿資源 A的鎖定。

很明顯,步驟 3,4中,事務 A,B 都想去拿鎖,但是又都拿不到,因為對方都還沒有釋放該資源的鎖。這種現象就是死鎖。 引發的問題-死鎖

InnoDB

中,有一個拿鎖的等待時間配置,超過這個時間就會拋出異常,這個時間預設是50秒。通常來說,有一個介面需要在

50

秒後才會回應是不可接受的。 innodb_lock_wait_timeout

那是不是把這個設定時間設定短一點就行了?例如1秒?

應該是不可以的,因為可能會影響到你的正常業務,或許你的業務導致你的事務執行時間本身就比較長,超過1秒。超出這個時間會拋出異常,你的正常業務就被影響了。

那該如何處理上述問題

InnoDB中,還有一個自動偵測死鎖並處理的設定。它是預設開啟的,在極端情況下,雖然能處理問題,但是對

CPU

消耗特別大。 它原理是在事務中即將要上鎖的時候,會去檢測其他並發線程,有沒有將此資源鎖住,如果檢測到某個

線程A

有,然後再會去偵測

線程A

的依賴有沒有被其他並發線程鎖住,如此循環往復,最後判斷這些鎖會不會形成死鎖。 可以看出,執行緒越多,偵測成本就越大。 innodb_deadlock_detect

僅代表個人當前的學習做出的對此問題的處理和總結:1.關閉死鎖檢測,將拿鎖時間配置縮短至預估的最高時間,通常不會超過15秒,超過

15

秒後,需要有重試機制。

###2.開啟死鎖偵測,在應用層控制並發連線數,使用連線池控制###Mysql###的連線數,在服務層限制###Mysql####最大連線數。 ######以上是對怎樣減少行鎖效能影響的學習總結。 ###

以上是一起聊聊Mysql兩階段鎖和死鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:learnku.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板