Temos 8 processos, cada um processando um conjunto separado de dados de uma tabela via cursor, para que várias CPUs possam ser usadas para iterar pelos dados. Isso é usado para migração de dados, portanto, neste ponto, a máquina do servidor não está sendo usada para mais nada.
Ocasionalmente, esse processo trava com o SQL voltando para efetivamente 0 uso da CPU. Cada um desses processos fica preso no estado WAITFOR, subindo até 30 segundos e voltando para 0 novamente. Não temos o comando WAITFOR em nosso SQL ou no lado do código, e o SQL não me diz o que está esperando no Activity Monitor ou nos DMVs. Parece acontecer mais em máquinas com recursos de menor especificação, mas sinto que o SQL deve eventualmente parar de esperar pela CPU quando o uso da CPU diminuir.
Estou faltando alguma coisa aqui, existe alguma maneira de desbloquear esses processos?
WAITFOR
pode ser um pouco complicado às vezes. Você não está realmente "bloqueado" aqui como pode temer. Eles são inofensivos (geralmente - nem tanto se alguém estiver colocando algo comoWAITFOR
no meio de uma transação e você estiver realmente esperando no meio e vendo o ID da sessão causar bloqueio).No final do dia, para suas perguntas/pensamentos iniciais - algo está definitivamente emitindo esse comando. O SQL Server nunca espera por isso sozinho - então o código em algum lugar está fazendo isso intencionalmente.
O próprio monitor de atividades às vezes também pode ser um pouco fraco no consumo de recursos e nem sempre fornece grandes detalhes facilmente sobre o que está acontecendo.
Eu sugiro que você use sp_whoisactive e considere adicioná-lo ao seu SQL Server e veja se consegue ver mais detalhes sobre quem está chamando isso. Às vezes você verá o DBMail esperando por ele, às vezes você verá o Service Broker esperando por ele. Mas isso geralmente é uma espera inofensiva se nenhum usuário estiver reclamando, então neste caso - eu trataria os sintomas em vez do monitor e diria "se ninguém estiver reclamando e isso não estiver causando bloqueio, é seguro focar em outros problemas ."
Acabou sendo um código mais profundo dentro de um procedimento armazenado que usava um semáforo para verificar se uma tarefa havia sido concluída e se a tarefa estava falhando inesperadamente.
Quando a tarefa falhou, sem gerar um erro de volta ao aplicativo principal, o SQL para todos os 8 threads ficou preso em um loop WAITFOR interminável - então as pessoas que disseram que havia um WAITFOR em algum lugar estavam certas...