SQL Server 為什么有時候無法殺(kill)掉一個線程(spid)


有些人可能見過一種叫做non-yielding scheduler(個人解釋:非讓步調度器程序)的現象。在這種情況下,線程正在使用處理器,並且在使用超過線程量程(4毫秒,不可更改)后不會自動退出。有一個名為調度器監視器的后台任務,它檢查SQL Server內的各種調度器上的進度,並在發現問題時發出警告。對於non-yielding Scheduler程序,你會看到錯誤17883,如下所示:

Process 56:0:0 (0xdee) Worker 0x041611F6 appears to be non-yielding on Scheduler 2.
Thread creation time: 13884536031127. Approx Thread CPU Used: kernel 18 ms, user 263 ms.
Process Utilization 0%. System Idle 98%. Interval: 331220558 ms.

可能發生這種情況的原因有很多,包括I/O子系統問題、對Windows API的緩慢調用或SQL Server錯誤。
官網解釋

在SQL Server錯誤的情況下,這是因為線程做了一些特殊處理,它能夠在不檢查4ms量程是否已經過期的情況下循環(通過調用SQLOS函數YieldAndCheckForAbort,或幾種變體之一)。如果線程不檢查量程是否已經過期,它不會知道,因此不會讓步,然后您就擁有了一個非讓步調度程序。錯誤是缺少對 YieldAndCheckForAbort 的調用。

你可能想殺死這個線程的SPID。可以運行該命令,但它可能不會執行任何操作。這是因為沒有辦法在SQL Server中'強制'終止這個線程。因為線程必須檢查它是否被要求終止,然后它終止自己(以及它在執行並行操作時可能創建的任何子線程)。猜猜這個檢查在哪里完成?在YieldAndCheckForAbort函數中!所以如果線程缺少對 YieldAndCheckForAbort 的調用,它就不會知道,所以不會終止。

這就是為什么有時無法kill掉一些線程,最終不得不重新啟動 SQL Server。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM