Estados de uma thread no SQL Server

Fala pessoal, tudo bem?

Ainda sobre o tema de otimização de desempenho, quando precisamos fazer uma análise de performance é comum utilizarmos algumas DMV’s , como por exemplo a sys.dm_os_tasks, sys.dm_os_workers, sys.dm_os_schedulers, sys.dm_exec_sessions e a sys.dm_exec_requests.

Como eu “pulei” alguns assuntos e falei direto sobre wait nesse post aqui, preciso voltar um pouquinho e explicar sobre o estados que uma thread pode se encontrar para enteder melhor o wait.

Antes de falar sobre os estados da query, vamos falar sobre o que é uma thread?

De maneira bem simplista, uma thread é a menor unidade de execução dentro de um processo.

Também é importante citar que podem existir muitas threads dentro de um processo e cada thread recebe um pequeno tempo de processamento para ser executado até precisar esperar por um recurso ou até ser executado por um determinado período de tempo. Nesse ciclo de processamento e espera que ocorre de tempos em tempos bem curtos, uma thread libera o processador para que outras threads possam continuar e não esperar por longos períodos.

Esse processo de executar um pouco, esperar e depois executar novamente é chamado de agendamento (scheduler) e podemos consultar no sql através da dmv sys.dm_os_schedulers. O SQLOS gerencia o agendamento de threads no SQL Server e permite que threads sejam expostos à CPU. 

Esse scheduler funciona em servidores com vários processadores e threads passando a impressão de que muitas coisas estão acontecendo ao mesmo tempo, onde, na verdade em cada processador individual, apenas um thread está sendo executado por vez, mas como eles são executados por um período de tempo muito pequeno e depois outra thread é executada, faz parecer que processa muitas coisas simultaneamente.

Não vou entrar no detalhe de como funciona toda a arquitetura de task scheduling pq não é o tópico do post, então com a introdução já feita posso dizer que temos 3 estados para a execução de uma task, que são RUNNING, SUSPENDED e RUNNABLE.

Para cada requisição, uma nova thread é aberta e executada ainda no status Running, até que a espera por um recurso seja identificada ou até que atinja um limite de 4 milisegundos. Quando a thread precisa esperar por um recurso, ele passa para o estado Suspended e é adicionada na lista. Essa lista é desordenada e a qualquer momento qualquer thread pode ser notificada que o recurso foi disponibilizado, então essa thread é passada para a fila do estado Runnable. Enquanto isso, a próximo thread da fila no estado Runnable passará para o estado Running para ser executada e consumir a CPU.

Este ciclo continua até que a thread termine de executar.

O tempo que essa thread leva entre sair do estado Running e entrar novamente no estado Running é chamado de Wait Time. Dei mais detalhes sobre wait time nesse post.

O tempo que a thread leva entre sair da lista Suspensa e entrar no estado Em execução (ou seja, o tempo gasto na fila Runnable) é chamado de Signal Wait Time.

Segue uma query q pode te ajudar a verificar como as threads estão distribuídas.

SELECT
	t.scheduler_id, task_state, COUNT (*) AS task_count
FROM
	sys.dm_os_tasks AS t 
INNER JOIN	sys.dm_exec_requests AS r    ON t.session_id = r.session_id
INNER JOIN	sys.dm_exec_sessions AS s    ON r.session_id = s.session_id
WHERE	s.is_user_process = 1
GROUP BY	t.scheduler_id,	task_state
ORDER BY	task_state,	t.scheduler_id;
GO

Quando vc estiver com uma grande quantidade de tarefas no estado suspended, você pode começar avaliando os waits para entender o que pode estar engargalando seu processamento.


select
 er.session_id,
 er.status,
 er.command,
 er.blocking_session_id,
 er.wait_type,
 ot.exec_context_id,
 ot.task_state,
 st.text
from
 sys.dm_exec_requests er
 join sys.dm_os_tasks ot on (er.session_id = ot.session_id)
 cross apply sys.dm_exec_sql_text(er.sql_handle) st
where er.session_id in
 (select session_id  from sys.dm_os_tasks GROUP by session_id HAVING count(exec_context_id)>1)

Existem outros estados como background e sleeping:

SLEEPING: A sessão está esperando para fazer algo.

BACKGROUND: Processos internos do SQL Server essenciais para manter tudo funcionando.

Por enquanto é isso pessoal, qualquer dúvida pode me chamar aqui.
Abs

Deixe um comentário