999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

一例Sybase插入死鎖故障分析

2009-12-31 00:00:00
致富時(shí)代·上半月 2009年10期

摘 要:Sybase插入經(jīng)常會(huì)發(fā)生死鎖現(xiàn)象,通過對(duì)分析死鎖的背景,推斷出發(fā)生死鎖的原因,與它相關(guān)的流程是什么,以此提出解決死鎖問題的辦法。

關(guān)鍵詞:死鎖;Sybase;故障分析

一、死鎖的背景

近日在協(xié)助同事優(yōu)化某應(yīng)用前置程序(簡稱Y前置)以提高其處理效率的過程中,我們碰到一個(gè)奇怪的現(xiàn)象:Y應(yīng)用主機(jī)(簡稱Y主機(jī))遠(yuǎn)程對(duì)Y前置Sybase數(shù)據(jù)庫表做插入操作時(shí)出現(xiàn)死鎖,日志顯示死鎖交易的比例高達(dá)當(dāng)日交易總量的10%,可是被數(shù)據(jù)庫自動(dòng)回滾的事務(wù)處理中只有一條簡單的嵌入式插入E-SQL語句。

便于大家了解背景,簡要描述與死鎖相關(guān)的處理流程如下:

(一)Y前置通過MQ統(tǒng)一接入合作方的交易請(qǐng)求,將其插入本地Sybase數(shù)據(jù)庫的交易請(qǐng)求表;

(二)Y主機(jī)遠(yuǎn)程從Y前置交易請(qǐng)求表依次讀取請(qǐng)求,將其轉(zhuǎn)發(fā)給各一級(jí)分行前置系統(tǒng);

(三)Y主機(jī)接收各一級(jí)分行前置系統(tǒng)應(yīng)答之后,將交易處理結(jié)果遠(yuǎn)程寫入Y前置Sybase數(shù)據(jù)庫的交易應(yīng)答表;

(四)Y前置循環(huán)讀取交易應(yīng)答表,通過MQ將處理結(jié)果逐一返給合作方。

日志顯示上述過程中的第3步發(fā)生了Y主機(jī)事務(wù)死鎖,我們通過sp_help確認(rèn)了交易應(yīng)答表的鎖模式為行鎖,也就是說對(duì)行鎖表做單筆插入操作的事務(wù)竟有高發(fā)性死鎖問題。

二、INSERT怎么會(huì)死鎖

Sybase有三大類型鎖:排它鎖(X鎖)、共享鎖(S鎖)和更新鎖(U鎖),三種鎖的相容矩陣表如下所示(×表示不兼容,∨表示兼容):

Y主機(jī)插入操作出現(xiàn)死鎖,既說明插入操作占用了其他事務(wù)需要的資源,也說明插入操作沒有申請(qǐng)到其他事務(wù)未釋放的資源,可是問題是對(duì)于行鎖模式的表而言,插入E-SQL除了要申請(qǐng)X行鎖(Ex_row)外,它還要申請(qǐng)什么資源呢?

(一)初步推斷

由于生產(chǎn)環(huán)境下數(shù)據(jù)庫沒有激活“print deadlock information”的設(shè)置(激活對(duì)系統(tǒng)性能影響較大),我們不知道死鎖事務(wù)相關(guān)的其他E-SQL語句是什么,但從上述過程可以推斷:與第3步死鎖沖突的環(huán)節(jié)應(yīng)該是第4步,因?yàn)橹挥羞@兩步的處理過程涉及到了發(fā)生死鎖的交易應(yīng)答表;其次是在我們優(yōu)化Y前置應(yīng)用之前,Y主機(jī)日志中從未提示過死鎖。

在開始排查之前,我們先回顧一下對(duì)Y前置應(yīng)用所做的優(yōu)化內(nèi)容:

