use DynamicsAx_PRO
go
------查询lock 循环次数 (倒序)
exec usp_Find_Problems
go
-----杀死进程
kill 141
go
-----查看当前数据库运行情况,可以看到进程被锁状况。
sp_who2
go
---查看当前数据库死锁明细
sp_lock
go
--查看当前数据库进程死锁等待时间(倒序)
Select a.sid,a.spid,a.waittime from sys.sysprocesses a where blocked <> 0
order by a.waittime desc
go
---
SELECT * FROM sys.dm_tran_locks;
go
SELECT * FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;
GO
SELECT session_id, wait_duration_ms, wait_type, blocking_session_id
FROM sys.dm_os_waiting_tasks
WHERE blocking_session_id <> 0
GO
----------------------------------------------
You might decide that you would like to take this query, and make it into a stored procedure. You can then load it into a maintenance database on each server so that you have it always available. It also means that you can parameterize it to control its behavior. For example, you may decide that you do not want to execute the portion of the query that counts locks, which on a very busy system could take quite a bit of time.
Listing 4 shows the code to create this stored procedure, named usp_Find_Problems, with a flag to execute the lock count portion based on need.
GO
/****** Object: StoredProcedure [dbo].[usp_Find_Problems] Script Date: 06/12/2012 16:34:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_Find_Problems] ( @count_locks BIT = 1 )
AS
SET NOCOUNT ON
-- Count the locks
IF @count_locks = 0
GOTO Get_Blocks
ELSE
IF @count_locks = 1
BEGIN
CREATE TABLE #Hold_sp_lock
(
spid INT,
dbid INT,
ObjId INT,
IndId SMALLINT,
Type VARCHAR(20),
Resource VARCHAR(50),
Mode VARCHAR(20),
Status VARCHAR(20)
)
INSERT INTO #Hold_sp_lock
EXEC sp_lock
SELECT COUNT(spid) AS lock_count,
SPID,
Type,
CAST(DB_NAME(DBID) AS VARCHAR(30)) AS DBName,
mode
FROM #Hold_sp_lock
GROUP BY SPID,
Type,
CAST(DB_NAME(DBID) AS VARCHAR(30)),
MODE
ORDER BY lock_count DESC,
DBName,
SPID,
MODE
--Show any blocked or blocking processes
Get_Blocks:
CREATE TABLE #Catch_SPID
(
bSPID INT,
BLK_Status CHAR(10)
)
INSERT INTO #Catch_SPID
SELECT DISTINCT
SPID,
'BLOCKED'
FROM master..sysprocesses
WHERE blocked <> 0
UNION
SELECT DISTINCT
blocked,
'BLOCKING'
FROM master..sysprocesses
WHERE blocked <> 0
DECLARE @tSPID INT
DECLARE @blkst CHAR(10)
SELECT TOP 1
@tSPID = bSPID,
@blkst = BLK_Status
FROM #Catch_SPID
WHILE( @@ROWCOUNT > 0 )
BEGIN
PRINT 'DBCC Results for SPID '
+ CAST(@tSPID AS VARCHAR(5)) + '( ' + RTRIM(@blkst)
+ ' )'
PRINT '-----------------------------------'
PRINT ''
DBCC INPUTBUFFER(@tSPID)
SELECT TOP 1
@tSPID = bSPID,
@blkst = BLK_Status
FROM #Catch_SPID
WHERE bSPID > @tSPID
ORDER BY bSPID
END
END
Executing usp_Find_Problems with no parameters will return the lock counts as well as the blocked and blocking SPIDs, whereas executing it with a value of 0 as the input parameter will exclude the lock counts. Figure 12 shows both executions in SSMS, using vertical tab groups.
Executing the usp_Find_Problems stored procedure with parameters.