在做 SQL Server 的管理、监控、效能调校时,我们可能会执行以下的 SQL 指令,去观察 SQL Server 里的状态:
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 栏位的这几个值,代表什么意思。
“pending” (等待),代表这个 process,既沒有 Thread 可用,也沒有 CPU 可用,正在同时等待这两项系统资源。
“runnable”,代表这个 process,有 Thread 可用,但沒有 CPU 可用,所以它正在等待 CPU 这项系统资源。
“running”,代表这个 process,有 Thread 可用,有 CPU 可用。
“suspended” (暂停),代表这个 process,正在「等待」別的 process 执行,等待的系统资源可能是 Disk I/O 或数据库的 Lock。
版工注:若这个 process 执行的 SELECT 没加上 NOLOCK 关键字,而別的 process 正在进行「交易」或写入 (会加 Lock),则这个 SELECT 的 process 就会呈现 “suspended” 的状态。
“sleeping”,代表这个 process,目前没在做任何事,正在等待进一步的指令。
“dormant” (暂时搁置),代表 SQL Server 正在对这个 process 做 reset。
“background”,代表这个 process 正在 SQL Server 背景执行。 即使你看到有很多 “background” process 正在执行,也不必担心。
spin lock essentially means that query is in kind of running mode where it is busy waiting in cpu for its own turn.
下图 10 为版工实际遇到的案例。经汇报,发现有系统卡住无法动弹。 版工去 SQL Server 做检查,发现有大量的 INSERT 指令,呈现 “suspended” 状态,代表这些 process,正在「等待」別的 process 执行,等待的系统资源可能是 Disk I/O 或数据库的 Lock。
后来发现,这些被卡住的 “suspended” process,大家等的都是 session_id 为 70 的这一个 “runnable” process。
參考文章:
[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/