Spinlock (Parte III)
Após comentar sobre os spinlock nos posts Spinlock Parte I e Parte II, agora vamos para o lado prático.
Monitorando os Spinlocks
O comando DBCC SQLPERF(SPINLOCKSTATS) não é documentado, mas auxilia na monitoração dos spinlocks. Enquanto escrevia esse post, descobri que existe uma DMV também.
SELECT * FROM sys.dm_os_spinlock_stats
O resultado será apresentado:
Impacto no Servidor
O que esperar do spinlock e qual será seu risco para o servidor? Em situações de contenção por spinlock, observa-se uma série de threads bloqueadas por um único ponto de contenção – são vários “loops infinitos” tentando obter o spinlock. Cada contenção é contabilizada como collision, sendo possível determinar o número de “rodadas” (spins) efetuada por cada thread através de spins_per_collision. O ideal é que esses números sejam ZERO – mas é tolerável (e normal) encontrar valores entre 0 e 1000.
Conforme o número de spins/collision aumenta, o servidor começa a perder mais tempo dentro do bloqueio do que executando tarefas. Nesse momento, a CPU dispara para 100% e entra em um loop infinito. Esse é um comportamento transitório de milissegundos porque, por outro lado, existe um limite máximo de spins. Quando a thread ultrapassa esse valor, ela entra entra em um estado de dormência (sleep) – denominado backoff:
Backoff – Após um alto número de spins para obter o spinlock e sem sucesso, o SQL Server coloca a thread no estado inativo durante alguns milissegundos. Durante o período de backoff, a thread deixa de executar suas tarefas e fica esperando pelo lock.
A partir do número de backoff e o tempo em dormência (sleep time), fica mais fácil compreender o impacto no desempenho do servidor. Esses contadores devem ser zero, pois qualquer outro valor indica uma contenção.
Analisando o Resultado
Se você encontrar um servidor que apresente as colunas spins, sleep time e backoff diferente de zero, não há motivos para desespero. Contenção sempre existe e para isso que servem os spinlocks.
Tenho utilizado uma estratégia de comparação entre os locks. Há estruturas em memória que apresentam mais contenção que outras, como por exemplo os Locks e Buffers.
A regra proposta é observar o número de spins/collision e backoff dos spinlocks chamados LOCK_HASH e BUF_HASH. Esses servem como baseline. Depois, procuramos por qualquer outro spinlock que apresente um maior número de spins/backoff. Esses serão os “possíveis spinlocks” com problemas.
Não há uma resolução simples para esse tipo de contenção. Normalmente, a causa está relacionada com uma limitação na arquitetura do SQL Server ou uma situação de Bug. Por isso, acredito que o DBA não tem controle sobre a situação. Seu papel é monitorar o servidor e identificar os problemas antes que se tornem críticos. Além disso, aplicar Service Pack e patches de correção podem resolver a situação.
Exemplos
Aqui seguem dois exemplos que ilustram contenção por spinlock. Nos dois casos, veja ambos ultrapassam 10000 spins/collision – chegando a quase 180000. Consequentemente, há backoff nas threads e sleep time.
1. Contenção no Spinlock MUTEX.
2. Contenção no Procedure Cache (SQL Manager)
Se alguém quiser compartilhar algum exemplo, envie o resultado do DBCC SQLPERF(SPINLOCKSTATS) e deixarei disponível a análise no blog.
Comments
Anonymous
July 20, 2010
Fabricio, Concordo com você sobre as limitações do DBA ante ao "problema de contenção SpinLock" ou por qualquer outro mecanismo de controle de threads concorrentes haja vista que a implementação do SQLOSWINSO não permite a parametrização do limite de spins para que thread possa ficar em backoff, como também não temos o "controle" sobre timming das threads. Claro, acredito que dar alguns "poderes" podem prejudicar mais o produto que ajudar. Por isso essa abstração é aceitavel. Mas seria bom se tivessemos algum documento detalhando os tipos de recursos "Spinlock Name". Assim ficando mais facil a investigação. ex: SpinLock name : XTS_MGR /* Que recurso é impactado ou que processo dentro do SQL Server e prejudicado */??? []´s Leivio FonteneleAnonymous
July 26, 2010
Muito interessante Leivio. Também tenho a mesma linha de pensamento. AbraçoAnonymous
August 09, 2010
The comment has been removed