sql >> Database teknologi >  >> RDS >> Sqlserver

Automatisk sletning af fastlåste processer i MS SQL Server

Introduktion

Der er situationer, hvor applikationer bevarer databaseforbindelsen i lang tid. Det ser ud til at være ikke vigtigt. Men hvis denne applikation skaber mange forbindelser, eller der er flere applikationer med sådan adfærd - bliver tingene værre.

Denne artikel er ikke en tutorial. Den beskriver mulige løsninger på dette problem. Som sædvanlig vil jeg være glad for at høre eventuelle alternative løsninger.

Løsning

1. Opret en lagret procedure, der lukker alle forbindelser eller forbindelser fra en bestemt bruger til den angivne database:

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

Denne lagrede procedure hjælper med manuelt at deaktivere alle forbindelser til databasen eller en bestemt bruger for yderligere handlinger med databasen.

2. Opret en lagret procedure for at fjerne alle fastlåste processer.

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

Denne lagrede procedure fjerner de forbindelser, der blev afsluttet for mere end 24 timer siden. Derudover påvirker denne procedure ikke hovedsystemets databaser (master, tempdb, model og msdb). Hvis du forsøger at få adgang til en database, mens forbindelsen er deaktiveret, oprettes en ny forbindelse til denne applikation.

Nu er det nødvendigt at køre en lagret procedure i Agent-opgaven én gang om dagen:

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

Det ville være bedre at pakke denne forespørgsel ind i try-catch-blokken for at behandle et muligt kald for undtagelser.

Resultat

I denne artikel har jeg analyseret, hvordan man implementerer lagrede procedurer for at lukke en forbindelse til en database (alle eller en bestemt bruger) og for at slette fastlåste processer på et bestemt eksempel. Derudover har jeg undersøgt på et bestemt eksempel, hvordan man automatisk kører en opgave på de fastlåste processer sletning på daglig basis. Det giver mulighed for at reducere antallet af 'døde' forbindelser til en server. Sletningen af ​​alle forbindelser til databasen giver dig mulighed for at ændre nogle egenskaber, samt lukke processen, der forårsager ethvert problem.

Referencer:

» sysprocesses
» kill
» db_id
» @@SPID


  1. Databasesikkerhedsovervågning til MySQL og MariaDB

  2. MySql får optegnelser eller data dagligt, ugentligt, månedligt og årligt

  3. Sådan opretter du en tabel i SQL Server ved hjælp af en forespørgsel

  4. Indstilling af MySQL-konfigurationsvariabler – MySQL 5.7 vs MySQL 8.0