首先是優(yōu)化E-SQL。我們?cè)谠搼?yīng)用生產(chǎn)環(huán)境下通過人工執(zhí)行set showplan on和set noexec on,對(duì)Y前置程序中的E-SQL逐一排查,凡是執(zhí)行計(jì)劃顯示為表掃描的,根據(jù)業(yè)務(wù)情況或是補(bǔ)充E-SQL語句的查詢條件、降低查詢的執(zhí)行強(qiáng)度,或是根據(jù)查詢條件增建索引。優(yōu)化E-SQL引起死鎖的可能性不大,所以我們首先排除了它的可能。

其次是優(yōu)化游標(biāo)的處理邏輯,改動(dòng)的地方很多,它的嫌疑最大。我們?cè)趦?yōu)化代碼的時(shí)候,發(fā)現(xiàn)Y前置各處理程序的過程基本一致:

1.聲明帶WHERE條件的可修改游標(biāo)(SELECT FOR UPDA TE)

2.開始循環(huán)

3.打開游標(biāo)

4.FETCH游標(biāo)

5.修改數(shù)據(jù)(WHERE條件按交易流水號(hào)定位,未用游標(biāo)位置)

6.提交修改事務(wù)(COMMIT)

7.結(jié)束循環(huán)

8.釋放游標(biāo)

由于缺乏文檔和注釋,我們猜測(cè)重復(fù)打開游標(biāo)的原因是每次修改后確保能及時(shí)提交,但是提交事務(wù)后游標(biāo)自動(dòng)關(guān)閉了,那么只好在每次循環(huán)處理開始時(shí)重新打開它;我們看到循環(huán)前面的代碼還有被注釋掉的打開游標(biāo)操作,因此判定原作者的確想打開一次游標(biāo),只是沒能找到提交事務(wù)同時(shí)保持游標(biāo)打開狀態(tài)的辦法。

在優(yōu)化過程中,我們發(fā)現(xiàn)每當(dāng)客戶反映交易長時(shí)間沒有應(yīng)答時(shí),Y前置日志文件顯示每次打開游標(biāo)時(shí)平均有6秒的等待,由于該應(yīng)用采用的是按交易提交順序的聯(lián)機(jī)批量式處理方式,那么這樣的效率意味著排在第100筆的請(qǐng)求僅在打開游標(biāo)一項(xiàng)上就要有10分鐘的等待,這樣的效率合作方自然無法接受。

使用Sybase ASE數(shù)據(jù)庫時(shí),提交事務(wù)同時(shí)保持游標(biāo)打開狀態(tài),需要在事務(wù)開始前將close on endtran選項(xiàng)關(guān)閉,若是12.0之后的ASE還要將事務(wù)類型設(shè)置為非鏈?zhǔn)?chainned off)。

鑒于此,我們對(duì)Y前置的事務(wù)處理進(jìn)行了改進(jìn):首先設(shè)置有關(guān)保持游標(biāo)打開的選項(xiàng);然后定義可修改游標(biāo)(select for update);打開游標(biāo)之后開始循環(huán)處理:將應(yīng)答信息組織成報(bào)文通過MQ發(fā)給合作方,若發(fā)送成功則開始事務(wù),通過游標(biāo)標(biāo)記當(dāng)前記錄為已處理,再提交事務(wù);最后在循環(huán)結(jié)束后關(guān)閉并釋放游標(biāo)。

假如說Y前置優(yōu)化的程序?qū)е铝薡主機(jī)事務(wù)出現(xiàn)死鎖,我們判斷故障誘因就位于上述內(nèi)容之中。

(二)嘗試游標(biāo)只讀

難道是游標(biāo)可修改的緣故?可修改游標(biāo)意味著每次FETCH游標(biāo)時(shí)會(huì)申請(qǐng)U鎖,我們猜U鎖和插入申請(qǐng)的X鎖可能會(huì)出現(xiàn)死鎖,只讀游標(biāo)FETCH時(shí)申請(qǐng)的S鎖或許就不會(huì)沖突。

