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
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
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
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
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
GO
SET QUOTED_IDENTIFIER ON
GO
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
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