Nous avons une ancienne application ASP qui fuit quelque part les connexions SQL. Dans Activity Monitor, je peux voir un tas de processus inactifs dont le dernier lot date de plus d'une heure.
Lorsque je regarde le lot de commandes T-SQL, il s'agit toujours de FETCH API_CURSOR[XXX] ([XXX] est un nombre hexadécimal aléatoire, par exemple FETCH API_CURSOR0000000002CE0BEC), ce qui, d'après ce que j'ai compris, est dû à une fermeture incorrecte des Recordsets ASP ADO.
Pendant que nous essayons d'identifier le code incriminé, y a-t-il un moyen pour moi de contrôler quelles requêtes ouvrent quels curseurs ? Je suppose qu'il s'agit d'un profiler, mais je ne suis pas sûr de ce que je devrais surveiller exactement. Je peux voir un tas d'appels à sp_cursoropen mais je ne vois nulle part le nom API_CUSROR[XXX].
Deuxièmement, quelqu'un pourrait-il nous suggérer un script que nous pourrions exécuter pour tuer ces processus en fonction de la durée du dernier lot > 10 minutes et de la dernière commande de lot FETCH API_CURSOR[XXX] ?
Pour diverses raisons, nous n'avons malheureusement pas de DBA SQL Server.
MISE À JOUR
Sur la base du script fourni par jl et des informations que j'ai trouvées à l'adresse suivante SQLAuthority.com J'ai trouvé ce script qui fait bien le travail.
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
Je ne sais toujours pas comment faire correspondre les commandes sp_opencusror aux API_CURSOR[XXX] correspondants à l'aide de profiler, cependant.