配置SSMS 让数据库中会话时长大于30秒的自动终止
配置SSMS 让数据库中会话时长大于30秒的自动终止
配置SSMS自动终止长时间运行的会话(>30秒)
在SQL Server Management Studio (SSMS)中,没有内置的直接设置可以自动终止长时间运行的会话。但你可以通过以下几种方法实现类似功能:
方法1:使用SQL Server Agent作业定期检查并终止
创建存储过程 检查并终止长时间运行的会话:
CREATE PROCEDURE sp_KillLongRunningSessions
@MaxDurationSeconds INT = 30
AS
BEGIN
DECLARE @sql NVARCHAR(MAX) = '';
SELECT @sql = @sql + 'KILL ' + CAST(session_id AS NVARCHAR(10)) + ';'
FROM sys.dm_exec_sessions
WHERE status = 'running'
AND DATEDIFF(SECOND, last_request_start_time, GETDATE()) > @MaxDurationSeconds
AND is_user_process = 1
AND session_id <> @@SPID; -- 不终止当前会话
IF @sql <> ''
BEGIN
EXEC sp_executesql @sql;
PRINT '已终止以下长时间运行的会话: ' + @sql;
END
ELSE
BEGIN
PRINT '没有发现运行时间超过' + CAST(@MaxDurationSeconds AS VARCHAR) + '秒的会话';
END
END
- 创建SQL Server Agent作业:
打开SSMS → SQL Server Agent → 作业 → 新建作业
添加步骤,类型选择"Transact-SQL脚本"
命令中输入:EXEC sp_KillLongRunningSessions 30;
设置计划(例如每分钟运行一次)
CREATE OR ALTER TRIGGER tr_KillLongRunningQueries
ON ALL SERVER
FOR LOGON
AS
BEGIN
DECLARE @spid INT;
DECLARE @login_time DATETIME;
SELECT @spid = session_id, @login_time = login_time
FROM sys.dm_exec_sessions
WHERE session_id = @@SPID
AND DATEDIFF(SECOND, login_time, GETDATE()) > 30
AND is_user_process = 1;
IF @spid IS NOT NULL
BEGIN
DECLARE @msg NVARCHAR(100) = '会话已运行超过30秒,将被终止';
RAISERROR(@msg, 16, 1);
KILL @spid;
END
END;
方法3:使用资源调控器(SQL Server Enterprise版)
- 创建工作负载组:
CREATE WORKLOAD GROUP LongRunningQueries
WITH (
MAX_DOP = 1,
REQUEST_MAX_MEMORY_GRANT_PERCENT = 25,
REQUEST_MAX_CPU_TIME_SEC = 30, -- 30秒后终止
REQUEST_MEMORY_GRANT_TIMEOUT_SEC = 30,
MAX_OUTSTANDING_IO_PER_VOLUME = 20
);
- 创建分类器函数:
CREATE FUNCTION dbo.ClassifierFunction()
RETURNS SYSNAME
WITH SCHEMABINDING
AS
BEGIN
DECLARE @group SYSNAME;
IF (SELECT DATEDIFF(SECOND, login_time, GETDATE())
FROM sys.dm_exec_sessions WHERE session_id = @@SPID) > 30
SET @group = 'LongRunningQueries';
ELSE
SET @group = 'default';
RETURN @group;
END;
- 配置资源调控器使用此分类器
方法4:使用扩展事件(XEvents)监控并触发操作
CREATE EVENT SESSION [KillLongRunningQueries] ON SERVER
ADD EVENT sqlserver.sql_statement_completed(
WHERE ([duration] > 30000000)) -- 30秒
ADD TARGET package0.event_file(SET filename=N'KillLongRunningQueries')
WITH (TRACK_CAUSALITY=ON);
GO
-- 需要额外编写处理程序来解析事件日志并执行KILL命令