Você já ouviu falar de DEADLOCK?


Olá pessoal tudo certo? Espero que sim!

 Vocês provavelmente já ouviram falar sobre deadlocks no SQL Server certo? Pois bem, no post de hoje irei explicar um pouco sobre eles, o que são, como simular um deadlock e como capturar a ocorrência dos mesmos na sua instância do SQL Server. 

O que é um deadlock? 

 Um deadlock ocorre em seu caso mais simples, quando duas sessões estão tentando adquirir um lock em um mesmo recurso, imagine que uma sessão detém um lock no recurso X e deseja adquirir um lock num recurso Y. Outra sessão possui um lock no recurso Y e deseja adquirir um lock no recurso X, neste cenário, nenhuma das sessões pode progredir e temos um deadlock, o SQL Server elimina uma das transações envolvidas através do DEADLOCK MONITOR, um dos componentes do engenho. O DEADLOCK MONITOR irá escolher como vítima a transação que custara menos para o processo de rollback considerando o que ela já executou até aquele momento. 

Simulando um deadlock 

 Crie uma base de dados com um nome de sua preferência, no meu caso a base se chama magusample: 

create database magusample
use magusample 

 Crie duas tabelas conforme abaixo nesta nova base: 

create table teste1 (col1 int)
insert into teste1 select 1

create table teste2 (col1 int)
insert into teste2 select 1 

 Na mesma sessão que foi usada para a criação da base execute o comando abaixo: 

begin tran
update teste1 set col1 = 1
--1 row updated 

 Em outra sessão, execute os comandos abaixo: 

begin tran
update teste2 set col1 = 1
update teste1 set col1 = 1
--Nada ira ser retornado 

 Volte na sessão usada para criar a base, limpe os códigos e rode a query abaixo: 

update teste2 set col1 = 1 

 Aguarde alguns segundos e o deadlock irá ocorrer: 

Msg 1205, Level 13, State 45, Line 1
Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

Capturando informações sobre os deadlocks 

 Existem algumas formas de se capturar a ocorrência de deadlocks, uma delas seria utilizando trace flags específicos, o 1204 e o 1222 (Preferível de ser utilizado no SQL 2005 e nas versões posteriores), os mesmos irão logar no errorlog a ocorrência dos deadlocks, cada um possui um nível de detalhamento do deadlock diferente, sugiro que você leia no artigo abaixo as diferenças entre eles: 


 Habilite o trace flag 1222 e simule o deadlock, você irá ver algo no errorlog parecido com o abaixo:

2013-08-13 11:09:54.230 spid18s      deadlock-list
2013-08-13 11:09:54.230 spid18s       deadlock victim=processa43e40
2013-08-13 11:09:54.230 spid18s        process-list
2013-08-13 11:09:54.230 spid18s         process id=processa43e40 taskpriority=0 logused=132 waitresource=RID: 17:1:200:0 waittime=777 ownerId=41178487 transactionname=user_transaction lasttranstarted=2013-08-13T11:09:45.700 XDES=0x5b9fbd8 lockMode=U schedulerid=4 kpid=12904 status=suspended s
2013-08-13 11:09:54.230 spid18s          executionStack
2013-08-13 11:09:54.230 spid18s           frame procname=adhoc line=1 stmtstart=16 sqlhandle=0x02000000f3bf4403840529446d8b4da8aeef25afee8e475c
2013-08-13 11:09:54.230 spid18s      UPDATE [teste2] set [col1] = @1    
2013-08-13 11:09:54.230 spid18s           frame procname=adhoc line=1 sqlhandle=0x02000000cb7b680d28d85f5bbdde3af4bc46eb163aff3b64
2013-08-13 11:09:54.230 spid18s      update teste2 set col1 = 1    
2013-08-13 11:09:54.230 spid18s          inputbuf
2013-08-13 11:09:54.230 spid18s      update teste2 set col1 = 1   
2013-08-13 11:09:54.230 spid18s         process id=processa29e40 taskpriority=0 logused=132 waitresource=RID: 17:1:192:0 waittime=3782 ownerId=41178505 transactionname=user_transaction lasttranstarted=2013-08-13T11:09:50.447 XDES=0x47ea9590 lockMode=U schedulerid=3 kpid=10688 status=suspended
2013-08-13 11:09:54.230 spid18s          executionStack
2013-08-13 11:09:54.230 spid18s           frame procname=adhoc line=3 stmtstart=16 sqlhandle=0x0200000039359225ab348dbc90898cfe36eb7f50891673e4
2013-08-13 11:09:54.230 spid18s      UPDATE [teste1] set [col1] = @1    
2013-08-13 11:09:54.230 spid18s           frame procname=adhoc line=3 stmtstart=80 sqlhandle=0x0200000031a2c819ff1c9ae4228f2731bb58cd43dab671db
2013-08-13 11:09:54.230 spid18s      update teste1 set col1 = 1    
2013-08-13 11:09:54.230 spid18s          inputbuf
2013-08-13 11:09:54.230 spid18s      begin tran
2013-08-13 11:09:54.230 spid18s      update teste2 set col1 = 1
2013-08-13 11:09:54.230 spid18s      update teste1 set col1 = 1   
2013-08-13 11:09:54.230 spid18s        resource-list
2013-08-13 11:09:54.230 spid18s         ridlock fileid=1 pageid=200 dbid=17 objectname=magusample.dbo.teste2 id=lock77a7dc0 mode=X associatedObjectId=72057594038845440
2013-08-13 11:09:54.230 spid18s          owner-list
2013-08-13 11:09:54.230 spid18s           owner id=processa29e40 mode=X
2013-08-13 11:09:54.230 spid18s          waiter-list
2013-08-13 11:09:54.230 spid18s           waiter id=processa43e40 mode=U requestType=wait
2013-08-13 11:09:54.230 spid18s         ridlock fileid=1 pageid=192 dbid=17 objectname=magusample.dbo.teste1 id=lock7e20e9c0 mode=X associatedObjectId=72057594038779904
2013-08-13 11:09:54.230 spid18s          owner-list
2013-08-13 11:09:54.230 spid18s           owner id=processa43e40 mode=X
2013-08-13 11:09:54.230 spid18s          waiter-list
2013-08-13 11:09:54.230 spid18s           waiter id=processa29e40 mode=U requestType=wait 

 O artigo abaixo pode te ajudar a entender as informações fornecidas na log por este trace flag: 


 A segunda forma de lidar com deadlocks seria utilizando o SQL Server Profiler, deixe iniciado um trace que colete os eventos iguais aos da imagem abaixo e simule um deadlock:

  
 Quando o deadlock ocorrer você verá uma imagem parecida com a abaixo:

 
 A terceira forma seria via Extended Events, o artigo abaixo possui um passo a passo de como se configurar este tipo de monitoração: 


 Independentemente do método usado para coletar informações sobre ocorrências de deadlocks, existe sempre a chance de que o último comando levantado em cada sessão envolvida não seja aquele que gerou os locks que estão sendo pedidos ou que estão concedidos. Nestes cenários, a coleta de um trace pode ser necessária para mostrar exatamente como as sessões se envolveram no deadlock.

 Um observação final, alguns deadlocks podem ser bastante complexos para destrinchar, às vezes nem mesmo as informações coletadas e um trace são suficientes. Nestes cenários, uma dica é conseguir figurar alguma mudança em índices que possa mudar o caminho de acesso aos dados. Para ter uma ideia melhor destas colocações, existem posts muito bons do Duncan sobre o assunto: 




 Espero que tenham gostado do post, um abraço!

Nenhum comentário:

Postar um comentário