|
|
July 03 Use o SQL Server Profiler para identificar a causa de um deadlock. Um deadlock ocorre quando há uma dependência cíclica entre dois ou mais threads, ou processos, do mesmo conjunto de recursos dentro do SQL Server. Usando o SQL Server Profiler, é possível criar um rastreamento que registra, reproduz e exibe eventos de deadlock para análise.
Para rastrear eventos de deadlock, adicione a classe de evento Deadlock graph a um rastreamento. Essa classe de evento popula a coluna de dados TextData no rastreamento com dados XML sobre o processo e os objetos envolvidos no deadlock. O SQL Server Profiler pode extrair o documento XML para um arquivo XML de deadlock (.xdl), que pode ser examinado posteriormente no SQL Server Management Studio. Você pode configurar o SQL Server Profiler para extrair eventos Deadlock graph para um único arquivo contendo todos os eventos Deadlock graph ou para arquivos separados. Essa extração pode ser feita de qualquer uma destas formas:
- No momento da configuração do rastreamento, usando a guia Configurações de Extração de Eventos. Observe que essa guia não aparece a menos que você selecione o evento Deadlock graph na guia Seleção de Eventos.
- Usando a opção Extrair Eventos do SQL Server no menu Arquivo.
- Eventos individuais também podem ser extraídos e salvos clicando-se com o botão direito do mouse em um evento específico e escolhendo Extrair Dados de Evento.
Gráficos de deadlock
O SQL Server Profiler e o SQL Server Management Studio usam um gráfico de espera de deadlock para descrever um deadlock. O gráfico de espera de deadlock contém nós de processo, nós de recurso e bordas representando as relações entre os processos e os recursos. Os componentes dos gráficos de espera estão definidos na tabela a seguir:
- Nó de processo
-
Um thread que executa uma tarefa; por exemplo, INSERT, UPDATE ou DELETE.
- Nó de recurso
-
Um objeto de banco de dados; por exemplo, uma tabela, índice ou linha.
- Borda
-
Uma relação entre um processo e um recurso. Uma borda request ocorre quando um processo espera por um recurso. Uma borda owner ocorre quando um recurso espera por um processo. O modo de bloqueio encontra-se na descrição da borda.
Nó de processo de deadlock
Em um gráfico de espera, o nó de processo contém informações sobre o processo. A tabela a seguir explica os componentes de um processo.
| Componente |
Definição |
|
ID de processo do servidor |
Identificador de processo de servidor (SPID), um identificador atribuído pelo servidor ao processo proprietário do bloqueio. |
|
ID de lote do servidor |
Identificador de lote de servidor (SBID). |
|
ID do contexto de execução |
Identificador do contexto de execução (ECID). A ID do contexto de execução de determinado thread associado a uma SPID específica.
ECID = {0, 1, 2, 3, ...n}, onde 0 sempre representa o thread principal ou pai e {1, 2, 3, ...n} representam os subthreads. |
|
Prioridade do deadlock |
Prioridade do deadlock para o processo. Para obter mais informações sobre os valores possíveis, consulte SET DEADLOCK_PRIORITY (Transact-SQL). |
|
Log Usado |
Quantidade de espaço de log usada pelo processo. |
|
ID do Proprietário |
ID de transação para os processos que estão usando transações e, atualmente, aguardam em um bloqueio. |
|
Descritor da transação |
Ponteiro para o descritor de transação que descreve o estado da transação. |
|
Buffer de entrada |
Buffer de entrada do processo atual; define o tipo de evento e a instrução que são executados. Os valores possíveis incluem:
|
|
Instrução |
Tipo de instrução. Os valores possíveis são:
- NOP
- SELECT
- UPDATE
- INSERT
- DELETE
- Desconhecido
|
Nó de recurso de deadlock
Em um deadlock, dois processos esperam por um recurso ocupado pelo outro processo. Em um gráfico de deadlock, os recursos são exibidos como nós de recurso. Cada recurso será de um dos tipos listados em Bloqueio de granularidade e hierarquias.
Continuaremos... July 02 Ferramentas de informações sobre deadlock
Para exibir informações sobre deadlock, o Mecanismo de Banco de Dados fornece ferramentas de monitoração na forma de dois sinalizadores de rastreamento e o evento gráfico de deadlock no SQL Server Profiler.
Sinalizadores de rastreamento 1204 e 1222
Quando acontecem deadlocks, os sinalizadores de rastreamento 1204 e 1222 retornam informações captadas no log de erros SQL Server 2005. O sinalizador de rastreamento 1204 relata informações de deadlock formatadas por cada nó envolvido no deadlock. O sinalizador de rastreamento 1222 formata informações de deadlock, primeiro por processos e depois por recursos. É possível permitir que ambos os sinalizadores de rastreamento obtenham duas representações do mesmo evento de deadlock.
Além de definir as propriedades dos sinalizadores de rastreamento 1204 e 1222, a tabela a seguir também mostra suas semelhanças e diferenças.
| Propriedade |
Sinalizadores de rastreamento 1204 e 1222 |
Apenas sinalizador de rastreamento 1204 |
Apenas sinalizador de rastreamento 1222 |
|
Formato de saída |
A saída captada no log de erros do SQL Server 2005. |
Focado nos nós envolvidos no deadlock. Cada nó tem uma seção dedicada e a seção final descreve a vítima de deadlock. |
Retorna informações em um formato parecido com XML que não está em conformidade com uma definição de esquema XML (XSD). O formato tem três seções principais. A primeira seção declara a vítima de deadlock. A segunda seção descreve cada processo envolvido no deadlock. A terceira seção descreve os recursos que são sinônimos com os nós no sinalizador de rastreamento 1204. |
|
Identificando atributos |
SPID:<x> ECID:<x>. Identifica o thread de ID de processo de sistema em casos de processos paralelos. A entrada SPID:<x> ECID:0, em que <x> é substituído pelo valor SPID, representa o thread principal. A entrada SPID:<x> ECID:<y>, em que <x> é substituído pelo valor SPID e <y> é maior que 0, representa os sub-threads para o mesmo SPID.
BatchID (sbid para o sinalizador de rastreamento 1222). Identifica o lote do qual a execução de código está solicitando ou mantendo um bloqueio. Quando vários conjuntos de resultados ativos (MARS) estão desabilitados, o valor BatchID é 0. Quando MARS estão habilitados, o valor de lotes ativos é 1 para n. Se não houver lotes ativos na sessão, BatchID será 0.
Mode. Especifica o tipo de bloqueio de um determinado recurso que é solicitado, concedido ou aguardado por um thread. O Mode pode ser IS (Tentativa Compartilhada), S (Compartilhado), U (Atualização), IX (Exclusivo da Tentativa), SIX (Exclusivo da Tentativa Compartilhado) e X (Exclusivo). Para obter mais informações, consulte Modos de bloqueio .
Line # (line para o sinalizador de rastreamento 1222). Lista o número de linha no lote atual de instruções que estava sendo executado quando o deadlock aconteceu.
Input Buf (inputbuf para o sinalizador de rastreamento 1222). Lista todas as instruções no lote atual. |
Node. Representa o número de entrada na cadeia de deadlock.
Lists. O proprietário do bloqueio pode fazer parte destas listas:
- Grant List. Enumera os proprietários atuais do recurso.
- Convert List. Enumera os proprietários atuais que estão tentando converter seus bloqueios em um nível mais alto.
- Wait List. Enumera as novas solicitações de bloqueio do recurso.
Statement Type. Descreve o tipo de instrução DML (SELECT, INSERT, UPDATE ou DELETE) em que os threads têm permissões.
Victim Resource Owner. Especifica o thread participante que o SQL Server escolhe como a vítima para quebrar o ciclo de deadlock. O thread escolhido e todos os sub-threads existentes são encerrados.
Next Branch. Representa os dois ou mais sub-threads do mesmo SPID envolvidos no ciclo de deadlock. |
deadlock victim. Representa o endereço de memória físico da tarefa (consulte sys.dm_os_tasks (Transact-SQL)) selecionada como vítima de deadlock. Pode ser 0 (zero) no caso de um deadlock não resolvido. Uma tarefa que está sendo revertida não pode ser escolhida como vítima de deadlock.
executionstack. Representa o código Transact-SQL que está sendo executado no momento em que o deadlock ocorre.
priority. Representa a prioridade do deadlock. Em determinados casos, o Mecanismo de Banco de Dados pode optar por alterar a prioridade de deadlock para uma duração curta para obter uma simultaneidade melhor.
logused. Espaço de log usado pela tarefa.
owner id. A ID da transação que tem controle da solicitação.
status O estado da tarefa. Pode ser um dos seguintes valores:
- pending. Esperando por um thread de trabalho.
- runnable. Pronto para ser executado, mas esperando por um quantum.
- running. Atualmente em execução no agendador.
- suspended. A execução está suspensa.
- done. A tarefa foi concluída.
- spinloop. Esperando que um spinlock seja liberado.
waitresource. O recurso requerido pela tarefa.
waittime. O tempo em milissegundos de espera pelo recurso.
schedulerid. O agendador associado à essa tarefa. Consulte sys.dm_os_schedulers (Transact-SQL).
hostname. O nome da estação de trabalho.
isolationlevel. O nível de isolamento da transação atual.
Xactid. A ID da transação que tem controle da solicitação.
currentdb. A ID do banco de dados.
lastbatchstarted. A última vez em que um processo cliente iniciou uma execução em lote.
lastbatchcompleted. A última vez em que um processo cliente concluiu uma execução em lote.
clientoption1 e clientoption2. Defina as opções nessa conexão de cliente. Esse é um bitmask que inclui informações sobre opções normalmente controladas por instruções SET, como SET NOCOUNT e SET XACTABORT.
associatedObjectId. Representa a ID de HoBT (heap ou árvore B). |
|
Atributos do recurso |
RID. Identifica a única linha dentro de uma tabela na qual um bloqueio é mantido ou solicitado. O RID é representado como RID: db_id:file_id:page_no:row_no. Por exemplo, RID: 6:1:20789:0.
OBJECT. Identifica a tabela na qual um bloqueio é mantido ou solicitado. OBJECT é representado como OBJECT: db_id:object_id. Por exemplo, TAB: 6:2009058193.
KEY. Identifica o intervalo de chave dentro de um índice em que um bloqueio é mantido ou solicitado. KEY é representado como KEY: db_id:hobt_id (index key hash value). Por exemplo, KEY: 6:72057594057457664 (350007a4d329).
PAG. Identifica o recurso de página no qual um bloqueio é mantido ou solicitado. O PAG é representado como PAG: db_id:file_id:page_no. Por exemplo, PAG: 6:1:20789.
EXT. Identifica a estrutura de extensão. EXT é representado como EXT: db_id:file_id:extent_no. Por exemplo, EXT: 6:1:9.
DB. Identifica o bloqueio de banco de dados. DB é representado de um dos seguintes modos:
- DB: db_id
- DB: db_id[BULK-OP-DB], que identifica o bloqueio de banco de dados feito pelo banco de dados de backup.
- DB: db_id[BULK-OP-DB], que identifica o bloqueio feito pelo log de backup daquele banco de dados específico.
APP. Identifica o bloqueio feito por um recurso de aplicativo. APP é representado por APP: lock_resource. Por exemplo, APP: Formf370f478.
METADATA. Representa os recursos de metadados envolvidos em um deadlock. Como METADATA tem muitos sub-recursos, o valor retornado depende do sub-recurso envolvido no deadlock. Por exemplo, METADATA.USER_TYPE retorna user_type_id =<integer_value>. Para obter mais informações sobre os recursos e sub-recursos de METADATA, consulte sys.dm_tran_locks (Transact-SQL).
HOBT. Representa um heap ou árvore B envolvida em um deadlock. |
Nenhum exclusivo para esse sinalizador de rastreamento. |
Nenhum exclusivo para esse sinalizador de rastreamento |
Exemplo do sinalizador de rastreamento 1204
O exemplo a seguir mostra a saída quando o sinalizador de rastreamento 1204 é ativado. Neste caso, a tabela em Node 1 é um heap sem índices, e a tabela em Node 2 é um heap com índices não-clusterizados. A chave de índice em Node 2 é atualizada quando o deadlock ocorre.
|
|
Deadlock encountered .... Printing deadlock information
Wait-for graph
Node:1
RID: 6:1:20789:0 CleanCnt:3 Mode:X Flags: 0x2
Grant List 0:
Owner:0x0315D6A0 Mode: X
Flg:0x0 Ref:0 Life:02000000 SPID:55 ECID:0 XactLockInfo: 0x04D9E27C
SPID: 55 ECID: 0 Statement Type: UPDATE Line #: 6
Input Buf: Language Event:
BEGIN TRANSACTION
EXEC usp_p2
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x03A3DAD0
Mode: U SPID:54 BatchID:0 ECID:0 TaskProxy:(0x04976374) Value:0x315d200 Cost:(0/868)
Node:2
KEY: 6:72057594057457664 (350007a4d329) CleanCnt:2 Mode:X Flags: 0x0
Grant List 0:
Owner:0x0315D140 Mode: X
Flg:0x0 Ref:0 Life:02000000 SPID:54 ECID:0 XactLockInfo: 0x03A3DAF4
SPID: 54 ECID: 0 Statement Type: UPDATE Line #: 6
Input Buf: Language Event:
BEGIN TRANSACTION
EXEC usp_p1
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x04D9E258
Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380)
Victim Resource Owner:
ResType:LockOwner Stype:'OR'Xdes:0x04D9E258
Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380) |
Exemplo do sinalizador de rastreamento 1222
O exemplo a seguir mostra a saída quando o sinalizador de rastreamento 1222 é ativado. Neste caso, uma tabela é um heap sem índices, e a outra tabela é um heap com um índice não-clusterizado. Na segunda tabela, a chave de índice é atualizada quando o deadlock ocorre.
|
|
deadlock-list
deadlock victim=process689978
process-list
process id=process6891f8 taskpriority=0 logused=868
waitresource=RID: 6:1:20789:0 waittime=1359 ownerId=310444
transactionname=user_transaction
lasttranstarted=2005-09-05T11:22:42.733 XDES=0x3a3dad0
lockMode=U schedulerid=1 kpid=1952 status=suspended spid=54
sbid=0 ecid=0 priority=0 transcount=2
lastbatchstarted=2005-09-05T11:22:42.733
lastbatchcompleted=2005-09-05T11:22:42.733
clientapp=Microsoft SQL Server Management Studio - Query
hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user
isolationlevel=read committed (2) xactid=310444 currentdb=6
lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
executionStack
frame procname=AdventureWorks.dbo.usp_p1 line=6 stmtstart=202
sqlhandle=0x0300060013e6446b027cbb00c69600000100000000000000
UPDATE T2 SET COL1 = 3 WHERE COL1 = 1;
frame procname=adhoc line=3 stmtstart=44
sqlhandle=0x01000600856aa70f503b8104000000000000000000000000
EXEC usp_p1
inputbuf
BEGIN TRANSACTION
EXEC usp_p1
process id=process689978 taskpriority=0 logused=380
waitresource=KEY: 6:72057594057457664 (350007a4d329)
waittime=5015 ownerId=310462 transactionname=user_transaction
lasttranstarted=2005-09-05T11:22:44.077 XDES=0x4d9e258 lockMode=U
schedulerid=1 kpid=3024 status=suspended spid=55 sbid=0 ecid=0
priority=0 transcount=2 lastbatchstarted=2005-09-05T11:22:44.077
lastbatchcompleted=2005-09-05T11:22:44.077
clientapp=Microsoft SQL Server Management Studio - Query
hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user
isolationlevel=read committed (2) xactid=310462 currentdb=6
lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
executionStack
frame procname=AdventureWorks.dbo.usp_p2 line=6 stmtstart=200
sqlhandle=0x030006004c0a396c027cbb00c69600000100000000000000
UPDATE T1 SET COL1 = 4 WHERE COL1 = 1;
frame procname=adhoc line=3 stmtstart=44
sqlhandle=0x01000600d688e709b85f8904000000000000000000000000
EXEC usp_p2
inputbuf
BEGIN TRANSACTION
EXEC usp_p2
resource-list
ridlock fileid=1 pageid=20789 dbid=6 objectname=AdventureWorks.dbo.T2
id=lock3136940 mode=X associatedObjectId=72057594057392128
owner-list
owner id=process689978 mode=X
waiter-list
waiter id=process6891f8 mode=U requestType=wait
keylock hobtid=72057594057457664 dbid=6 objectname=AdventureWorks.dbo.T1
indexname=nci_T1_COL1 id=lock3136fc0 mode=X
associatedObjectId=72057594057457664
owner-list
owner id=process6891f8 mode=X
waiter-list
waiter id=process689978 mode=U requestType=wait | Continuaremos...June 30 Quando uma instância do Microsoft SQL Server escolhe uma transação como uma vítima de deadlock, ele encerra o lote atual, reverte a transação e retorna a mensagem de erro 1205 ao aplicativo.
Como qualquer aplicativo que envia consultas Transact-SQL pode ser escolhido como vítima de deadlock, os aplicativos deverão ter um manipulador de erros que possa interceptar a mensagem de erro 1205. Se um aplicativo não interceptar o erro, o aplicativo poderá prosseguir sem saber que sua transação foi revertida e que erros podem ocorrer.
A implementação de um manipulador de erros que intercepte a mensagem de erro 1205 permite que um aplicativo manipule a situação de deadlock e tome uma ação paliativa (por exemplo, enviar automaticamente de novo a consulta que estava envolvida no deadlock). Ao enviar a consulta novamente de forma automática, o usuário não precisa saber que ocorreu um deadlock.
O aplicativo deveria pausar brevemente antes de enviar novamente a consulta. Isso dá a outra transação envolvida no deadlock uma chance para completar e liberar seus bloqueios que formaram parte do ciclo de deadlock. Diminuindo a probabilidade do deadlock ocorrer novamente quando a consulta reenviada solicitar seus bloqueios.
Minimizando deadlocks
Embora deadlocks não possam ser completamente evitados, seguir certas convenções de codificação pode minimizar a chance de gerar um deadlock. Minimizar deadlocks pode aumentar a taxa de transferência da transação e pode reduzir a sobrecarga do sistema pois poucas transações são:
- Revertidas, desfazendo todo o trabalho executado pela transação;
- Reenviadas por aplicativos pois elas foram revertidas quando bloqueadas.
Para ajudar a minimizar deadlocks:
- Acesse objetos na mesma ordem;
- Evite a interação de usuário durante as transações;
- Mantenha as transações curtas e em um lote
- Use um nível de isolamento inferior;
- Use um nível de isolamento com base em controle de versão de linha:
- Configure a opção de banco de dados READ_COMMITTED_SNAPSHOT em ON, para habilitar que as transações confirmadas por leitura utilizem controle de versão de linha;
- Use transação de isolamento;
- Use associações de saída.
Continuaremos... June 26 Detectando e encerrando deadlocks
Um deadlock acontece quando duas ou mais tarefas bloqueiam uma à outra permanentemente, sendo que cada uma tem o bloqueio de um recurso que a outra tarefa está tentando bloquear. O seguinte gráfico apresenta uma exibição de alto nível de um estado de deadlock em que:
- A tarefa T1 tem um bloqueio no recurso R1 (indicado pela seta de R1 para T1) e solicitou um bloqueio no recurso R2 (indicado pela seta de T1 para R2).
- A tarefa T2 tem um bloqueio no recurso R2 (indicado pela seta de R2 a T2) e solicitou um bloqueio no recurso R1 (indicado pela seta de T2 a R1).
- Como nenhuma tarefa pode continuar até que um recurso esteja disponível e nenhum recurso pode ser liberado até que uma tarefa continue, ocorre um estado de deadlock.

