Uma vez por semana, tenho que resolver uma cadeia de bloqueio em um banco de dados do SQL Server 2005, causada por um bloqueio de leitura de longa duração de um front-end do Access 2003. O bloqueio é retirado sempre que um usuário abre um determinado formulário e é liberado quando o usuário termina de rolar o formulário ou fechá-lo. Como muitos de nossos usuários abrem este formulário como referência, esses bloqueios ficam por um tempo. Qualquer atualização na tabela causa o bloqueio e, de repente, ninguém pode selecionar nessa tabela, pois todos aguardam o primeiro bloqueio. Isso é um problema para nós, pois muitos aplicativos dependem desses dados. Entendo que esse comportamento de bloqueio faz parte de como o Access funciona com tabelas vinculadas.
Resolvi o problema no Activity Monitor, matando qualquer processo SELECT que seja o Head Blocker sempre que eu descobrir. Esse é um problema não apenas porque levo tempo para fazê-lo manualmente, mas também porque é reativo. No momento em que soube disso, já havia sido um problema para muitas pessoas.
Gostaria de saber se existe uma maneira automática de verificar essas cadeias de bloqueio duradouras e receber um email ou resolver o problema automaticamente. A lógica parece bastante direta ("se algum processo correspondente a essa consulta SELECT estiver bloqueando por mais de um minuto, notifique-me / mate-a"), mas não sei como implementar isso com o SQL Server.
Pelo que vale a pena, acho que a solução adequada é consertar ou reescrever o aplicativo. No entanto, devido à política departamental, essa não é uma opção para os próximos meses, por isso estou procurando um paliativo.
fonte
Respostas:
Você já pensou em usar o isolamento de instantâneo ? A ativação de read_committed_snapshot no banco de dados fará com que todas as leituras (seleções) fiquem livres de bloqueios:
Nenhuma alteração de aplicativo. Algumas semânticas mudam no snapshot e seu aplicativo pode reagir de maneira estranha, mas essa é a exceção, não a norma. A grande maioria dos aplicativos não percebe diferença, apenas recebe um aumento de desempenho gratuito.
Enfim, gostaria de responder também à pergunta original : como detectar (e possivelmente matar) uma consulta de longa duração. Na verdade, o mecanismo já faz isso por você. Há um evento gerado quando um limite é passado: Classe de Eventos do Relatório de Processo Bloqueado . O limite é configurado através da opção de limite do processo bloqueado . Qualquer evento de rastreamento pode ser transformado em uma Notificação de Eventos e as notificações de eventos podem ativar procedimentos . Conecte os pontos e você terá um código ativado sob demanda que será executado quando o mecanismo detectar uma consulta que ultrapassou um limite de tempo de execução. Sem pesquisa, sem monitoramento. Observe que a notificação é assíncrona, no momento em que você a processa, a consulta pode ter sido concluída, e isso deve ser levado em consideração.
Aqui está um exemplo:
Agora, em uma nova consulta, configure a
WAITFOR
expectativa de uma notificação:E vá em frente e cause algum bloqueio. Eu usei um processo que criou uma tabela e não foi confirmado e, em outras janelas de consulta, tentei selecionar na tabela. Em 20 segundos (meu limite configurado acima), recebi o relatório de bloqueio:
Vou deixar a tarefa de agrupar isso em um processo automatizado como um exercício para o leitor. E sim, o serviço de processo de fila / / activado deve estar em
[msdb]
.fonte
Você pode criar sua própria ferramenta de monitoramento ou procurar uma solução de terceiros que possa fornecer uma para você. Se você estiver interessado em criar seu próprio, isso depende de qual versão do SQL Server você está trabalhando. Se for 2005, você poderá usar o evento de rastreamento Blocked Process Report . Se você estiver executando 2008 ou acima, sugiro usar o evento estendido equivalente, locked_process_report. Jonathan Kehayias tem um bom artigo sobre como usá-lo.
Se você estiver procurando produtos de terceiros, o SQL Monitor do software Red Gate bloqueou os alertas de processo e de longa execução incorporados.
fonte
Embora isso não resolva como notificá-lo sobre o problema, este procedimento mostrará como consultar para ver se existe algum bloqueio. Também irá gerar comandos de matar para você, se você passar o parâmetro correto.
Espero que isso te dê algumas ideias.
fonte
Eu sugiro ler o seguinte tópico do fórum do MSDN . Trata-se de bloqueio causado pelo acesso a um banco de dados do SQL Server. A sugestão é principalmente acessar as tabelas através de consultas usando a dica NOLOCK, para que isso não cause nenhum problema de bloqueio. O NOLOCK não é a melhor solução, pois pode causar outros problemas, mas reduzirá a maioria dos problemas de bloqueio.
A melhor solução seria implementar a idéia de Remus, configurar o isolamento de instantâneo em seu banco de dados. Ou implemente o nível de isolamento de captura instantânea apenas para determinadas conexões que estão causando bloqueio.
Para monitorar adequadamente seu servidor quanto a problemas de bloqueio, sugiro:
Se você deseja uma resposta proativa a esse problema, em vez de ter um trabalho a cada hora para monitorar os rastreamentos, execute-o a cada minuto e elimine qualquer sessão principal do Access de bloqueio.
fonte
Após a excelente resposta de @Remus Rusanu, realizei a tarefa do leitor de conectar o evento a um procedimento armazenado.
No meu caso, o sp gravará o xml do evento de bloqueio em uma tabela, mas você é livre para fazer o que quiser nessa posição.
Então, siga o código do Remus e crie o
queue
, theservice
e onotification
com uma simples cópia / colar de cima. Adicione assp_configure
opções e você está basicamente definido.A única coisa que resta a fazer é
queue
Assim que você ativar o SP, os eventos começarão a fluir para a sua mesa.
Eu descobri que a fila se desativa imediatamente, se o SP tiver um erro. Nesse caso, você precisa acessar o Server Studio e ativá-lo novamente no menu de contexto da entrada da fila (
[msdb]->Service Broker->Warteschlangen
na versão em alemão).Levei algum tempo para que isso funcionasse e para encontrar os pontos certos na documentação, então acho que isso também é útil para outras pessoas. Estou usando o SQLServer 2005.
Crie o SP sem argumentos
Crie a
pdix_lock_events
tabelaAtive o SP no
queue
fonte