恢復(fù)系統(tǒng)正常運(yùn)行的壓力迫使我們沒有仔細(xì)推敲,直接就把可修改游標(biāo)變?yōu)榱酥蛔x,但是更換程序之后,發(fā)現(xiàn)Y主機(jī)不僅仍出現(xiàn)死鎖,死鎖占比也絲毫沒有下降。

(三)降低隔離級(jí)別

既然只讀游標(biāo)也解決不了問題,我們還剩下一個(gè)終極辦法:將Y前置負(fù)責(zé)處理交易應(yīng)答的程序事務(wù)隔離級(jí)別由默認(rèn)的3級(jí)(串行化讀)降為1級(jí)(讀已提交),一方面這樣可使E-SQL語句執(zhí)行完之后可以盡快釋放包括鎖在內(nèi)的各種臨界資源,另一方面仔細(xì)審查有關(guān)源代碼之后,我們認(rèn)為1級(jí)讀已提交的隔離級(jí)別對(duì)Y前置應(yīng)答處理過程的完整性沒有實(shí)質(zhì)影響。

假如降為1級(jí)隔離之后,Y主機(jī)仍出現(xiàn)死鎖,那么可以排除掉Y前置引起Y主機(jī)死鎖的可能性;如果降級(jí)能讓Y主機(jī)的死鎖故障消失,那么我們就贏得了時(shí)間來進(jìn)一步查找引發(fā)死鎖的根源。

當(dāng)時(shí)我意識(shí)到,如果Y前置導(dǎo)致了Y主機(jī)出現(xiàn)死鎖,那么Y主機(jī)必定也會(huì)導(dǎo)致Y前置出現(xiàn)死鎖,或許查看Y前置的運(yùn)行日志能給我們提供一些幫助,以彌補(bǔ)我們因沒有生產(chǎn)環(huán)境下的sa權(quán)限無法獲取死鎖詳細(xì)信息的不足。

事實(shí)證實(shí)了我們的假設(shè),Y前置日志清楚地表明,自該應(yīng)用上線以來游標(biāo)事務(wù)發(fā)生死鎖的提示信息連綿不絕,之前未發(fā)現(xiàn)在于Y前置事務(wù)被自動(dòng)回滾時(shí),只是未能從數(shù)據(jù)庫中取出應(yīng)答數(shù)據(jù)而已,下次操作會(huì)自動(dòng)重新取,從使用者角度根本發(fā)現(xiàn)不了故障。

目前Y主機(jī)也出現(xiàn)了死鎖,直接導(dǎo)致應(yīng)答數(shù)據(jù)無法寫入Y前置的數(shù)據(jù)庫,由于該應(yīng)用的設(shè)計(jì)沒有考慮此類異常的自動(dòng)恢復(fù),應(yīng)答數(shù)據(jù)丟失自然會(huì)產(chǎn)生單邊賬務(wù),隱藏已久的問題終于得到了暴露。

鑒于此,我們對(duì)Y前置代碼進(jìn)行了迅速更換,首先合并原來分散于前置不同程序內(nèi)返回合作方交易結(jié)果的代碼,以降低前置進(jìn)程間不必要的內(nèi)部資源爭(zhēng)用;然后在合并后的代碼中將事務(wù)隔離級(jí)別設(shè)置為1級(jí)(讀已提交),以避免占用過多的臨界資源。

經(jīng)過數(shù)日監(jiān)控,死鎖故障終于消失,而且交易高峰期間處理異常緩慢的問題一并得到了解決。

(四)追根溯源

問題雖然得到了解決,但我們并未找到原因,實(shí)際上查找死鎖原因最簡單的辦法是在生產(chǎn)系統(tǒng)上激活死鎖信息輸出選項(xiàng),這樣發(fā)生死鎖時(shí)Sybase的系統(tǒng)日志會(huì)清楚地表明死鎖相關(guān)SQL語句的執(zhí)行情況,可是我們作為開發(fā)人員沒有激活的sa權(quán)限,加之生產(chǎn)系統(tǒng)已恢復(fù)正常,再這樣做已經(jīng)沒有意義。

