sql >> Base de Datos >  >> RDS >> Sqlserver

Eliminación automática de procesos atascados en MS SQL Server

Introducción

Hay situaciones en las que las aplicaciones mantienen la conexión con la base de datos durante un largo período de tiempo. Parece que no es importante. Sin embargo, si esta aplicación hace muchas conexiones o hay varias aplicaciones con ese comportamiento, las cosas están empeorando.

Este artículo no es un tutorial. Describe posibles soluciones a este problema. Como de costumbre, estaré encantado de escuchar cualquier solución alternativa.

Solución

1. Crear un procedimiento almacenado que cierre todas las conexiones o conexiones de un determinado usuario a la base de datos especificada:

USE [DATABASE_NAME]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [srv].[KillConnect]
    @databasename nvarchar(255), -- database
    @loginname    nvarchar(255)=NULL  -- login details
AS
BEGIN
    /*
     deletes connections for the specified database and login details access
    */
    SET NOCOUNT ON;
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

    if(@databasename is null)
    begin
        ;THROW 50000, 'A database is not specified!', 0;
    end
    else
    begin
        declare @dbid int=db_id(@databasename);

        if(@dbid is NULL)
        begin
            ;THROW 50000, 'The database does not exist!', 0;
        end
        else if @dbid <= 4
        begin
            ;THROW 50000, 'To delete connections to a system database is forbidden!', 0;
        end
        else
        begin
            declare @query nvarchar(max);
            set @query = '';

            select @query=coalesce(@query,',' )
                        +'kill '
                        +convert(varchar, spid)
                        +'; '
            from master..sysprocesses
            where dbid=db_id(@databasename)
            and spid<>@@SPID
            and ([email protected] or @loginname is null);

            if len(@query) > 0
            begin
                begin try
                    exec(@query);
                end try
                begin catch
                end catch
            end
        end
    end
END

GO

Este procedimiento almacenado ayuda a deshabilitar manualmente todas las conexiones a la base de datos o a un determinado usuario para realizar más acciones con la base de datos.

2. Cree un procedimiento almacenado para eliminar todos los procesos atascados.

USE [DATABASE_NAME]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [srv].[KillFullOldConnect]
AS
BEGIN
    /*
       It deletes the connections which were executed a day ago. 
       Attention! System databases such as master, tempdb, model and msdb 
       do not take part in this process. 
       However, it does not affect database distribution for replication.
    */
    SET NOCOUNT ON;
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

    declare @query nvarchar(max);
    set @query = '';

    select @query=coalesce(@query,',' )
                +'kill '
                +convert(varchar, spid)
                +'; '
    from master..sysprocesses
    where dbid>4
    and [last_batch]<dateadd(day,-1,getdate())
    order by [last_batch]

    if len(@query) > 0
    begin
        begin try
            exec(@query);
        end try
        begin catch
        end catch
    end
END
GO

Este procedimiento almacenado elimina las conexiones que se completaron hace más de 24 horas. Además, este procedimiento no afecta a las principales bases de datos del sistema (master, tempdb, model y msdb). Si intenta acceder a una base de datos mientras la conexión está deshabilitada, se creará una nueva conexión para esta aplicación.

Ahora, es necesario ejecutar un procedimiento almacenado en la tarea del Agente una vez al día:

exec [DATABASE_NAME].[srv].[KillFullOldConnect];

Sería mejor incluir esta consulta en el bloque try-catch para procesar una posible llamada de excepciones.

Resultado

En este artículo, he analizado cómo implementar procedimientos almacenados al cerrar una conexión a una base de datos (todos o un determinado usuario) y eliminar procesos atascados en un ejemplo en particular. Además, he explorado en un ejemplo particular cómo ejecutar automáticamente una tarea en la eliminación de procesos atascados a diario. Permite disminuir una cantidad de conexiones 'muertas' a un servidor. La eliminación de todas las conexiones a la base de datos le permite modificar algunas propiedades, así como cerrar el proceso que causa cualquier problema.

Referencias:

» sysprocesses
» matar
» db_id
» @@SPID