《Mysql必讀MSSQL產(chǎn)生死鎖的根本原因及解決方法》要點:
本文介紹了Mysql必讀MSSQL產(chǎn)生死鎖的根本原因及解決方法,希望對您有用。如果有疑問,可以聯(lián)系我們。
一、 什么是死鎖
MYSQL入門
死鎖是指兩個或兩個以上的進(jìn)程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進(jìn)下去.此時稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)發(fā)生了死鎖,這些永遠(yuǎn)在互相等的進(jìn)程稱為死鎖進(jìn)程.
MYSQL入門
二、 死鎖產(chǎn)生的四個需要條件
MYSQL入門
?互斥條件:指進(jìn)程對所分配到的資源進(jìn)行排它性使用,即在一段時間內(nèi)某資源只由一個進(jìn)程占用.如果此時還有其它進(jìn)程哀求資源,則哀求者只能等待,直至占有資源的進(jìn)程用畢釋放
MYSQL入門
?哀求和保持條件:指進(jìn)程已經(jīng)保持至少一個資源,但又提出了新的資源哀求,而該資源已被其它進(jìn)程占有,此時哀求進(jìn)程阻塞,但又對自己已獲得的其它資源保持不放
MYSQL入門
?不剝奪條件:指進(jìn)程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由本身釋放
MYSQL入門
?環(huán)路等待條件:指在產(chǎn)生死鎖時,必然存在一個進(jìn)程――資源的環(huán)形鏈,即進(jìn)程集合{P0,P1,P2,???,Pn}中的P0正在等待一個P1占用的資源;P1正在等待P2占用的資源,……,Pn正在等待已被P0占用的資源
MYSQL入門
這四個條件是死鎖的需要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發(fā)生死鎖.
MYSQL入門
三、 如何處理死鎖
MYSQL入門
1) 鎖模式
MYSQL入門
1.共享鎖(S)
MYSQL入門
由讀操作創(chuàng)建的鎖,防止在讀取數(shù)據(jù)的過程中,其它事務(wù)對數(shù)據(jù)進(jìn)行更新;其它事務(wù)可以并發(fā)讀取數(shù)據(jù).共享鎖可以加在表、頁、索引鍵或者數(shù)據(jù)行上.在SQL SERVER默認(rèn)隔離級別下數(shù)據(jù)讀取完畢后就會釋放共享鎖,但可以通過鎖提示或設(shè)置更高的事務(wù)隔離級別改變共享鎖的釋放時間.
MYSQL入門
2.獨占鎖(X)
MYSQL入門
對資源獨占的鎖,一個進(jìn)程獨占地鎖定了哀求的數(shù)據(jù)源,那么別的進(jìn)程無法在此數(shù)據(jù)源上獲得任何類型的鎖.獨占鎖一致持有到事務(wù)結(jié)束.
MYSQL入門
3.更新鎖(U)
MYSQL入門
更新鎖實際上并不是一種獨立的鎖,而是共享鎖與獨占鎖的混合.當(dāng)SQL SERVER執(zhí)行數(shù)據(jù)修改操作卻首先必要搜索表以找到必要修改的資源時,會獲得更新鎖.
MYSQL入門
更新鎖與共享鎖兼容,但只有一個進(jìn)程可以獲取當(dāng)前數(shù)據(jù)源上的更新鎖,
MYSQL入門
其它進(jìn)程無法獲取該資源的更新鎖或獨占鎖,更新鎖的作用就好像一個序列化閥門(serialization gate),將后續(xù)申請獨占鎖的哀求壓入隊列中.持有更新鎖的進(jìn)程能夠?qū)⑵滢D(zhuǎn)換成該資源上的獨占鎖.更新鎖不足以用于更新數(shù)據(jù)―實際的數(shù)據(jù)修改仍需要用到獨占鎖.對于獨占鎖的序列化訪問可以避免轉(zhuǎn)換死鎖的發(fā)生,更新鎖會保留到事務(wù)結(jié)束或者當(dāng)它們轉(zhuǎn)換成獨占鎖時為止.
MYSQL入門
4. 意向鎖(IX,IU,IS)
MYSQL入門
意向鎖并不是獨立的鎖定模式,而是一種指出哪些資源已經(jīng)被鎖定的機(jī)制.
MYSQL入門
如果一個表頁上存在獨占鎖,那么另一個進(jìn)程就無法獲得該表上的共享表鎖,這種層次關(guān)系是用意向鎖來實現(xiàn)的.進(jìn)程要獲得獨占頁鎖、更新頁鎖或意向獨占頁鎖,首先必需獲得該表上的意向獨占鎖.同理,進(jìn)程要獲得共享行鎖,必需首先獲得該表的意向共享鎖,以防止別的進(jìn)程獲得獨占表鎖.
MYSQL入門
5. 特殊鎖模式(Sch_s,Sch_m,BU)
MYSQL入門
SQL SERVER提供3種額外的鎖模式:架構(gòu)穩(wěn)定鎖、架構(gòu)修改鎖、大容量更新鎖.
MYSQL入門
6.轉(zhuǎn)換鎖(SIX,SIU,UIX)
MYSQL入門
轉(zhuǎn)換鎖不會由SQL SERVER 直接哀求,而是從一種模式轉(zhuǎn)換到另一種模式所造成的.SQL SERVER 2008支持3種類型的轉(zhuǎn)換鎖:SIX、SIU、UIX.其中最常見的是SIX鎖,如果事務(wù)持有一個資源上的共享鎖(S),然后又需要一個IX鎖,此時就會出現(xiàn)SIX.
MYSQL入門
7.鍵范圍鎖
MYSQL入門
鍵范圍鎖是在可序列化隔離級別中鎖定必定范圍內(nèi)數(shù)據(jù)的鎖.保證在查詢數(shù)據(jù)的鍵范圍內(nèi)不允許插入數(shù)據(jù).MYSQL入門
SQL SERVER 鎖模式MYSQL入門 |
||
縮寫MYSQL入門 |
鎖模式MYSQL入門 |
闡明MYSQL入門 |
SMYSQL入門 |
SharedMYSQL入門 |
允許其他進(jìn)程讀取但不克不及修改鎖定的資源MYSQL入門 |
XMYSQL入門 |
ExclusiveMYSQL入門 |
防止其余進(jìn)程讀取或者修改鎖定資源中的數(shù)據(jù)MYSQL入門 |
UMYSQL入門 |
UpdateMYSQL入門 |
防止其它進(jìn)程獲取更新鎖或獨占鎖;在搜索要修改的數(shù)據(jù)時使用MYSQL入門 |
ISMYSQL入門 |
Intent sharedMYSQL入門 |
表現(xiàn)該資源的一個組件被共享鎖鎖定了.只有在表或頁級別才能獲得這類鎖MYSQL入門 |
IUMYSQL入門 |
Intent updateMYSQL入門 |
表現(xiàn)該資源的一個組件被更新鎖鎖定了.只有在表或頁級別才能獲得這類鎖MYSQL入門 |
IXMYSQL入門 |
Intent exclusiveMYSQL入門 |
表現(xiàn)該資源的一個組件被獨占鎖鎖定了.只有在表或頁級別才能獲得這類鎖MYSQL入門 |
SIXMYSQL入門 |
Shared with intent exclusiveMYSQL入門 |
表現(xiàn)一個正持有共享鎖的資源還有一個組件(一頁或一行)被獨占鎖鎖定了MYSQL入門 |
SIUMYSQL入門 |
Shared with intent UpdateMYSQL入門 |
表現(xiàn)一個正持有共享鎖的資源還有一個組件(一頁或一行)被更新鎖鎖定了MYSQL入門 |
UIXMYSQL入門 |
Update with intent exclusiveMYSQL入門 |
表現(xiàn)一個正持有更新鎖的資源還有一個組件(一頁或一行)被獨占鎖鎖定了MYSQL入門 |
Sch-SMYSQL入門 |
Schema stabilityMYSQL入門 |
表現(xiàn)一個使用該表的查詢正在被編譯MYSQL入門 |
Sch-MMYSQL入門 |
Schema modificationMYSQL入門 |
表現(xiàn)表的結(jié)構(gòu)正在被修改MYSQL入門 |
BUMYSQL入門 |
Bulk UpdateMYSQL入門 |
在一個大容量復(fù)制操作將數(shù)據(jù)導(dǎo)入表中而且(手動或自動)應(yīng)用了TABLOCK查MYSQL入門 詢提示時使用MYSQL入門 |
2) 鎖粒度
MYSQL入門
SQL SERVER 可以在表、頁、行等級別鎖定用戶的數(shù)據(jù)資源即非系統(tǒng)資源(系統(tǒng)資源是用閂鎖來掩護(hù)的).此外SQL SERVER 還可以鎖定索引鍵和索引鍵范圍.
MYSQL入門
通過sys.dm_tran_locks視圖可以查看誰被鎖定了(如行,鍵,頁)、鎖的模式以及特定資源的標(biāo)記符.基于sys.dm_tran_locks視圖創(chuàng)建如下視圖用于查看鎖定的資源以及鎖模式(通過這個視圖可以查看事務(wù)鎖定的表、頁、行以及加在數(shù)據(jù)資源上的鎖類型).
MYSQL入門
CREATE VIEW dblocks AS SELECT request_session_id AS spid, DB_NAME(resource_database_id) AS dbname, CASE WHEN resource_type='object' THEN OBJECT_NAME(resource_associated_entity_id) WHEN resource_associated_entity_id=0 THEN 'n/a' ELSE OBJECT_NAME(p.object_id) END AS entity_name, index_id, resource_type AS RESOURCE, resource_description AS DESCRIPTION, request_mode AS mode, request_status AS STATUS FROM sys.dm_tran_locks t LEFT JOIN sys.partitions p ON p.partition_id=t.resource_associated_entity_id WHERE resource_database_id=DB_ID()
3) 如何跟蹤死鎖
MYSQL入門
通過選擇sql server profiler 變亂中的如下選項就可以跟蹤到死鎖產(chǎn)生的相關(guān)語句.
MYSQL入門
4) 死鎖案例闡發(fā)
MYSQL入門
在該案例中process65db88, process1d0045948為語句1的進(jìn)程,process629dc8 為語句2的進(jìn)程; 語句2獲取了1689766頁上的更新鎖,在等待1686247頁上的更新鎖;而語句1則獲取了1686247頁上的更新鎖在等待1689766頁上的更新鎖,兩個語句等待的資源形成了一個環(huán)路,造成死鎖.
MYSQL入門
5) 如何辦理死鎖
MYSQL入門
針對如上死鎖案例,闡發(fā)其對應(yīng)語句執(zhí)行計劃如下:
MYSQL入門
通過執(zhí)行計劃可以看出,在查找需要更新的數(shù)據(jù)時使用的是索引掃描,比擬耗費性能,這樣就造成鎖定資源時間過長,增加了語句并發(fā)執(zhí)行時產(chǎn)生死鎖的概率.
MYSQL入門
處理方式:
MYSQL入門
1. 在表上建立一個聚集索引.
MYSQL入門
2. 對語句更新的相關(guān)字段建立包括索引.
MYSQL入門
優(yōu)化后該語句執(zhí)行計劃如下:
MYSQL入門
優(yōu)化后的執(zhí)行計劃使用了索引查找,將大幅提升該查詢語句的性能,降低了鎖定資源的時間,同時也減少了鎖定資源的范圍,這樣就降低了鎖資源循環(huán)等待事件發(fā)生的概率,對于預(yù)防死鎖的發(fā)生會有必定的作用.
MYSQL入門
死鎖是無法完全避免的,但如果應(yīng)用程序適當(dāng)處理死鎖,對涉及的任何用戶及系統(tǒng)別的部分的影響可降至最低(適當(dāng)處理是指發(fā)生錯誤1205時,應(yīng)用程序重新提交批處理,第二次嘗試大多能成功.一個進(jìn)程被殺死,它的事務(wù)被取消,它的鎖被釋放,死鎖中涉及到的另一個進(jìn)程就可以完成它的工作并釋放鎖,所以就不具備產(chǎn)生另一個死鎖的條件了.)
MYSQL入門
四、 如何預(yù)防死鎖
MYSQL入門
阻止死鎖的途徑就是避免滿足死鎖條件的情況發(fā)生,為此我們在開發(fā)的過程中必要遵循如下原則:
MYSQL入門
1.盡量避免并發(fā)的執(zhí)行涉及到修改數(shù)據(jù)的語句.
MYSQL入門
2.要求每一個事務(wù)一次就將所有要使用到的數(shù)據(jù)全部加鎖,不然就不允許執(zhí)行.
MYSQL入門
3.預(yù)先規(guī)定一個加鎖順序,所有的事務(wù)都必須依照這個順序?qū)?shù)據(jù)執(zhí)行封鎖.如不同的過程在事務(wù)內(nèi)部對對象的更新執(zhí)行順序應(yīng)盡量保證一致.
MYSQL入門
4.每個事務(wù)的執(zhí)行時間弗成太長,對程序段的事務(wù)可考慮將其分割為幾個事務(wù).在事務(wù)中不要求輸入,應(yīng)該在事務(wù)之前得到輸入,然后快速執(zhí)行事務(wù).
MYSQL入門
5.使用盡可能低的隔離級別.
MYSQL入門
6.數(shù)據(jù)存儲空間離散法.該方法是指采用各種手段,將邏輯上在一個表中的數(shù)據(jù)分散的若干離散的空間上去,以便改善對表的訪問性能.主要通過將大表按行或者列分解為若干小表,或者依照不同的用戶群兩種方法實現(xiàn).
MYSQL入門
7.編寫應(yīng)用法式,讓進(jìn)程持有鎖的時間盡可能短,這樣其它進(jìn)程就不必花太長的時間等待鎖被釋放.
MYSQL入門
維易PHP培訓(xùn)學(xué)院每天發(fā)布《Mysql必讀MSSQL產(chǎn)生死鎖的根本原因及解決方法》等實戰(zhàn)技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養(yǎng)人才。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/11954.html