sql server資料庫select產生嚴重阻塞引起效能問題

datapeng發表於2014-09-15
   今天處理了一個問題,因為sql server資料庫查詢阻塞引起的。
   首先,在資料庫上面檢視,存在大量的阻塞:
SELECT a.blocking_session_id, a.wait_duration_ms, a.session_id,b.text
FROM sys.dm_os_waiting_tasks a,
(SELECT t.text ,c.session_id 
FROM sys.dm_exec_connections c  
CROSS APPLY sys.dm_exec_sql_text (c.most_recent_sql_handle) t) b  
WHERE  a.session_id = b.session_id and a.blocking_session_id IS NOT NULL 


   從查詢的結果來看,均是select阻塞,然後對該select 語句對某個大表進行全表掃描,長時間進行,阻塞其它會話,使得資料庫效能極具下降!從活動會話分析來看,佔用了大量cpu。

   出現這種情況,主要是由於sql server的封鎖機制引起的。
   sql server的隔離級別分為兩種,這兩種隔離級別都是透過行版本控制在tempdb中生成資料的複本來解決資料的寫和讀的時候發生鎖及阻塞的問題的。不過snapshot isolation需要在資料庫中執行

ALTER DATABASE Aesop SET ALLOW_SNAPSHOT_ISOLATION ON

之後,然後在執行事務之前,設定連線的隔離級別

SET TRANSACTION ISOLATION LEVEL Snapshot;
 BEGIN TRAN
 SELECT Title
 FROM FABLE
 WHERE FableID = 2
這時候當發生第二個事務對fableid=2的行進行更新的時候,它可以進行更新,但是在更新事務提交之後,查詢事務依然是無法查到更新事務所做的修改,它還是隻能查詢到原始的資料,這種情況類似於repeatable read隔離級別,但是在repeatable read下,更新事務是無法更新的,直到查詢事務提交之後才可以。有的類似oracle的髒讀機制。
Read Committed Snapshot Isolation只是針對sqlserver預設的read committed隔離級別的。使用它需要執行如下sql:
 ALTER DATABASE Aesop SET READ_COMMITTED_SNAPSHOT ON;
如果資料庫只是普通的read committed級別下,當執行一個更新事務但沒有提交時,再執行一個對更新資料進行查詢的事務,查詢事務將無法查詢,被阻塞,但是在 READ_COMMITTED_SNAPSHOT被開啟的情況下,在上面那種情況中,查詢事務將不會被阻塞,它能夠查詢到未更新前的資料。
 Snapshot Isolation是針對SET TRANSACTION ISOLATION LEVEL Snapshot;的,在使用的時候需要在事務前設定隔離級別,而Read Committed Snapshot Isolation完全不需要使用set transaction isolation,因為它是針對資料預設的read committed隔離級別的。
 
而本資料庫是採用的off,所以才出現以上的這種情況。跟開發商溝通後,他們認為不能開啟,會影響業務!

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

相關文章