模擬測(cè)試也是一種解決問題的途徑,我在該應(yīng)用的開發(fā)機(jī)兼生產(chǎn)備機(jī)上,依據(jù)流程編寫了并發(fā)測(cè)試代碼,同時(shí)激活了測(cè)試數(shù)據(jù)庫的死鎖輸出選項(xiàng),可是結(jié)果令人沮喪,測(cè)試程序跑了幾天也沒有出現(xiàn)過一個(gè)死鎖,從重現(xiàn)的角度查找原因的辦法看來行不通。

既然自己實(shí)現(xiàn)不了,或許網(wǎng)上有高人的心得體會(huì)。的確,網(wǎng)上可以找到很多Sybase插入與查詢間出現(xiàn)死鎖的帖子,但多是描述全頁鎖模式下進(jìn)行插入與查詢并發(fā)操作時(shí),申請(qǐng)數(shù)據(jù)頁鎖與索引頁鎖操作之間發(fā)生死鎖的情況。

為表述清楚,我們將Sybase數(shù)據(jù)庫各種鎖模式之間鎖操作的區(qū)別列表如下:

可以看出,DataRows模式下Sybase不會(huì)鎖索引頁,Y前置的數(shù)據(jù)庫為DataRows模式,因而網(wǎng)上有關(guān)全頁鎖模式出現(xiàn)死鎖的帖子所解釋的原因顯然并不適合我們碰到的問題。不過最終我們還是在網(wǎng)上找到了一篇與情況類似的案例描述,該案例貼出了Sybase發(fā)生死鎖時(shí)的詳細(xì)日志,這正是我當(dāng)初苦苦測(cè)試尋求而未得的結(jié)果。

該案例描述的日志表明:在3級(jí)隔離級(jí)別的事務(wù)中,Sybase對(duì)于包含索引列的行鎖模式表做插入時(shí),會(huì)先申請(qǐng)數(shù)據(jù)頁X行鎖,然后申請(qǐng)下一個(gè)依主鍵序的鍵鎖(next key lock),這個(gè)next key鎖正是造成此類死鎖的誘因,也是第二節(jié)中INSERT申請(qǐng)什么資源的答案。

Sybase網(wǎng)站的有關(guān)資料表明,在3級(jí)隔離級(jí)別狀態(tài)下,使用索引條件讀取數(shù)據(jù)的游標(biāo)事務(wù)中,為防止出現(xiàn)幻讀,打開游標(biāo)時(shí)會(huì)申請(qǐng)滿足條件范圍之后下一個(gè)依主鍵序的鍵鎖(next key lock),以阻止其他事務(wù)在條件范圍后面追加記錄;另外在3級(jí)隔離下,無論游標(biāo)是否只讀,F(xiàn)ETCH操作要申請(qǐng)的數(shù)據(jù)頁行鎖都是范圍擴(kuò)張鎖,每次FETCH其申請(qǐng)到的行鎖不會(huì)立即釋放,而是隨著后續(xù)FETCH逐步蔓延,直到操作到下一個(gè)數(shù)據(jù)頁或關(guān)閉游標(biāo)時(shí),Sybase才會(huì)一并釋放之前占有的數(shù)據(jù)頁行鎖。

這樣當(dāng)FETCH導(dǎo)致范圍擴(kuò)張鎖蔓延時(shí),恰好與插入操作事務(wù)先申請(qǐng)數(shù)據(jù)頁X鎖、再申請(qǐng)next key鎖的次序相沖突,滿足了死鎖的必要條件。

三、結(jié)束語

通過探尋這次Sybase INSERT事務(wù)死鎖的始末,我充分體驗(yàn)到解決此類問題的困難。

