Кажется, у меня есть приложение на моем Dev-сервере, у которого много открытых подключений (они должны быть там, но для их открытия использовался какой-то плохой уровень данных, который забыл их закрыть). Я просто хочу, чтобы они были закрыты, чтобы на сервере работали другие приложения. Как я могу принудительно закрыть все соединения?





Помимо удаления ваших соединений вручную, вы можете
Что ж, если это веб-приложение, работающее на IIS, вы можете время от времени перезапускать (= перезапускать) приложение IIS, что, очевидно, уничтожает все соединения. Если это не веб-приложение, вы не можете использовать этот подход. Это не специфические для MSSQL решения, но тем не менее уничтожит соединения.
Используйте столбец last_batch из sysprocesses, чтобы выяснить, действительно ли он активен или нет. SPID> 50 (или это> = 50?), Чтобы избежать уничтожения системных SPID.
Сравните это с желаемым временем сна и KILL spid.
Вам придется пройти через это.
DECLARE @kill_id smallint
DECLARE spid_cursor CURSOR FOR
select spid from sysprocesses
where dbid = > 4 and last_batch < dateadd(hour, -24, getdate()) and spid >= 50
OPEN spid_cursor
FETCH NEXT FROM spid_cursor INTO @kill_id
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- Kill the current spid here
-- KILL @kill_id <---This line will not work
-- Get the next cursor row
FETCH NEXT FROM spid_cursor INTO @kill_id
END
CLOSE spid_cursor
DEALLOCATE spid_cursor
Используйте следующий сценарий, чтобы убить неактивные сеансы с определенного хоста / входа. Вы можете использовать его из запланированного задания, конечно, вашим приоритетом должно быть исправление уровня вашего приложения.
SET NOCOUNT ON;
DECLARE @host VARCHAR(50), @login NVARCHAR(128);
SET @host = 'fooHost'; --NULL to kill sessions from all hosts.
SET @login = 'fooLogin';
DECLARE @cmd NVARCHAR(255);
DECLARE @possition INT, @total INT, @selSpid SMALLINT;
DECLARE @spidInfo TABLE
(
[id] INT IDENTITY(1,1),
spid SMALLINT,
loginame NVARCHAR(128)
);
INSERT @spidInfo(spid, loginame)
SELECT session_id, login_name
FROM sys.dm_exec_sessions
WHERE is_user_process = 1 AND [status] = 'sleeping' AND
login_name = @login AND [host_name] = COALESCE(@host, [host_name]);
SELECT @total = @@IDENTITY, @selSpid = 0, @possition = 0;
WHILE @possition < @total
BEGIN
SELECT TOP 1 @selSpid = spid, @possition = [id]
FROM @spidInfo
WHERE [ID] > @possition
SET @cmd = N'KILL ' + CAST(@selSpid AS NVARCHAR(10));
EXEC sp_executesql @cmd;
PRINT 'SessionId = ' + CAST(@selSpid AS NVARCHAR(10)) + '[' + @login +
'] killed by ' + system_user + ' at ' + CAST(GETDATE() AS VARCHAR(50));
END;
IF (@total = 0)
PRINT 'No sessions owned by user ' + '[' + @login + ']';
Сначала запустите это, чтобы найти проблемную базу данных ...
SELECT DB_NAME(dbid) as 'Database Name',
COUNT(dbid) as 'Total Connections'
FROM master.dbo.sysprocesses WITH (nolock)
WHERE dbid > 0
GROUP BY dbid
SELECT @@MAX_CONNECTIONS AS 'Max Allowed Connections'
Затем запустите это, чтобы убить подключения к желаемой БД.
USE master
go
DECLARE @dbname sysname
SET @dbname = 'Events'
DECLARE @spid int
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname)
WHILE @spid IS NOT NULL
BEGIN
EXECUTE ('KILL ' + @spid)
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname) AND spid > @spid
END
Спасибо - у меня есть слой данных, который является одноразовым и убивает все соединения при удалении, но по какой-то причине разработчик, работающий над этим приложением, решил не убивать доступ к данным. Что вы подразумеваете под переработкой пула приложений?