Hoje experimentamos uma degradação no desempenho em nosso servidor sql de produção. Durante o tempo em que isso ocorreu, registramos vários "The query processor could not start the necessary thread resources for parallel query execution"
erros. A leitura que fiz sugere que isso tem a ver com quantas CPUs usar ao executar uma consulta complexa. No entanto, quando verifiquei durante a interrupção, nosso arquivo CPU Utilization was only at 7%
. Existe alguma outra coisa que isso poderia estar se referindo também que eu ainda não encontrei? Este é um provável culpado da degradação do desempenho ou estou perseguindo um arenque vermelho?
Meus valores sp_configure para isso são os seguintes:
name minimum maximum config_value run_value
cost threshold for parallelism 0 32767 5 5
Alguns meses atrás, enfrentei uma situação semelhante em que a configuração MAXDOP era padrão e uma consulta de fuga esgotou todos os threads de trabalho.
Como Remus apontou, isso é chamado de inanição de thread de trabalho .
Haverá um despejo de memória criado em seu servidor quando essa condição ocorrer.
Se você estiver em 2008R2 + SP1 e superior,
sys.dm_server_memory_dumps
também fornecerá o local do arquivo de despejo.Agora voltando ao problema:
Existe 1 thread de monitor de agendador por nó NUMA e, como você tem 2 nós NUMA, haverá 2 threads de monitor de agendador que são responsáveis pela verificação de integridade de todos os agendadores a cada 60 segundos para esse nó NUMA específico, certificando-se de que o agendador está travado ou não.
Cada vez que uma nova solicitação de trabalho é retirada da fila de trabalho do agendador, o contador de processos de trabalho é incrementado. Portanto, se o agendador tiver uma solicitação de trabalho enfileirada e não tiver processado uma das solicitações de trabalho em 60 segundos, o agendador será considerado travado.
Devido a uma consulta de fuga ou paralelismo extensivo, surge uma condição de threads de trabalho começarem esgotados, pois todos os threads são ocupados por essa única consulta de fuga ou bloqueio prolongado excessivo e nenhum trabalho pode ser feito a menos que o processo ofensivo seja morto.
Sua melhor aposta é primeiro ajustar sua configuração de Grau Máximo de Paralelismo . O padrão
0
significa que o SQL Server pode usar todas as CPUs disponíveis para processamento paralelo e esgotar todos os threads de trabalho.Há muitas razões que podem levar à exaustão de threads de trabalho:
Consulte minha resposta aqui que mostrará como você pode calcular o valor MAXDOP para sua instância de servidor.
Além disso, recomendo que você comece a coletar informações de estatísticas de espera sobre sua instância do servidor de banco de dados.
Pode haver várias razões. O mais provável é que você estava sem trabalhadores. Veja
max_worker_threads
. A condição é chamada de 'travamento do trabalhador'. Os trabalhadores podem ser roubados por vários meios (nenhum dos quais resultaria em alta utilização da CPU, btw), como ter muitos pedidos bloqueados ou fazer coisas estúpidas no CLR (por exemplo, solicitações HTTP).O sintoma que você vê é a vítima do problema, não a causa. Não podemos recomendar uma solução sem conhecer a causa. Você precisa coletar contadores de desempenho, DMVs e verificar o ERRORLOG para obter mais informações.