Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Автоматично изтриване на блокирани процеси в MS SQL Server

Въведение

Има ситуации, когато приложенията запазват връзката с базата данни за дълъг период от време. Изглежда не е важно. Ако обаче това приложение прави много връзки или има няколко приложения с такова поведение — нещата се влошават.

Тази статия не е урок. Той описва възможните решения на този проблем. Както обикновено, ще се радвам да чуя всякакви алтернативни решения.

Решение

1. Създайте съхранена процедура, която затваря всички връзки или връзки на определен потребител към посочената база данни:

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

Тази съхранена процедура помага ръчно да деактивирате всички връзки към базата данни или определен потребител за по-нататъшни действия с базата данни.

2. Създайте съхранена процедура, за да премахнете всички блокирани процеси.

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

Тази съхранена процедура премахва връзките, които са били завършени преди повече от 24 часа. Освен това тази процедура не засяга основните системни бази данни (master, tempdb, model и msdb). Ако се опитате да получите достъп до база данни, докато връзката е деактивирана, ще бъде създадена нова връзка за това приложение.

Сега е необходимо да изпълнявате съхранена процедура в задачата Агент веднъж на ден:

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

Би било по-добре да обвиете тази заявка в блока try-catch, за да обработите възможно извикване за изключения.

Резултат

В тази статия анализирах как да прилагам съхранени процедури за затваряне на връзка с база данни (всички или определен потребител) и за изтриване на заседнали процеси в конкретен пример. В допълнение, аз проучих на конкретен пример как да стартирам автоматично задача за изтриване на блокирани процеси на дневна база. Позволява намаляване на количеството „мъртви“ връзки към сървър. Изтриването на всички връзки към базата данни ви позволява да промените някои свойства, както и да затворите процеса, който причинява проблем.

Препратки:

» sysprocesses
» kill
» 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. Как да наблюдавате промените в таблицата на SQL Server с помощта на C#?

  2. Как да променя SQL Server 2005 така, че да е чувствителен към главни букви?

  3. Изберете/Вмъкнете версия на Upsert:има ли модел на проектиране за висок едновременност?

  4. Не може да се съкрати таблицата, защото се препраща от ограничение FOREIGN KEY?

  5. Как мога да съкратя дата и час в SQL Server?