在作 SQL Server 的管理、監控、效能調校時,我們可能會執行如下的 SQL 指令,去觀察 SQL Server 裡的狀態:sql
SELECT * FROM sys.sysprocesses; EXEC sp_who2;
SELECT sqltext.TEXT, req.session_id, req.status, req.command, req.cpu_time, req.blocking_session_id, req.total_elapsed_time FROM sys.dm_exec_requests req (NOLOCK) CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext
以下圖 1,各個運做中的 process 裡,有一個 status 欄位。
而 status 欄位的值,有這幾種 : Pending, Runnable, Running, Suspended, Sleeping, Dormant, Background, Spinlock
本文是參考 SQLAuthority.com 的文章 [1],加上本身的實務經驗,解釋 status 欄位的這幾個值,表明什麼意思。
圖 1 status 欄位的值
"pending" (等待),表明這個 process,既沒有 Thread 可用,也沒有 CPU 可用,正在同時等待這兩項系統資源。 session
圖 2 Pending
"runnable",表明這個 process,有 Thread 可用,但沒有 CPU 可用,因此它正在等待 CPU 這項系統資源。spa
圖 3 Runnable
"running",表明這個 process,有 Thread 可用,有 CPU 可用。3d
圖 4 Running
"suspended" (暫停),表明這個 process,正在「等待」別的 process 執行,等待的系統資源多是 Disk I/O 或資料庫的 Lock。
版工註:若這個 process 執行的 SELECT 沒加上 NOLOCK 關鍵字,而別的 process 正在進行「交易」或寫入 (會加 Lock),則這個 SELECT 的 process 就會呈現 "suspended" 的狀態。code
圖 5 Suspended
"sleeping",表明這個 process,目前沒在作任何事,正在等待進一步的指令。orm
圖 6 Sleeping
"dormant" (暫時擱置),表明 SQL Server 正在對這個 process 作 reset。server
圖 7 Dormant
"background",表明這個 process 正在 SQL Server 背景執行。 即便你看到有不少 "background" process 正在執行,也沒必要擔心。blog
圖 8 Background
spin lock essentially means that query is in kind of running mode where it is busy waiting in cpu for its own turn. get
圖 9 Spinlock
下圖 10 為版工實際遇到的案例。 經回報,發現有系統卡住無法動彈。 版工去 SQL Server 作檢查,發現有大量的 INSERT 指令,呈現 "suspended" 狀態,表明這些 process,正在「等待」別的 process 執行,等待的系統資源多是 Disk I/O 或資料庫的 Lock。
後來發現,這些被卡住的 "suspended" process,你們等的都是 session_id 為 70 的這一個 "runnable" process。requests
圖 10 實際案例
----------------------------------------------------------------------------------------------------------------------------------------
參考文章:
[1] Sleeping vs Suspended Process
https://blog.sqlauthority.com/2020/09/10/sleeping-vs-suspended-process-sql-in-sixty-seconds-122/?fbclid=IwAR1hbs8IWBER9orsnA72lvKqD0S5mPg6ifcfUh5L4I0Ah_4WiglNswmGRKw
[2] Find Currently Running Query
https://blog.sqlauthority.com/2009/01/07/sql-server-find-currently-running-query-t-sql/----------------------------------------------------------------------------------------------------------------------------------------