Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Automatyczne usuwanie zablokowanych procesów w MS SQL Server

Wprowadzenie

Zdarzają się sytuacje, w których aplikacje utrzymują połączenie z bazą danych przez długi czas. Wydaje się, że to nie jest ważne. Jeśli jednak ta aplikacja nawiązuje wiele połączeń lub istnieje kilka aplikacji zachowujących się w taki sposób — sytuacja się pogarsza.

Ten artykuł nie jest samouczkiem. Opisuje możliwe rozwiązania tego problemu. Jak zwykle z przyjemnością wysłucham wszelkich alternatywnych rozwiązań.

Rozwiązanie

1. Utwórz procedurę składowaną, która zamyka wszystkie połączenia lub połączenia określonego użytkownika z określoną bazą danych:

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

Ta procedura składowana pomaga ręcznie wyłączyć wszystkie połączenia z bazą danych lub określonego użytkownika w celu wykonania dalszych działań z bazą danych.

2. Utwórz procedurę składowaną, aby usunąć wszystkie zablokowane procesy.

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

Ta procedura składowana usuwa połączenia, które zostały zakończone ponad 24 godziny temu. Ponadto ta procedura nie wpływa na główne bazy danych systemu (master, tempdb, model i msdb). Jeśli spróbujesz uzyskać dostęp do bazy danych, gdy połączenie jest wyłączone, zostanie utworzone nowe połączenie dla tej aplikacji.

Teraz konieczne jest uruchomienie procedury składowanej w zadaniu Agenta raz dziennie:

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

Lepiej byłoby umieścić to zapytanie w bloku try-catch, aby przetworzyć możliwe wywołanie wyjątków.

Wynik

W tym artykule przeanalizowałem, jak zaimplementować procedury składowane przy zamykaniu połączenia z bazą danych (wszystkim lub określonym użytkownikiem) i usuwać zablokowane procesy na konkretnym przykładzie. Ponadto zbadałem na konkretnym przykładzie, jak codziennie automatycznie uruchamiać zadanie po usunięciu zablokowanych procesów. Pozwala zmniejszyć liczbę „martwych” połączeń z serwerem. Usunięcie wszystkich połączeń z bazą danych umożliwia modyfikację niektórych właściwości, a także zamknięcie procesu, który powoduje jakikolwiek problem.

Referencje:

» procesy systemowe
» zabij
» db_id
» @@SPID


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wiele wierszy do jednej wartości oddzielonej przecinkami w Sql Server

  2. Uzupełnij ciąg zerami na początku, aby miał 3 znaki w SQL Server 2008

  3. Typowe błędy DBA w MS SQL Server

  4. Wyniki dynamicznego SQL w tabeli tymczasowej w procedurze SQL Stored

  5. Co to jest RAISERROR programu SQL Server?