自动终止某些特定任务的会话
Posted
技术标签:
【中文标题】自动终止某些特定任务的会话【英文标题】:Automatically kill session of some specific task 【发布时间】:2016-05-16 11:23:23 【问题描述】:在某些报表生成中,我们在 SQL Server 中面临死锁问题,所以我能做的是
select *
from sys.sysprocesses
where dbid = db_id()
and spid <> @@SPID
and blocked <> 0
and lastwaittype LIKE 'LCK%'
dbcc inputbuffer (SPID from above query result)
dbcc inputbuffer (blocked from above query result)
如果EventInfo
列包含“mytext”,我想终止该部分
Kill 53
53
不是 SPID 或在我看到我想终止其连接的特定文本时被阻止
每当死锁创建并且找到特定单词时,我想自动执行此过程以终止这些会话。没有用户间隔或动作。
【问题讨论】:
SQL 将在它认为合适的时候分配它自己的死锁受害者(iirc 它基于查询的估计操作员成本)。为什么你觉得有必要自己做这件事?最好先查看 SQL Server 中的隔离级别以阻止死锁。 发生这种情况时,所有用户都会收到错误消息并且条目无法保存。除非我做上述练习。 (现在有完成时间,这种情况经常发生) 如果你要走极端的自动杀死进程,那么你不妨走极端的开启读取提交快照隔离。 您可以将“SET DEADLOCK_PRIORITY LOW”添加到使用“mytext”运行查询的会话中。这样,如果发生死锁情况,如果与另一个优先级正常(默认)或高的会话发生死锁,该会话将被选为牺牲品 恭喜,检查dbareaction :) 【参考方案1】:有时我使用这个旧查询来摆脱带有特定描述的会话:
declare @t table (sesid int)
--Here we put all sessionid's with specific description into temp table
insert into @t
select spid
from sys.sysprocesses
where dbid = db_id()
and spid <> @@SPID
and blocked <> 0
and lastwaittype LIKE 'LCK%'
DECLARE @n int,
@i int= 0,
@s int,
@kill nvarchar(20)= 'kill ',
@sql nvarchar (255)
SELECT @n = COUNT(*) FROM @t
--Here we execute `kill` for every sessionid from @t in while loop
WHILE @i < @n
BEGIN
SELECT TOP 1 @s = sesid from @t
SET @sql = @kill + cast(@s as nvarchar(10))
--select @sql
EXECUTE sp_executesql @sql
delete from @t where sesid = @s
SET @i = @i + 1
END
【讨论】:
我不想杀死所有会话,只有特定事件会话在我的数据库中创建死锁,例如“SUBLEDGER”这个词。如果在 eventinfo 中找到这个词,spid 会被上面的 t-sql 杀死 好吧,看看我的回答中的变化,我把你的查询代替了我的。您在 TEMP 表中查询的所有 spid - 而不是在 while 循环中的动态 sql 查询中被杀死。【参考方案2】:从上面的答案,我根据我的要求进行更改。
/*drop table #inputbuffer
--First Time create Table
create table #inputbuffer
(eventType varchar(255) ,
parameters int ,
procedureText varchar(255),
spid varchar(6))
*/
declare @spid varchar(6)
declare @sql varchar(50)
declare sprocket cursor fast_forward for
select spid from SYS.sysprocesses
where dbid =db_id() and spid <> @@SPID and blocked <>0 and lastwaittype LIKE 'LCK%'
union all
select blocked from SYS.sysprocesses
where dbid =db_id() and spid <> @@SPID and blocked <>0 and lastwaittype LIKE 'LCK%'
open sprocket
fetch next from sprocket into
@spid
while @@fetch_status = 0
begin
set @sql = 'dbcc inputbuffer(' + @spid + ')'
insert into #inputbuffer(eventType, parameters, procedureText)
exec (@sql)
update #inputbuffer
set spid = @spid
where spid is null
fetch next from sprocket into
@spid
end
close sprocket
deallocate sprocket
if @@cursor_rows <> 0
begin
close sprocket
deallocate sprocket
end
DELETE from #inputbuffer where procedureText NOT like '%SUBLED%'
select spid, eventType, parameters, procedureText from #inputbuffer
DECLARE @n int,
@i int= 0,
@s int,
@kill nvarchar(20)= 'kill ',
@sqln nvarchar (255)
SELECT @n = COUNT(*) FROM #inputbuffer
WHILE @i < @n
BEGIN
SELECT TOP 1 @s = spid from #inputbuffer
SET @sqln = @kill + cast(@s as nvarchar(10))
select @sqln
EXECUTE sp_executesql @sqln
delete from #inputbuffer where spid = @s
SET @i = @i + 1
END
【讨论】:
【参考方案3】:这里有更简洁的查询,可以杀死所有运行特定 sql 的会话。
DECLARE @kill varchar(8000); SET @kill = '';
SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';'
FROM sys.dm_exec_requests CROSS APPLY sys.dm_exec_sql_text(sql_handle)
WHERE database_id = db_id('dldb') and session_id <> @@SPID
and text like '%FROM dl2ResultsHeaderItemSubTree%'
EXEC(@kill);
这从 SQL Server 2005 开始有效。
从List the queries running on SQL Server 和Script to kill all connections to a database (More than RESTRICTED_USER ROLLBACK) 合并。
【讨论】:
以上是关于自动终止某些特定任务的会话的主要内容,如果未能解决你的问题,请参考以下文章