sqlserver自检堵塞并kill~~~

sqlserver还是很强大  很牛皮的  自身有作业可以定时定点去执行脚本
首先写一个检测堵塞的过程,并设置触发条件

USE [lianxi]

GO
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[monitor_deadlock]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[monitor_deadlock]
GO
USE [lianxi]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[monitor_deadlock]
as
BEGIN
    SET NOCOUNT ON;
declare @cnt int;
    select @cnt = COUNT(1) from (SELECT  
    DB_NAME(Blocked.database_id)                    AS 'database', 
    Blocked.Session_ID                              AS 'blocked SPID', 
    Blocked_SQL.TEXT                                AS 'blocked SQL', 
    Waits.wait_type                 AS 'wait resource', 
    Blocking.Session_ID                             AS 'blocking SPID', 
    Blocking_SQL.TEXT                               AS 'blocking SQL', 
    sess.status                 AS 'blocking status', 
    sess.total_elapsed_time             AS 'blocking elapsed time', 
    sess.logical_reads              AS 'blocking logical reads', 
    sess.memory_usage               AS 'blocking memory usage', 
    sess.cpu_time                   AS 'blocking cpu time', 
    sess.program_name               AS 'blocking program', 
    GETDATE()                                       AS 'timestamp' 
FROM sys.dm_exec_connections AS Blocking  
    INNER JOIN sys.dm_exec_requests AS Blocked ON Blocked.Blocking_Session_ID = Blocking.Session_ID 
        INNER JOIN sys.dm_os_waiting_tasks AS Waits ON waits.Session_ID = Blocked.Session_ID 
        INNER JOIN sys.dm_exec_sessions sess ON sess.session_id = Blocking.Session_ID 
        CROSS APPLY sys.dm_exec_sql_text(Blocking.most_recent_sql_handle) AS Blocking_SQL 
        CROSS APPLY sys.dm_exec_sql_text(Blocked.sql_handle) AS Blocked_SQL  )n;
       
        select '堵塞数量:',COUNT(1) from (SELECT  
    DB_NAME(Blocked.database_id)                    AS 'database', 
    Blocked.Session_ID                              AS 'blocked SPID', 
    Blocked_SQL.TEXT                                AS 'blocked SQL', 
    Waits.wait_type                 AS 'wait resource', 
    Blocking.Session_ID                             AS 'blocking SPID', 
    Blocking_SQL.TEXT                               AS 'blocking SQL', 
    sess.status                 AS 'blocking status', 
    sess.total_elapsed_time             AS 'blocking elapsed time', 
    sess.logical_reads              AS 'blocking logical reads', 
    sess.memory_usage               AS 'blocking memory usage', 
    sess.cpu_time                   AS 'blocking cpu time', 
    sess.program_name               AS 'blocking program', 
    GETDATE()                                       AS 'timestamp' 
FROM sys.dm_exec_connections AS Blocking  
    INNER JOIN sys.dm_exec_requests AS Blocked ON Blocked.Blocking_Session_ID = Blocking.Session_ID 
        INNER JOIN sys.dm_os_waiting_tasks AS Waits ON waits.Session_ID = Blocked.Session_ID 
        INNER JOIN sys.dm_exec_sessions sess ON sess.session_id = Blocking.Session_ID 
        CROSS APPLY sys.dm_exec_sql_text(Blocking.most_recent_sql_handle) AS Blocking_SQL 
        CROSS APPLY sys.dm_exec_sql_text(Blocked.sql_handle) AS Blocked_SQL  )n;
       
    if @cnt>=100
    begin
    select ('堵塞超过100,执行 kill deadlock');
    exec lianxi.dbo.kill_deadlock;
    end
   
END

GO

检测的过程写完了  那接下来就是检测出堵塞要怎么办 当然是干掉,然后再写个kill的procedure

USE [lianxi]
GO
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[kill_deadlock]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[kill_deadlock]
GO
USE [lianxi]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[kill_deadlock]
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    DECLARE
@USER_ID INT, @KILLCMD VARCHAR(100)
-- 根据选择条件,选择出应该取消的进程
DECLARE cur_lock CURSOR FOR
SELECT spid FROM master..sysprocesses
WHERE
blocked = 0
AND spid IN
(SELECT blocked FROM master..sysprocesses);
-- 取消所有选择出的进程。
OPEN cur_lock;
FETCH NEXT FROM cur_lock INTO @USER_ID;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @KILLCMD = 'kill ' + CAST(@USER_ID AS VARCHAR);
EXECUTE (@KILLCMD);
FETCH NEXT FROM cur_lock INTO @USER_ID;
END;
CLOSE cur_lock;
DEALLOCATE cur_lock;
   
   
   
END
GO

两个过程写完之后就可以在SQL server中添加作业试试看了 



猜你喜欢

转载自blog.csdn.net/lyk_for_dba/article/details/79402797
今日推荐