sql >> Database >  >> RDS >> Sqlserver

Automatische verwijdering van vastgelopen processen in MS SQL Server

Inleiding

Er zijn situaties waarin toepassingen de databaseverbinding voor een lange periode behouden. Het schijnt niet belangrijk te zijn. Als deze applicatie echter veel verbindingen maakt of als er meerdere applicaties zijn met dergelijk gedrag, wordt het erger.

Dit artikel is geen zelfstudie. Het beschrijft mogelijke oplossingen voor dit probleem. Zoals gewoonlijk hoor ik graag alternatieve oplossingen.

Oplossing

1. Maak een opgeslagen procedure die alle verbindingen of verbindingen van een bepaalde gebruiker met de opgegeven database sluit:

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

Deze opgeslagen procedure helpt bij het handmatig uitschakelen van alle verbindingen met de database of een bepaalde gebruiker voor verdere acties met de database.

2. Maak een opgeslagen procedure om alle vastgelopen processen te verwijderen.

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

Deze opgeslagen procedure verwijdert de verbindingen die meer dan 24 uur geleden zijn voltooid. Bovendien heeft deze procedure geen invloed op de belangrijkste systeemdatabases (master, tempdb, model en msdb). Als u probeert toegang te krijgen tot een database terwijl de verbinding is uitgeschakeld, wordt er een nieuwe verbinding voor deze toepassing gemaakt.

Nu is het nodig om één keer per dag een opgeslagen procedure in de Agent-taak uit te voeren:

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

Het zou beter zijn om deze vraag in het try-catch-blok te plaatsen om een ​​mogelijke oproep voor uitzonderingen te verwerken.

Resultaat

In dit artikel heb ik geanalyseerd hoe opgeslagen procedures kunnen worden geïmplementeerd bij het sluiten van een verbinding met een database (alle of een bepaalde gebruiker) en hoe vastgelopen processen op een bepaald voorbeeld kunnen worden verwijderd. Daarnaast heb ik in een bepaald voorbeeld onderzocht hoe ik dagelijks automatisch een taak op het verwijderen van vastgelopen processen kan uitvoeren. Het maakt het mogelijk om het aantal 'dode' verbindingen met een server te verminderen. Door alle verbindingen met de database te verwijderen, kunt u enkele eigenschappen wijzigen en het proces sluiten dat een probleem veroorzaakt.

Referenties:

» sysprocesses
» kill
» db_id
» @@SPID


  1. MySQL migreren naar PostgreSQL op AWS RDS, deel 3

  2. Hoe gebruiker in Superuser te veranderen in PostgreSQL

  3. Ontmoet Michal Bar en mij bij Microsoft Ignite!

  4. Een overzicht van Just-in-Time Compilation (JIT) voor PostgreSQL