O Mecanismo de Banco de Dados do SQL Server detecta ciclos de deadlock automaticamente dentro do SQL Server. O Mecanismo de Banco de Dados escolhe uma das sessões como vítima de deadlock e a transação atual é encerrada com um erro para quebrar o deadlock.
Recursos que podem acarretar deadlock
Cada sessão de usuário pode ter uma ou mais tarefas sendo executadas em seu nome, sendo que cada tarefa pode adquirir ou aguardar para adquirir uma variedade de recursos. Os tipos de recursos a seguir podem causar bloqueio que pode resultar em um deadlock.
- Bloqueios. A espera para adquirir bloqueios em recursos, como objetos, páginas, linhas, metadados e aplicativos pode causar deadlock. Por exemplo, a transação T1 tem um bloqueio compartilhado (S) na linha r1 e está esperando para obter um bloqueio exclusivo (X) em r2. A transação T2 tem um bloqueio compartilhado (S) na linha r1 e está esperando para obter um bloqueio exclusivo (X) em r1. Isso resulta em um ciclo de bloqueio no qual T1 e T2 esperam que uma libere os recursos bloqueados da outra.
- Threads de trabalho Uma tarefa em fila aguardando um thread de trabalho pode causar um deadlock. Se a tarefa em fila possuir recursos que estão bloqueando todos os threads de trabalhado, haverá um deadlock. Por exemplo, a sessão S1 inicia uma transação e adquire um bloqueio compartilhado (S) na linha r1 e, depois, fica suspenso. As sessões ativas em execução em todos os threads de trabalhado disponíveis estão tentando adquirir bloqueios exclusivos (X) na linha r1. Como a sessão S1 não pode adquirir um thread de trabalho, ela não pode confirmar a transação e liberar o bloqueio na linha r1. Isso resulta em um deadlock.
- Memória. Quando solicitações simultâneas estão esperando por concessões de memória que não podem ser satisfeitas com a memória disponível, pode ocorrer um deadlock. Por exemplo, duas consultas simultâneas, Q1 e Q2, são executadas como funções definidas pelo usuário que adquirem 10MB e 20MB de memória, respectivamente. Se cada consulta precisar de 30MB e a memória disponível total for de 20MB, Q1 e Q2 deverão esperar uma pela outra para liberar memória. Isso resulta em um deadlock.
- Recursos relacionados à execução de consultas paralelas Threads de coordenação, produção ou consumo associados a uma porta de troca podem bloquear um ao outro causando um deadlock, normalmente ao incluir pelo menos um outro processo que não faz parte da consulta paralela. Além disso, quando uma consulta paralela começa a ser executada, o SQL Server determina o grau de paralelismo, ou o número de threads de trabalho, com base na carga de trabalho atual. Se a carga de trabalho do sistema for alterada inesperadamente, por exemplo, quando novas consultas forem executadas no servidor ou o sistema ficar sem threads de trabalho, poderá ocorrer um deadlock.
- Recursos de vários conjuntos de resultados ativos (MARS). Esses recursos são usados para controlar a intercalação de várias solicitações ativas em MARS (consulte Ambiente de execução em lote e MARS).
- Recurso do usuário. Quando um thread está esperando por um recurso que é potencialmente controlado por um aplicativo de usuário, o recurso é considerado como externo ou recurso de usuário e é tratado como um bloqueio.
- Mutex de sessão. As tarefas que estão sendo executadas em uma sessão são intercaladas, ou seja, apenas uma tarefa pode ser executada na sessão em um determinado momento. Antes de a tarefa ser executada, deve ter acesso exclusivo ao mutex de sessão.
- Mutex de transação. Todas as tarefas que estão sendo executadas em uma transação são intercaladas, ou seja, somente uma tarefa pode ser executada na transação em um determinado momento. Antes da tarefa ser executada, deve ter acesso exclusivo ao mutex de transação.
Para que uma tarefa seja executada em MARS, ela deve adquirir o mutex da sessão. Se a tarefa estiver sendo executada em uma transação, deverá adquirir o mutex de transação. Isso garante que apenas uma tarefa esteja ativa em um determinado momento, sessão e transação. Quando os mutexes solicitados forem adquiridos, a tarefa poderá ser executada. Quando a tarefa termina, ou está no meio da solicitação, primeiro ela libera o mutex de transação e, depois, o mutex de sessão em ordem reversa de aquisição. Porém, podem ocorrer deadlocks com esses recursos. No exemplo de código a seguir, duas tarefas, solicitação de usuário U1 e solicitação de usuário U2, estão sendo executadas na mesma sessão.
|
|
U1: Rs1=Command1.Execute("insert sometable EXEC usp_someproc");
U2: Rs2=Command2.Execute("select colA from sometable"); | O procedimento armazenado que está sendo executado na solicitação U1 adquiriu o mutex de sessão. Se o procedimento armazenado levar muito tempo para ser executado, o Mecanismo de Banco de Dados presumirá que o procedimento armazenado está esperando uma entrada do usuário. A solicitação de usuário U2 está esperando pelo mutex de sessão, enquanto o usuário está esperando pelo conjunto de resultados de U2, e U1 está esperando por um recurso de usuário. Esse estado de deadlock é logicamente ilustrado como:

Continuaremos.. June 24 Um deadlock acontece quando duas ou mais tarefas bloqueiam uma à outra permanentemente, sendo que cada uma tem o bloqueio de um recurso, que a outra tarefa está tentando bloquear. Por exemplo:
- A transação A adquire um bloqueio compartilhado da linha 1.
- A transação B adquire um bloqueio compartilhado da linha 2.
- A transação A agora solicita um bloqueio exclusivo na linha 2 e é bloqueado até que a transação B termine e libere o bloqueio compartilhado que tem na linha 2.
- A transação B agora solicita um bloqueio exclusivo na linha 1 e é bloqueado até que a transação A termine e libere o bloqueio compartilhado que tem na linha 1.
A transação A não pode terminar até que a transação B termine, mas a transação B está bloqueada pela transação A. Essa condição é também chamada de dependência cíclica: a transação A tem uma dependência da transação B, e a transação B fecha o círculo tendo uma dependência da transação A.
Ambas as transações em um deadlock esperarão indefinidamente, a menos que o deadlock seja quebrado por um processo externo. O monitor de deadlock do Microsoft Mecanismo de Banco de Dados do SQL Server verifica periodicamente as tarefas que estão em um deadlock. Se o monitor detectar uma dependência cíclica, ele escolhe uma das tarefas como vítima e termina sua transação com um erro. Isso permite que a outra tarefa complete sua transação. O aplicativo com a transação que terminou com um erro pode repetir a transação, a qual normalmente é concluída depois que a outra transação em deadlock é encerrada.
Usando certas convenções de codificação em aplicativos reduz a chance de que os aplicativos causarão deadlocks. Para obter mais informações, consulte Minimizando deadlocks.
O deadlock é freqüentemente confundido com bloqueio normal. Quando uma transação solicita um bloqueio em um recurso bloqueado por outra transação, a transação solicitante espera até que o bloqueio seja liberado. Por padrão, as transações SQL Server não têm tempo limite, a menos que LOCK_TIMEOUT seja configurado. A transação solicitante é bloqueada, não em deadlock, por que ela não fez nada para bloquear a transação que deve o bloqueio. Finalmente, a transação proprietária vai terminar e liberar o bloqueio e a transação solicitante terá o bloqueio atribuído e processado.
Os deadlocks às vezes são chamados de abraço mortal.
Deadlock é uma condição que pode ocorrer em qualquer sistema com vários threads, não só em sistemas de gerenciamento de banco de dados relacional, e pode ocorrer para outros recursos, além de bloqueios de objetos em bancos de dados. Por exemplo, um thread em um sistema operacional de vários threads pode adquirir um ou mais recursos, como bloqueios de memória. Se o recurso sendo adquirido é atualmente propriedade de outro thread, o primeiro thread pode ter que esperar o thread proprietário liberar o recurso alvo. O thread em espera tem uma dependência do thread proprietário para aquele recurso em particular. Em uma instância do Mecanismo de Banco de Dados, sessões podem fazer um deadlock ao adquirir recursos que não são de banco de dados, como memória ou threads.
Na ilustração, a transação T1 tem uma dependência da transação T2 para o recurso de bloqueio de tabela Part. Da mesma forma, a transação T2 tem uma dependência da transação T1 para o recurso de bloqueio de tabela Supplier. Devido a essas dependências formarem um ciclo, há um deadlock entre as transações T1 e T2.
Os deadlocks também podem ocorrer quando uma tabela é particionada e a configuração LOCK_ESCALATION do ALTER TABLE é configurada para AUTO. Quando a LOCK_ESCALATION é configurada para AUTO, a simultaneidade aumenta ao permitir que o Mecanismo de Banco de Dados bloqueie partições de tabela no nível de HoBT em vez de no nível de TABLE. Entretanto, quando transações separadas mantêm bloqueios de partição em uma tabela e querem um bloqueio em algum lugar de outra partição de transações, isso causa um deadlock. Esse tipo de deadlock pode ser evitado configurando LOCK_ESCALATION para TABLE; embora essa configuração irá reduzir a simultaneidade forçando as atualizações extensas em uma partição a esperarem por um bloqueio de tabela.
Continuaremos...
|
|
|
|