一方面是技術(shù)上的困難。出現(xiàn)問題時(shí)僅憑數(shù)據(jù)庫和應(yīng)用程序運(yùn)行日志難以判斷故障的根本原因,測(cè)試環(huán)境難以重現(xiàn)故障現(xiàn)象、分析源代碼時(shí),往往發(fā)現(xiàn)不僅缺乏有效文檔、合理注釋,同時(shí)連原創(chuàng)人員都早已不知去向。

另一方面是協(xié)調(diào)上的困難。開發(fā)與運(yùn)維上的分離導(dǎo)致開發(fā)人員缺乏快速有效定位系統(tǒng)運(yùn)行故障的有效手段,僅僅依靠運(yùn)行日志解決不了深層次問題,很多操作都需要有系統(tǒng)權(quán)限,比如數(shù)據(jù)庫要有sa權(quán)限才能開啟死鎖信息輸出選項(xiàng)和查看執(zhí)行計(jì)劃,系統(tǒng)要有root權(quán)限才能跟蹤進(jìn)程和監(jiān)測(cè)有關(guān)資源,這些顯然是開發(fā)人員所不具備的權(quán)限,而讓運(yùn)維人員熟悉所有應(yīng)用也并不現(xiàn)實(shí),如何既能保障生產(chǎn)的安全運(yùn)行、又能方便應(yīng)急處理是我們應(yīng)該思考的問題。

主站蜘蛛池模板: 欧美高清国产| 天天综合天天综合| 伦精品一区二区三区视频| 青草娱乐极品免费视频| 一级一级特黄女人精品毛片| 99免费视频观看| 亚洲男人天堂网址| 国产成人久久综合777777麻豆 | 日韩亚洲综合在线| 国产69精品久久| 国产一在线观看| 国产呦精品一区二区三区下载| 亚洲欧美精品一中文字幕| 亚洲侵犯无码网址在线观看| 亚洲三级视频在线观看| 丝袜亚洲综合| 五月天天天色| 久草中文网| 国产精品一老牛影视频| 亚洲欧美一区二区三区蜜芽| 三上悠亚精品二区在线观看| 日韩欧美成人高清在线观看| 亚洲欧美成人网| 亚洲一道AV无码午夜福利| 国产成人盗摄精品| 免费黄色国产视频| 精品少妇人妻无码久久| 热热久久狠狠偷偷色男同| 精品国产自| 国产女人在线| 久久精品娱乐亚洲领先| 欧美一级色视频| 国产成本人片免费a∨短片| 亚洲天堂成人在线观看| 色综合天天视频在线观看| 亚洲日韩精品无码专区97| 欧美精品亚洲精品日韩专| 免费可以看的无遮挡av无码| 国产成人永久免费视频| 91精品啪在线观看国产60岁| 亚洲AⅤ永久无码精品毛片| 亚洲码在线中文在线观看| 99热这里只有成人精品国产| 午夜日b视频| 日韩午夜福利在线观看| 国产一区二区视频在线| 亚洲黄色成人| 久综合日韩| 国产三级视频网站| 精品久久久久久成人AV| 精品无码国产自产野外拍在线| 亚国产欧美在线人成| 亚洲三级色| 伊人无码视屏| 国产成人毛片| 欧美激情福利| 国产性爱网站| 欧洲高清无码在线| 999国产精品| 免费xxxxx在线观看网站| 亚洲欧美日韩动漫| 免费xxxxx在线观看网站| 亚洲美女一区| 伊人久久婷婷五月综合97色| 免费A级毛片无码无遮挡| 夜夜操国产| 99久久精彩视频| 国产一级在线观看www色| 国产在线观看精品| 又爽又大又黄a级毛片在线视频| 国产美女精品人人做人人爽| 91免费片| 免费不卡在线观看av| 国产69精品久久久久妇女| 色丁丁毛片在线观看| 免费一级无码在线网站| 欧美成人午夜视频免看| 18黑白丝水手服自慰喷水网站| 欧美成人aⅴ| AV无码无在线观看免费| 99re在线视频观看| 免费高清毛片|