我们有 8 个进程,每个进程通过游标处理表中的一组单独的数据,以便可以使用多个 CPU 来迭代数据。这用于数据迁移,因此此时服务器计算机未用于其他任何用途。
有时,此进程会锁定,并且 SQL 的 CPU 使用率实际上会回落到 0。这些进程中的每一个都陷入了 WAITFOR 状态,最长可达 30 秒,然后再次降至 0。我们的 SQL 或代码端没有 WAITFOR 命令,并且 SQL 不会告诉我它在活动监视器或 DMV 中等待什么。这种情况似乎更多地发生在资源规格较低的机器上,但我觉得一旦 CPU 使用率回落,SQL 最终应该停止等待 CPU。
我在这里遗漏了什么吗?我们有什么办法可以解锁这些进程吗?
WAITFOR
有时可能有点棘手。正如您可能担心的那样,您并没有真正被“封锁”在这里。WAITFOR
这些是无害的(通常 - 如果有人在事务中间放置类似 a 的东西,而您实际上在中间等待,然后看到会话 ID 导致阻塞,则不会有太大影响。)归根结底,对于您最初的问题/想法 - 肯定有东西发出了该命令。SQL Server 绝不会自行等待 - 因此某处的代码有意这样做。
活动监视器本身有时在资源消耗方面也可能有点贪婪,并且并不总是轻松地提供有关正在发生的事情的详细信息。
我建议您使用sp_whoisactive并考虑将其添加到您的 SQL Server 中,看看是否可以看到有关谁调用它的更多详细信息。有时您会看到 DBMail 正在等待它,有时您会看到 Service Broker 正在等待它。但如果没有用户抱怨,这通常是一种无害的等待,所以在这种情况下 - 我会治疗症状而不是监视器,并说“如果没有人抱怨并且这不会导致阻塞,那么可以安全地专注于其他问题”。
事实证明,这是存储过程中更深层的代码,它使用信号量来检查任务是否已完成,并且任务意外失败。
当任务失败时,没有向主应用程序返回错误,所有 8 个线程的 SQL 都陷入了无限的 WAITFOR 循环 - 所以那些说某处有 WAITFOR 的人是对的......