Banco de dados

SQL Server travando? Como diagnosticar bloqueios e deadlocks em produção

InfraCtrl·Leitura: 8 min·Banco de dados

Existe um momento específico que todo mundo que opera SQL Server em produção conhece: o sistema fica lento sem motivo aparente, as reclamações começam a chegar, e ninguém sabe dizer o que está segurando o banco. Na maioria das vezes, o culpado não é falta de hardware — é contenção. Alguém está esperando por um recurso que outra transação não soltou.

Este guia é para você achar o culpado rápido, entender o que está acontecendo e agir antes que o cliente perceba. Vamos direto ao que importa.

Bloqueio e deadlock não são a mesma coisa

A confusão mais comum começa aqui, e ela muda completamente a forma de agir.

Um bloqueio (blocking) é normal e temporário: uma transação segura um lock sobre uma linha ou tabela, e outra precisa esperar até ele ser liberado. Isso acontece o tempo todo em qualquer banco transacional. Vira problema quando a espera é longa — uma transação demorada (ou esquecida aberta) segura o recurso e forma uma fila de sessões paradas atrás dela.

Um deadlock é diferente e mais grave: duas transações seguram, cada uma, um recurso que a outra precisa, e nenhuma consegue avançar. É um impasse circular. O SQL Server detecta isso automaticamente e mata uma das transações (a "vítima") para desfazer o nó — você vê o erro 1205. Ou seja: bloqueio é espera; deadlock é impasse que o servidor resolve na marra.

Achando o bloqueio em tempo real

Quando o banco está lento agora, você quer saber quem está esperando por quem. A forma rápida é olhar as sessões ativas e a cadeia de bloqueio:

SELECT r.session_id, r.status, r.blocking_session_id, -- quem esta me segurando r.wait_type, r.wait_time, r.command, t.text AS query_texto FROM sys.dm_exec_requests AS r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t WHERE r.blocking_session_id <> 0;

A coluna blocking_session_id é o ouro aqui: ela diz qual sessão está segurando o recurso. Se várias sessões apontam para o mesmo session_id, você achou a cabeça da fila — a transação que precisa ser investigada (e, se necessário, encerrada).

Para ver o texto e o plano da sessão bloqueadora, cruze o session_id dela com sys.dm_exec_connections e sys.dm_exec_sql_text. Muitas vezes o vilão é uma transação aberta e esquecida (status sleeping com open_transaction_count > 0) — um BEGIN TRAN sem COMMIT, geralmente vindo da aplicação.

Achar depois do estrago não resolve

Rodar essa query manualmente só funciona se você estiver olhando na hora exata. O WhatsDBA vigia isso 24/7 e te avisa no WhatsApp em menos de 60 segundos quando um bloqueio passa do limite — com o SPID, a query e o contexto já prontos.

Conhecer o WhatsDBA ↗

Capturando deadlocks (que já passaram)

Deadlock é traiçoeiro porque some sozinho: o servidor mata a vítima e a vida segue — até a aplicação começar a retornar erro 1205 para o usuário. Como o evento é instantâneo, você precisa de captura passiva.

A boa notícia: desde o SQL Server 2012, existe uma sessão de Extended Events padrão chamada system_health que já grava o grafo de todos os deadlocks — sem você configurar nada. Para listá-los:

SELECT xed.value('@timestamp','datetime2') AS quando, xed.query('.') AS deadlock_graph FROM ( SELECT CAST(target_data AS XML) AS tdx FROM sys.dm_xe_session_targets st JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address WHERE s.name = 'system_health' AND st.target_name = 'ring_buffer' ) AS src CROSS APPLY tdx.nodes('//RingBufferTarget/event[@name="xml_deadlock_report"]') AS q(xed);

O deadlock graph mostra as duas transações, os recursos que cada uma segurava e qual foi escolhida como vítima. É a partir dele que você entende o padrão — e quase sempre o padrão se repete.

As causas mais comuns (e o que fazer)

Depois de diagnosticar centenas desses casos, a maioria cai em poucos padrões:

Como último recurso, no meio de um incidente, você pode encerrar a sessão bloqueadora com KILL <session_id>. É um estancamento, não uma cura: se o padrão volta amanhã, o problema está no código ou no índice, não na sessão.

O que separa quem apaga incêndio de quem previne

A diferença entre uma operação madura e uma reativa não é saber rodar essas queries — é não precisar estar olhando para saber que algo travou. Quem previne tem observabilidade contínua, alerta que chega antes do cliente reclamar, e um histórico que mostra se o problema está melhorando ou piorando ao longo do tempo.

É exatamente para fechar essa lacuna que criamos o WhatsDBA e que a InfraCtrl opera banco de dados como serviço: transformar o "descobrimos pelo cliente" em "fomos avisados e já resolvemos".

Seu banco de dados é uma caixa-preta?

Faça um diagnóstico gratuito. A gente olha sua operação de verdade e mostra onde estão os riscos — sem compromisso.

Diagnóstico gratuito