O Que é Deadlock SQL Server

Hoje veremos o que é deadlock sql server e como monitorar esse tipo de evento no seu banco de dados SQL Server.

Muita gente confunde deadlocks com locks e com loops infinitos, então vamos começar esclarecendo a pergunta base: o que são deadlocks?

Resumidamente, um deadlock ocorre quando o banco de dados detecta que 2 processos estão aguardando um pelo outro para continuarem suas atividades. Um deadlock pode envolver 2 ou mais processos.

Latin Fitness 2018: Summer Edition (2018) – EurekaDDL winstrol dragon pharma guida femmina di controllo orologio intelligente tracker di fitness e sorridente dopo il jogging e corridori gambe foto stock – alamy

Se o banco de dados não detectar o deadlock e eliminar um dos processos em espera, todos ficarão esperando eternamente, da mesma forma como ocorreria com os caminhões da figura abaixo:

deadlock no trânsito

Observe que o caminhão A espera pelo B, que espera pelo C, que espera pelo D, que espera pelo A! Ou seja, no final das contas, a cabine do caminhão A está esperando pela parte de traz dele mesmo! Assim como ocorre com os outros caminhões.

Ah, e a propósito, na vida real esse tipo de exemplo acontece, sabia? Veja a foto abaixo:

deadlock no trânsito vida real

O fato é, se nenhum dos caminhões do nosso exemplo “der ré”, os 4 ficarão esperando eternamente um pelo outro.

Quando o banco de dados detecta um deadlock como esse, ele cancela um dos processos (ou seja, faz um dos caminhões dar ré), para que os demais possam prosseguir (veja a animação na vídeo-aula).

deadlock no trânsito vítima

O processo cancelado é chamado de vítima do deadlock, no nosso exemplo, o caminhão A.

Com o caminho desobstruído, todos podem seguir viagem:

deadlock no trânsito desobstrução

O único problema disso, é que o processo vítima (no caso o caminhão A) fica em estado de erro, e o usuário precisará enviar novamente os comandos ao banco, pois o SQL não faz nada além de cancela-lo!

Até por conta disso, deadlocks devem ser evitados ao máximo. Não está no escopo desse artigo estudarmos como evitar deadlocks, mas quero mostrar como você pode monitora-los para análise posterior da causa raiz do incidente.

Locks vs deadlocks vs loops infinitos

Como mencionado anteriormente, muita gente confunde lock, deadlock e loop infinito.

A seguir, inclui algumas definições para ajudar no esclarecimento:

Lock

Locks ocorrem quando um processo está parando, esperando por outro que está em andamento.

Um exemplo típico seria você parado no semáforo (em lock), esperando os outros carros passarem (eles estão em andamento).

Outro exemplo, agora culinário, é o seguinte: Você vai distribuir petiscos aos convidados. Nesse momento você está com a tigela vazia, esperando seu pai terminar de cortar os petiscos para então ele colocar na tigela os pedaços e você seguir com o seu “processo de servir”.

Enquanto você espera, você está em lock, seu pai está em andamento…

Loop Infinito

Loops infinitos ocorrem devido a erro na lógica, por exemplo do seu código, que fica repetindo um trecho infinitamente por não encontrar uma condição de saída (também conhecido como condição de finalização do loop).

Exemplo: Há frases circulando na internet, muitas vezes como exemplo de deadlock, que na verdade tratam-se de loops infinitos:

– “Preciso de experiência para conseguir trabalho. Preciso de trabalho para ter experiência.”

– “Pai, posso sair? Pergunta para a sua mãe. Mãe, posso sair? Pergunte para seu pai”

Esses não são deadlock, são loops infinitos.

Seu código deveria encontrar alternativas de saída como “estágio” ou “trabalho voluntário” para o exemplo 1, ou então chamar pai e mãe e perguntar aos dois simultaneamente, para o exemplo 2.

Deadlock

Um deadlock é uma situação envolvendo múltiplos processos, onde o progresso de nenhum deles é possível devido a dependências de um pelo outro.

Em um deadlock, não há ação em andamento, todas as partes estão apenas esperando mutuamente, como no exemplo do transito que você viu acima.

Como monitorar deadlocks no SQL Server

Visto o que são deadlocks, agora vamos aprender a monitora-los no SQL Server.

Uma das formas de monitorar a ocorrência de deadlocks em seu SQL é ativando as traceflags 1204 e 1222.

Traceflags são configurações do SQL que alteram o comportamento do banco temporariamente para apoio a investigação de problemas. Mais informações aqui: https://docs.microsoft.com/pt-br/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql

Para ativar traceflags você utilizará os comandos dbcctraceon, conforme exemplo abaixo:

-- Consultar flags ativas
dbcc tracestatus(-1)

-- Ativar monitoramento de deadlocks
dbcc traceon (1204,-1)
dbcc traceon (1222,-1)

Com as traceflags ativadas, você poderá usar o script de exemplo abaixo para causar um deadlock e verificar se o SQL está de fato registrando os detalhes dos eventos de deadlock:

[sociallocker id=”5114″]


--------------------------------------------------------------
-- Monitorando Deadlocks
--------------------------------------------------------------

---------------------------------------
-- Banco de testes
---------------------------------------
use master
if db_id('curso') is not null
drop database curso
go
create database curso
go
use curso
go

---------------------------------------
-- Ativando traceflags
---------------------------------------
-- Traceflags do SQL:
-- https://docs.microsoft.com/pt-br/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql?view=sql-server-2017

-- Consultar flags ativas
dbcc tracestatus(-1)

-- Ativar monitoramento de deadlocks
dbcc traceon (1204,-1)
dbcc traceon (1222,-1)

---------------------------------------
-- Causar deadlock para testes
---------------------------------------
-- Deadlock: Concorrência de registros em 1 tabela:
if object_id('lock_table') is not null drop table lock_table
create table lock_table (id int, ds varchar(100))

-- Sessão 1:
begin transaction
insert into lock_table values (1, 'teste 1')
-- Sessão 2:
/*
begin transaction
insert into lock_table values (2, 'teste 2')
delete lock_table
rollback
*/
-- Sessão 1:
delete lock_table
--commit
rollback
go

---------------------------------------
-- Consultando logs:
---------------------------------------
if object_id('tempdb.dbo.#error_log') is not null drop table #error_log
create table #error_log (logdate datetime, processinfo varchar(1000), text varchar(max))
insert into #error_log exec xp_ReadErrorLog
select * from #error_log where logdate in (select logdate from #error_log where text like 'Deadlock encountered%')

-- clear log
exec sp_cycle_errorlog

---------------------------------------
-- Desativar monitoramento deadlocks
---------------------------------------
dbcc traceoff (1204,-1)
dbcc traceoff (1222,-1)

[/sociallocker]

CONCLUSÃO

Deadlocks as vezes são uma grande dor de cabeça para os DBAs por 3 razões:
– Ocorrem intermitentemente
– Envolvem processos que rodam independentemente um do outro
– As mensagens de erro para o usuário não dão informações completas sobre o que aconteceu

Por conta delas, saber o que é deadlock e como monitorar esse tipo de evento no SQL server é essencial para o correto diagnóstico e resolução do problema.

Espero que também tenha gostado desse conteúdo.

Abraço do seu amigo Josué 🙂

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *