AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 34313
Accepted
Lumpy
Lumpy
Asked: 2013-02-08 05:14:24 +0800 CST2013-02-08 05:14:24 +0800 CST 2013-02-08 05:14:24 +0800 CST

identificar bloqueio e enviar alerta

  • 772

Preciso criar um alerta que me notifique quando alguma consulta for bloqueada por mais de 60 segundos. Por exemplo, se alguém tiver uma transação aberta em uma tabela e se esquecer de executar um commit ou um rollback. Isso é possível obter das tabelas do sistema?

sql-server-2008-r2
  • 2 2 respostas
  • 11417 Views

2 respostas

  • Voted
  1. Best Answer
    db2
    2013-02-08T08:02:53+08:002013-02-08T08:02:53+08:00

    Gostei da sugestão de Martin de usar notificações de eventos, então segui seu link de exemplo e montei isso em nosso servidor. Você precisará colocar seu endereço de e-mail na chamada para sp_send_dbmail ou modificar o procedimento para ler endereços de e-mail de uma tabela de configuração de algum tipo. Além disso, ajuste o limite do processo bloqueado ao seu gosto. O resultado é uma mensagem de relatório concisa, com informações sobre os processos bloqueados e bloqueadores.

    O tratamento de erros é realmente básico; ele apenas encerra a conversa se receber uma mensagem de erro ou uma mensagem de finalização da caixa de diálogo.

    Certifique-se de que o Database Mail esteja configurado em seu sistema para permitir o uso de sp_send_dbmail.

    USE msdb
    GO
    
    EXEC sp_configure 'show advanced options', 1
    RECONFIGURE
    GO
    EXEC sp_configure 'blocked process threshold', 30
    RECONFIGURE
    GO
    
    CREATE QUEUE BlockedProcessQueue
    
    CREATE SERVICE BlockedProcessService ON QUEUE BlockedProcessQueue ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])
    GO
    
    USE master
    GO
    
    CREATE FUNCTION [dbo].[wait_resource_name](@obj nvarchar(max))
    RETURNS @wait_resource TABLE (
        wait_resource_database_name sysname,
        wait_resource_schema_name sysname,
        wait_resource_object_name sysname
    )
    AS
    BEGIN
        DECLARE @dbid int
        DECLARE @objid int
    
        IF @obj IS NULL RETURN
        IF @obj NOT LIKE 'OBJECT: %' RETURN
    
        SET @obj = SUBSTRING(@obj, 9, LEN(@obj) - 9 + CHARINDEX(':', @obj, 9))
    
        SET @dbid = LEFT(@obj, CHARINDEX(':', @obj, 1) - 1)
        SET @objid = SUBSTRING(@obj, CHARINDEX(':', @obj, 1) + 1, CHARINDEX(':', @obj, CHARINDEX(':', @obj, 1) + 1) - CHARINDEX(':', @obj, 1) - 1)
    
        INSERT INTO @wait_resource (wait_resource_database_name, wait_resource_schema_name, wait_resource_object_name)
        SELECT db_name(@dbid), object_schema_name(@objid, @dbid), object_name(@objid, @dbid)
    
        RETURN
    END
    GO
    
    CREATE PROCEDURE StartBlockedProcessNotification
    AS
    CREATE EVENT NOTIFICATION BlockedProcessNotification ON SERVER FOR BLOCKED_PROCESS_REPORT TO SERVICE 'BlockedProcessService', 'current database'
    GO
    
    EXEC sp_procoption 'StartBlockedProcessNotification', 'startup', 'on'
    EXEC StartBlockedProcessNotification
    
    USE msdb
    GO
    
    CREATE PROCEDURE BlockedProcessActivationProcedure
    AS
    
    --Service Broker
    DECLARE @message_body xml
    DECLARE @message_body_text nvarchar(max)
    DECLARE @dialog uniqueidentifier
    DECLARE @message_type nvarchar(256)
    
    WHILE 1 = 1
    BEGIN --Process the queue
        BEGIN TRANSACTION;
    
        RECEIVE TOP (1)
            @message_body = message_body,
            @dialog = conversation_handle,
            @message_type = message_type_name
        FROM BlockedProcessQueue
    
        IF @@ROWCOUNT = 0
        BEGIN
            RAISERROR('Nothing more to process', 0, 1)
            ROLLBACK TRANSACTION
            RETURN
        END
    
        IF @message_type = 'http://schemas.microsoft.com/SQL/Notifications/EventNotification'
        BEGIN
            DECLARE @mail_body nvarchar(max)
    
            DECLARE @post_time varchar(32)
            DECLARE @duration int
            DECLARE @blocked_spid int
            DECLARE @waitresource nvarchar(max)
            DECLARE @waitresource_db nvarchar(128)
            DECLARE @waitresource_schema nvarchar(128)
            DECLARE @waitresource_name nvarchar(128)
            DECLARE @blocked_hostname nvarchar(128)
            DECLARE @blocked_db nvarchar(128)
            DECLARE @blocked_login nvarchar(128)
            DECLARE @blocked_lasttranstarted nvarchar(32)
            DECLARE @blocked_inputbuf nvarchar(max)
            DECLARE @blocking_spid int
            DECLARE @blocking_hostname nvarchar(128)
            DECLARE @blocking_db nvarchar(128)
            DECLARE @blocking_login nvarchar(128)
            DECLARE @blocking_lasttranstarted nvarchar(32)
            DECLARE @blocking_inputbuf nvarchar(max)
    
            SET @post_time = CONVERT(varchar(32), @message_body.value(N'(//EVENT_INSTANCE/PostTime)[1]', 'datetime'), 109)
            SET @duration = CAST(@message_body.value(N'(//EVENT_INSTANCE/Duration)[1]', 'bigint') / 1000000 AS int)
            SET @blocked_spid = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@spid)[1]', 'int')
            SET @waitresource = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@waitresource)[1]', 'nvarchar(max)')
            SET @blocked_hostname = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@hostname)[1]', 'nvarchar(128)')
            SET @blocked_db = DB_NAME(@message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@currentdb)[1]', 'int'))
            SET @blocked_login = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@loginname)[1]', 'nvarchar(128)')
            SET @blocked_lasttranstarted = CONVERT(varchar(32), @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@lasttranstarted)[1]', 'datetime'), 109)
            SET @blocked_inputbuf = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/inputbuf)[1]', 'nvarchar(max)')
            SET @blocking_spid = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@spid)[1]', 'int')
            SET @blocking_hostname = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@hostname)[1]', 'nvarchar(128)')
            SET @blocking_db = DB_NAME(@message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@currentdb)[1]', 'int'))
            SET @blocking_login = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@loginname)[1]', 'nvarchar(128)')
            SET @blocking_lasttranstarted = CONVERT(varchar(32), @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@lasttranstarted)[1]', 'datetime'), 109)
            SET @blocking_inputbuf = @message_body.value(N'(//EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/inputbuf)[1]', 'nvarchar(max)')
    
            SELECT
                @waitresource_name = wait_resource_object_name,
                @waitresource_schema = wait_resource_schema_name,
                @waitresource_db = wait_resource_database_name
            FROM master.dbo.wait_resource_name(@waitresource)
    
            SET @mail_body = 'Posted: ' + ISNULL(@post_time, '') + CHAR(10) +
                'Duration: ' + ISNULL(CAST(@duration AS varchar) + ' s', '') + CHAR(10) +
                CHAR(10) +
                '==========Blocked Process==========' + CHAR(10) +
                'SPID: ' + ISNULL(CAST(@blocked_spid AS varchar), '') + CHAR(10) +
                'Wait Resource: ' + ISNULL(ISNULL(QUOTENAME(@waitresource_db) + '.' + QUOTENAME(@waitresource_schema) + '.' + QUOTENAME(@waitresource_name), @waitresource), '') + CHAR(10) +
                'Hostname: ' + ISNULL(@blocked_hostname, '') + CHAR(10) +
                'Current Database: ' + ISNULL(@blocked_db, '') + CHAR(10) +
                'Login Name: ' + ISNULL(@blocked_login, '') + CHAR(10) +
                'Last Transaction Started: ' + ISNULL(@blocked_lasttranstarted, '') + CHAR(10) +
                '----------Input Buffer----------' + CHAR(10) +
                ISNULL(@blocked_inputbuf, '') + CHAR(10) +
                CHAR(10) +
                '==========Blocking Process==========' + CHAR(10) +
                'SPID: ' + ISNULL(CAST(@blocking_spid AS varchar), '') + CHAR(10) +
                'Hostname: ' + ISNULL(@blocking_hostname, '') + CHAR(10) +
                'Current Database: ' + ISNULL(@blocking_db, '') + CHAR(10) +
                'Login Name: ' + ISNULL(@blocking_login, '') + CHAR(10) +
                'Last Transaction Started: ' + ISNULL(@blocking_lasttranstarted, '') + CHAR(10) +
                '----------Input Buffer----------' + CHAR(10) +
                ISNULL(@blocking_inputbuf, '') + CHAR(10)
    
            EXEC sp_send_dbmail @recipients = 'Your address here', @subject = 'Blocked Process Report', @body = @mail_body
        END
        ELSE IF @message_type IN ('http://schemas.microsoft.com/SQL/ServiceBroker/Error', 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
        BEGIN
            END CONVERSATION @dialog
        END
    
        COMMIT TRANSACTION
    END
    
    GO
    
    ALTER QUEUE BlockedProcessQueue WITH ACTIVATION (
        STATUS = ON,
        PROCEDURE_NAME = [BlockedProcessActivationProcedure],
        MAX_QUEUE_READERS = 1,
        EXECUTE AS OWNER
    )
    
    • 7
  2. Martin Smith
    2013-02-08T05:33:37+08:002013-02-08T05:33:37+08:00

    Não tenho certeza se existe alguma maneira mais fácil, mas uma maneira seria primeiro configurar o limite do processo bloqueado para 60 segundos.

    sp_configure 'show advanced options', 1 ;
    GO
    RECONFIGURE ;
    GO
    sp_configure 'blocked process threshold', 60 ;
    GO
    RECONFIGURE ;
    GO
    

    Em seguida, configure uma notificação de evento para o arquivo BLOCKED_PROCESS_REPORT. Veja esta resposta para obter um código de exemplo para notificações de eventos.

    Seu procedimento de ativação pode ser usado sp_send_dbmailpara enviar o e-mail.

    • 4

relate perguntas

  • Propriedades de redução automática, criptografia e modelo de recuperação no SQL Server 2008 R2

  • A instalação autônoma do cluster do SQL Server 2008 R2 falha com o erro - "Caracteres ilegais no caminho".

  • Migração de banco de dados grande

  • plano de manutenção executado pelo agente

  • Randomizando o conteúdo da tabela e armazenando-o de volta na tabela

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve