您好,登錄后才能下訂單哦!
如何深入解析mssql在高頻高并發訪問時鍵查找死鎖問題,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
死鎖對于DBA或是數據庫開發人員而言并不陌生,它的引發多種多樣,一般而言,數據庫應用的開發者在設計時都會有一定的考量進而盡量避免死鎖的產生.但有時因為一些特殊應用場景如高頻查詢,高并發查詢下由于數據庫設計的潛在問題,一些不易捕捉的死鎖可能出現從而影響業務.這里為大家介紹由于設計問題引起的鍵查找死鎖及相關的解決辦法.
這里我們在測試的同時開啟trace profiler跟蹤死鎖視圖(locks:deadlock graph).(當然也可以開啟跟蹤標記,或者應用擴展事件(xevents)等捕捉死鎖)
創建測試對象code
create table testklup(clskey int not null,nlskey int not null,cont1 int not null,cont2 char(3000))create unique clustered index inx_cls on testklup(clskey)create unique nonclustered index inx_nlcs on testklup(nlskey) include(cont1)insert into testklup select 1,1,100,'aaa'insert into testklup select 2,2,200,'bbb'insert into testklup select 3,3,300,'ccc'
開啟會話1 模擬高頻update操作
----模擬高頻update操作
declare @i intset @i=100while 1=1 begin update testklup set cont1=@i where clskey=1 set @i=@i+1 end
開啟會話2 模擬高頻select操作
----模擬高頻select操作
declare @cont2 char(3000)while 1=1begin select @cont2=cont2 from testklup where nlskey=1end
此時開啟會話2執行一小段時間時我們就可以看到類似錯誤信息:圖1-1
圖1-1
而在我們開啟的跟蹤中捕捉到了如下的死鎖圖.圖1-2
圖1-2
死鎖分析:可以看出由于讀進程(108)請求寫進程(79)持有的X鎖被阻塞的同時,寫進程(79)又申請讀進程(108)鎖持有的S鎖.讀執行計劃圖1-3,寫執行計劃圖1-4
(由于在默認隔離級別下(讀提交)讀申請S鎖只是瞬間過程,讀完立即釋放,不會等待事務完成),所以在并發,執行頻率不高的情形下不易出現.但我們模擬的高頻情況使得S鎖獲得頻率非常高,此時就出現了僅僅兩個會話,一個讀,一個寫就造成了死鎖現象.
圖1-3
圖1-4死鎖原因:讀操作中的鍵查找造成的額外鎖(聚集索引)需求
解決方案:在了解了死鎖產生的原因后,解決起來就比較簡單了.
我們可以從以下幾個方面入手.
a 消除額外的鍵查找鎖需的鎖
b 讀操作時取消獲取鎖
a.1我們可以創建覆蓋索引使select語句中的查詢列包含在指定索引中
CREATE NONCLUSTERED INDEX [inx_nlskey_incont2] ON [dbo].[testklup]([nlskey] ASC) INCLUDE ( [cont2])
a.2 根據查詢需求,分步執行,通過聚集索引獲取查詢列,避免鍵查找.
declare @cont2 char(3000)declare @clskey intwhile 1=1begin select @clskey=clskey from testklup where nlskey=1 select @cont2=cont2 from testklup where clskey=@clskeyend
b 通過改變隔離級別,使用樂觀并發模式,讀操作時源行無需鎖
declare @cont2 char(3000)while 1=1begin select @cont2=cont2 from testklup with(nolock) where nlskey=1end
看完上述內容,你們掌握如何深入解析mssql在高頻高并發訪問時鍵查找死鎖問題的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。