SQLServer會話KILL不掉,一直處於KILLED/ROLLBACK狀態情形淺析

傑克.陳發表於2018-08-03
原文:SQL Server會話KILL不掉,一直處於KILLED /ROLLBACK狀態情形淺析

今天遇到一個很奇怪的情況,發現一個會話異常,這個會話只是在執行一個簡單的儲存過程,裡面使用了連結伺服器(Linked Server)查詢另外一臺伺服器資料(儲存過程裡面沒有任何顯性事務、UPDATE、DELETE操作,只有幾個簡單的SELECT查詢,其中有兩個查詢使用了連結伺服器Linked Server,由於生產環境,不好貼出SQL語句),在DPA監控工具裡面,發現該會話引起了非常長的OLEDB等待時間,手工執行測試,發現並不耗費很長時間,KILL該會話後, 回滾狀態已完成一直是0%, 估計剩餘時間也一直是0秒。如下截圖所示:

 

KILL 129 WITH STATUSONLY; 

 

SPID 129: 正在進行事務回滾。估計回滾已完成: 0%。估計剩餘時間: 0 秒。

 

如下所示,這個會話的start_time(Timestamp when the request arrived. Is not nullable.)為2016-10-18 02:17:58.210,到現在2016-10-19 16:02:30.173已經有幾十個小時了,我kill會話的時間點為2016-10-19 12:00:01。

 

 

 

可以看到它的等待型別是OLEDB等待(圖一),也就是說等待連結伺服器所指的伺服器返回結果。另外這個事務的transaction_type為2,意味這只是一個Read-only transaction(避免別人誤解,這是一個證據),transaction_state為2,表示事務處於活動狀態(The transaction is active)。事務出現的這個時間點引起了我的注意,因為連結伺服器所指向的這臺伺服器出現當機(參考連結VmWare平臺Windows Server 2012 無響應當機),剛好是那臺伺服器虛擬機器出現當機時候,重啟的時間點前面一點(那臺伺服器凌晨1點多當機,2:22AM的時候重啟的)。從DPA監控工具也能看到確實是那個點出現的。如下所示:

 

 

這種分散式查詢,由於Linked Server所指的伺服器出現異常(例如當機),這邊的會話程式一直在等待其返回結果,但是Linked Server所指伺服器由於異常永遠都無法給這個會話程式反饋任何結果,就出現了這種情況,不過有點奇怪的是,這種情況無法通過KILL會話來結束。 只能通過重啟伺服器來解決問題, 也不能通過Kill程式解決(因為SQL Server是單程式多執行緒架構,不像ORACLE那種多程式架構,可以從作業系統層面殺掉程式或執行緒(Windows平臺,Oracle提供了一個工具ORAKILL utility 可以Kill執行緒)),但是重啟資料庫是一個很麻煩的事情。 所以這個殭屍會話就一直存在資料庫裡面,對於我這個有強迫症的人,看著它的存在,總想幹掉它. 確實是個折磨人的事情.


相關文章