杀死SQL Server 2005上的连接

我们有一个传统的ASP应用程序,在某处泄漏SQL连接。 在Activity Monitor中,我可以看到一堆超过一个小时的Last Batch时间的空闲进程。

当我查看T-SQL命令批处理时,这些总是FETCH API_CURSOR [XXX]([XXX]是一个随机表示的hex数,例如FETCH API_CURSOR0000000002CE0BEC),这从我的理解是由不正确closuresASP ADOlogging集引起的。

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

其次,任何人都可以build议一个脚本,我们可以运行杀死这些进程基于最后一批> 10分钟和最后一批命令是FETCH API_CURSOR [XXX]?

由于各种原因,我们很遗憾没有任何SQL Server数据库pipe理员。

UPDATE

基于jl提供的脚本和我在SQLAuthority.com上find的一些信息,我想出了这个脚本,它很好地完成了这项工作。

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 

不过,我仍然不知道如何使用profiler将sp_opencusror命令与相应的API_CURSOR [XXX]相匹配。

不是一个原始的脚本,但调整,可能会得到你需要的地方,或至less是一个开始:

 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