官方定義如下:兩個(gè)事務(wù)都持有對(duì)方需要的鎖,并且在等待對(duì)方釋放,并且雙方都不會(huì)釋放自己的鎖。

十余年的靈臺(tái)網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整靈臺(tái)建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“靈臺(tái)網(wǎng)站設(shè)計(jì)”,“靈臺(tái)網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
這個(gè)就好比你有一個(gè)人質(zhì),對(duì)方有一個(gè)人質(zhì),你們倆去談判說換人。你讓對(duì)面放人,對(duì)面讓你放人。
看到這里,也許你會(huì)有這樣的疑問,事務(wù)和談判不一樣,為什么事務(wù)不能使用完鎖之后立馬釋放呢?居然還要操作完了之后一直持有鎖?這就涉及到 MySQL 的并發(fā)控制了。
MySQL的并發(fā)控制有兩種方式,一個(gè)是 MVCC,一個(gè)是兩階段鎖協(xié)議。那么為什么要并發(fā)控制呢?是因?yàn)槎鄠€(gè)用戶同時(shí)操作 MySQL 的時(shí)候,為了提高并發(fā)性能并且要求如同多個(gè)用戶的請(qǐng)求過來之后如同串行執(zhí)行的一樣( 可串行化調(diào)度 )。具體的并發(fā)控制這里不再展開。咱們繼續(xù)深入討論兩階段鎖協(xié)議。
官方定義:
對(duì)應(yīng)到 MySQL 上分為兩個(gè)階段:
就是說呢,只有遵循兩段鎖協(xié)議,才能實(shí)現(xiàn) 可串行化調(diào)度 。
但是兩階段鎖協(xié)議不要求事務(wù)必須一次將所有需要使用的數(shù)據(jù)加鎖,并且在加鎖階段沒有順序要求,所以這種并發(fā)控制方式會(huì)形成死鎖。
MySQL有兩種死鎖處理方式:
由于性能原因,一般都是使用死鎖檢測(cè)來進(jìn)行處理死鎖。
死鎖檢測(cè)的原理是構(gòu)建一個(gè)以事務(wù)為頂點(diǎn)、鎖為邊的有向圖,判斷有向圖是否存在環(huán),存在即有死鎖。
檢測(cè)到死鎖之后,選擇插入更新或者刪除的行數(shù)最少的事務(wù)回滾,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段來判斷。
MySQL如何處理死鎖
mysql一般不會(huì)死鎖,除非程序有問題。性能優(yōu)先事務(wù)不優(yōu)先的數(shù)據(jù)庫(設(shè)置)不要追求可靠性萬無一失。
網(wǎng)站性能問題主要是數(shù)據(jù)庫量大了以后,查詢掃描硬盤而產(chǎn)生的。其它性能不要太在意。編寫代碼的時(shí)候不要堅(jiān)持性能原則,而是堅(jiān)持可用性原則。初學(xué)者編寫代碼通常容易面向性能,但是一個(gè)項(xiàng)目的一個(gè)頁面幾百、幾千行代碼是很常見的。要面向可用性、可維護(hù)性、可讀性。這是項(xiàng)目原則。你看看java語言。對(duì)于網(wǎng)站,除了查詢掃描硬盤而產(chǎn)生的時(shí)間延遲,其它是不管的,只要不算有問題就可以。
連接方式是否為永久連接,在訪問量未達(dá)到高并發(fā)之前,還是非永久鏈接更好。非永久連接的資源消耗是不大于永久連接的,因?yàn)閙ysql是把連接權(quán)限緩存的,不會(huì)多次掃描硬盤,性能是可執(zhí)行級(jí)別的而不是查找數(shù)據(jù)級(jí)別的。在訪問量達(dá)到高并發(fā)之后,性能問題的原因是多方面的,多環(huán)節(jié)的,是否為永久連接不是主要原因。
一、show ENGINE INNODB status
查看死鎖位置,分析。
二、
首先解決死鎖可以從死鎖發(fā)生的條件入手,最容易解決的就是更改獲取資源的順序;
其次是避免長(zhǎng)事務(wù),讓事務(wù)執(zhí)行的時(shí)間盡可能少,讓事務(wù)的覆蓋范圍盡可能小,長(zhǎng)事務(wù)會(huì)導(dǎo)致并發(fā)度降低,且會(huì)有更多的SQL查 詢延遲;
給整個(gè)方法加事務(wù)是否是必須的?可以不加事務(wù)的盡量不加。
一、活鎖
如果事務(wù)T1封鎖了數(shù)據(jù)R,事務(wù)T2又請(qǐng)求封鎖R,于是T2等待。T3也請(qǐng)求封鎖R,當(dāng)T1釋放了R上的封鎖之后系統(tǒng)首先批準(zhǔn)了T3的請(qǐng)求,T2仍然等待。然后T4又請(qǐng)求封鎖R,當(dāng)T3釋放了R上的封鎖之后系統(tǒng)又批準(zhǔn)了T4的請(qǐng)求,...,T2有可能永遠(yuǎn)等待,這就是活鎖的情形,如圖8.4(a)所示。
避免活鎖的簡(jiǎn)單方法是采用先來先服務(wù)的策略。
二、死鎖
如果事務(wù)T1封鎖了數(shù)據(jù)R1,T2封鎖了數(shù)據(jù)R2,然后T1又請(qǐng)求封鎖R2,因T2已封鎖了R2,于是T1等待T2釋放R2上的鎖。接著T2又申請(qǐng)封鎖R1,因T1已封鎖了R1,T2也只能等待T1釋放R1上的鎖。這樣就出現(xiàn)了T1在等待T2,而T2又在等待T1的局面,T1和T2兩個(gè)事務(wù)永遠(yuǎn)不能結(jié)束,形成死鎖。
1. 死鎖的預(yù)防
在數(shù)據(jù)庫中,產(chǎn)生死鎖的原因是兩個(gè)或多個(gè)事務(wù)都已封鎖了一些數(shù)據(jù)對(duì)象,然后又都請(qǐng)求對(duì)已為其他事務(wù)封鎖的數(shù)據(jù)對(duì)象加鎖,從而出現(xiàn)死等待。防止死鎖的發(fā)生其實(shí)就是要破壞產(chǎn)生死鎖的條件。預(yù)防死鎖通常有兩種方法:
① 一次封鎖法
一次封鎖法要求每個(gè)事務(wù)必須一次將所有要使用的數(shù)據(jù)全部加鎖,否則就不能繼續(xù)執(zhí)行。
一次封鎖法雖然可以有效地防止死鎖的發(fā)生,但也存在問題,一次就將以后要用到的全部數(shù)據(jù)加鎖,勢(shì)必?cái)U(kuò)大了封鎖的范圍,從而降低了系統(tǒng)的并發(fā)度。
② 順序封鎖法
順序封鎖法是預(yù)先對(duì)數(shù)據(jù)對(duì)象規(guī)定一個(gè)封鎖順序,所有事務(wù)都按這個(gè)順序?qū)嵭蟹怄i。
順序封鎖法可以有效地防止死鎖,但也同樣存在問題。事務(wù)的封鎖請(qǐng)求可以隨著事務(wù)的執(zhí)行而動(dòng)態(tài)地決定,很難事先確定每一個(gè)事務(wù)要封鎖哪些對(duì)象,因此也就很難按規(guī)定的順序去施加封鎖。
可見,在操作系統(tǒng)中廣為采用的預(yù)防死鎖的策略并不很適合數(shù)據(jù)庫的特點(diǎn),因此DBMS在解決死鎖的問題上普遍采用的是診斷并解除死鎖的方法。
2. 死鎖的診斷與解除
① 超時(shí)法
如果一個(gè)事務(wù)的等待時(shí)間超過了規(guī)定的時(shí)限,就認(rèn)為發(fā)生了死鎖。超時(shí)法實(shí)現(xiàn)簡(jiǎn)單,但其不足也很明顯。一是有可能誤判死鎖,事務(wù)因?yàn)槠渌蚴沟却龝r(shí)間超過時(shí)限,系統(tǒng)會(huì)誤認(rèn)為發(fā)生了死鎖。二是時(shí)限若設(shè)置得太長(zhǎng),死鎖發(fā)生后不能及時(shí)發(fā)現(xiàn)。
② 等待圖法
事務(wù)等待圖是一個(gè)有向圖G=(T,U)。 T為結(jié)點(diǎn)的集合,每個(gè)結(jié)點(diǎn)表示正運(yùn)行的事務(wù);U為邊的集合,每條邊表示事務(wù)等待的情況。若T1等待T2,則T1、T2之間劃一條有向邊,從T1指向T2。事務(wù)等待圖動(dòng)態(tài)地反映了所有事務(wù)的等待情況。并發(fā)控制子系統(tǒng)周期性地(比如每隔1分鐘)檢測(cè)事務(wù)等待圖,如果發(fā)現(xiàn)圖中存在回路,則表示系統(tǒng)中出現(xiàn)了死鎖。
DBMS的并發(fā)控制子系統(tǒng)一旦檢測(cè)到系統(tǒng)中存在死鎖,就要設(shè)法解除。通常采用的方法是選擇一個(gè)處理死鎖代價(jià)最小的事務(wù),將其撤消,釋放此事務(wù)持有的所有的鎖,使其它事務(wù)得以繼續(xù)運(yùn)行下去。當(dāng)然,對(duì)撤消的事務(wù)所執(zhí)行的數(shù)據(jù)修改操作必須加以恢復(fù)。
(看標(biāo)簽只有java和mysql的,就挑出來說了,其他方面的我也沒啥可以說的...)
運(yùn)行時(shí)發(fā)現(xiàn)死鎖:
java進(jìn)程用jstack打出堆棧看看有沒有就知道有沒有死鎖
mysql innodb的話,show engine innodb status 看看鎖持有情況也能看的出來有沒有死鎖
怎么處理:首先肯定優(yōu)先恢復(fù)服務(wù)。該回滾版本的回滾版本,該殺的殺,該重啟的重啟。
java進(jìn)程:看jstack的堆棧找到阻塞的位置,然后對(duì)著代碼分析
mysql:show engine innodb status已經(jīng)可以看的到sql以及等待什么鎖 etc.,對(duì)著分析就好,看不到sql的話可以用thread id去查mysql 的bin log查到具體執(zhí)行的sql。
避免死鎖:
我是沒什么好的辦法,只能說所有涉及到多線程操作的地方都要提高警惕,涉及到資源競(jìng)爭(zhēng)、加鎖的地方都要提高警惕,分析清楚該邏輯會(huì)不會(huì)產(chǎn)生死鎖。
條件允許的情況下可以做并發(fā)測(cè)試。
標(biāo)題名稱:怎么預(yù)防m(xù)ysql死鎖,mysql死鎖排查及解決
網(wǎng)頁網(wǎng)址:http://chinadenli.net/article38/dsgpspp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、做網(wǎng)站、虛擬主機(jī)、網(wǎng)頁設(shè)計(jì)公司、用戶體驗(yàn)、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)