终止 SQL Server 2005 上的泄漏连接

终止 SQL Server 2005 上的泄漏连接

我们有一个遗留的 ASP 应用程序,它在某处泄漏了 SQL 连接。在活动监视器中,我可以看到一堆空闲进程,上次批处理时间超过一小时。

当我查看 T-SQL 命令批处理时,这些始终是 FETCH API_CURSOR[XXX]([XXX] 是一个随机出现的十六进制数,例如 FETCH API_CURSOR0000000002CE0BEC),据我了解,这是由未正确关闭的 ASP ADO 记录集引起的。

在我们尝试找出有问题的代码时,有没有办法让我监视哪些请求打开了哪些游标?我假设是分析器,但我不确定我应该监视什么。我可以看到一堆对 sp_cursoropen 的调用,但我没有在任何地方看到 API_CUSROR[XXX] 名称。

其次,有人能建议一个脚本来根据上次批处理时间> 10 分钟和上次批处理命令为 FETCH API_CURSOR[XXX] 来终止这些进程吗?

由于各种原因,很遗憾我们没有任何 SQL Server DBA。

更新

根据 jl 提供的脚本和我在以下位置找到的一些信息SQLAuthority.com,我想出了这个可以很好地完成工作的脚本。

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

CREATE PROCEDURE [dbo].[sp_KillHungADORecordsets] @dbname varchar(50)  
AS

CREATE table #oldSpids
( 
    spid int, 
) 

DECLARE @Now DATETIME
SET @Now = GETDATE()

INSERT INTO #oldSpids  
select spid  
from master.dbo.sysprocesses (nolock)  
where dbid = db_id(@dbname)
and spid > 50 
and DATEDIFF(minute,last_batch,@Now) > 10

DECLARE hungSpids CURSOR FAST_FORWARD 
FOR SELECT spid FROM #oldSpids


DECLARE @spid int 

OPEN hungSpids 

DECLARE @strSQL varchar(255) 
DECLARE @sqlHandle VARBINARY(128)
DECLARE @sqlText VARCHAR(MAX)

FETCH NEXT FROM hungSpids INTO @spid
WHILE (@@fetch_status <> -1) 
BEGIN 
    IF (@@fetch_status <> -2) 
    BEGIN 
        SELECT @sqlHandle = sql_handle
        FROM sys.sysprocesses
        WHERE spid = @spid
        SELECT @sqlText = TEXT
        FROM sys.dm_exec_sql_text(@sqlHandle)
        IF (@sqlText LIKE 'FETCH API_CURSOR%')
        BEGIN
            PRINT 'Killing ' + convert(varchar(10),@spid) 
            SET @strSQL = 'KILL ' + convert(varchar(10),@spid) 
            EXEC (@strSQL) 
        END 
    END
    FETCH NEXT FROM hungSpids INTO @spid 
END 

CLOSE hungSpids 
DEALLOCATE hungSpids 
DROP table #oldSpids 

但是,我仍然不知道如何使用分析器将 sp_opencusror 命令与相应的 API_CURSOR[XXX] 进行匹配。

答案1

虽然不是原始脚本,但经过调整可能会达到您需要的目的,或者至少是一个开始:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[uspKillUsersFETCH] @dbname varchar(50) 
as

DECLARE @strSQL varchar(255)
PRINT 'Killing Users '
PRINT '-------------------------------------------------------------------------------------------'


CREATE table #tmpUsers(
spid int,
dbname varchar(128),
cmd varchar(128))


INSERT INTO #tmpUsers 
select spid, convert(varchar(128),db_name(dbid)), cmd
 from master.dbo.sysprocesses (nolock) 

DECLARE LoginCursor CURSOR
READ_ONLY
FOR SELECT spid, program_name FROM #tmpUsers WHERE dbname = 'database name here'
and spid > 50
and cmd like '%FETCH API_CURSORXXX%' 


DECLARE @spid int
DECLARE @dbname2 varchar(128)
OPEN LoginCursor

FETCH NEXT FROM LoginCursor INTO @spid, @dbname2
WHILE (@@fetch_status <> -1)
BEGIN
    IF (@@fetch_status <> -2)
    BEGIN
    PRINT 'Killing ' + convert(varchar(10),@spid)
    SET @strSQL = 'KILL ' + convert(varchar(10),@spid)
    EXEC (@strSQL)
    END
    FETCH NEXT FROM LoginCursor INTO  @spid, @dbname2
END

CLOSE LoginCursor
DEALLOCATE LoginCursor

DROP table #tmpUsers

****再次强调,此剧非原创,因此应归功于那位现已不为人知的编剧****

我使用这个版本来杀死使用 Mgt Studion 连接到日志传送备用数据库的 SQL 2005 spid

相关内容