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:
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:
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).
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:
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 aconteceuPor 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é 🙂