有些人可能見過一種叫做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。
