Sqlserver2008行版本控制解決阻塞

ai3707發表於2016-01-12
    公司有一個跑了N年的OLTP系統,使用的是sqlserver2008資料庫,由於之前運維sqlserver的經驗較少,權當oracle的方式在運維,資料庫本身也並沒做過什麼最佳化,只是給了很大的記憶體;有一次突然使用者反饋系統使用緩慢、卡死,於是先檢視應用伺服器日誌,發現後臺頻繁刷報錯日誌:

     死鎖的典型報錯,於是檢視資料庫的阻塞情況,透過sqlserver2008的活動監視器發現,資料庫阻塞嚴重,等待型別均為等待獲取S共享鎖,被阻塞的SQL均為select

    於是就奇怪了,查詢為什麼會執行這麼久呢? 根據以往經驗查詢語句不會加鎖,難道是查詢SQL的效能太差了需要最佳化?於是抓取資料庫中執行時間久的SQL,抓到了幾條然後又建了索引,單條SQL跑是挺快的,覺得大功告成了,這時一看資料庫效能資料,發現仍然阻塞嚴重,使用者還是一直叫卡~~~,看來思路錯了,這時繼續在監視器中檢視阻塞最久的會話的阻塞者ID,發現阻塞者居然是update,也就是說update阻塞了select。
     發現這個問題以後,於是仔細的學習了下sqlserver有關MVCC和隔離級別相關知識,明白了原來在sqlserver中查詢是需要加共享鎖的,而Update需要獲取排它鎖,併發系統中在同一行記錄會產生鎖衝突,要解決這個問題可以開啟sqlserver的行版本管理,在預設的提交讀隔離級別中設定ALTER DATABASE thoms SET READ_COMMITTED_SNAPSHOT ON,開啟快照讀的功能


    如此設定,select就不會被update阻塞了,加入了行版本控制,select可以根據事務ID和每行的頭資訊讀取可見版本,是不是跟oracle的undo有異曲同工之妙哇!~
目前系統已經開啟了READ_COMMITTED_SNAPSHOT引數,資料庫會話阻塞消失,使用者反饋系統使用順暢!

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29018063/viewspace-1975432/,如需轉載,請註明出處,否則將追究法律責任。

相關文章