今天有個客戶的資料庫發生了異常的鎖定狀況,但並不是鎖死 (Deadlocked) 的情況,所以必須要進一步分析才能知道問題的主因,不過在分析的過程中卻遇到了一個問題,那就是雖然知道是哪一條連線(SPID)出問題,但卻不知道應該 如何快速查出這條有問題的連線實際執行的 T-SQL 為何,唯有查出這條 T-SQL 實際執行的內容我才能找出應用程式中的哪一段程式出錯,這個技巧算是非常實用喔!
我們若用 sp_who2 這個系統預儲程序可以查出所有連線的狀況,也可以看到該連線被卡住 (Blocked) 的狀況,不過 Command 這個欄位卻只有查詢的摘要,看不出完整的查詢命令為何:
這 時我們可以利用 SQL Server 2005 以上都有支援的幾個 DMVs (Dynamic Management Views) 來查詢 SQL Server 資料庫中即時的運作資訊,當然也包括正在執行的完整 T-SQL 命令句,技術細節我就留在本文最後的相關連結讓各位自行研究,以下是我的研究成果:
SELECT r.scheduler_id as 排程器識別碼, status as 要求的狀態, r.session_id as SPID, r.blocking_session_id as BlkBy, substring( ltrim(q.text), r.statement_start_offset/2+1, (CASE WHEN r.statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(MAX), q.text)) * 2 ELSE r.statement_end_offset END - r.statement_start_offset)/2) AS [正在執行的 T-SQL 命令], r.cpu_time as [CPU Time(ms)], r.start_time as [開始時間], r.total_elapsed_time as [執行總時間], r.reads as [讀取數], r.writes as [寫入數], r.logical_reads as [邏輯讀取數], -- q.text, /* 完整的 T-SQL 指令碼 */ d.name as [資料庫名稱] FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS q LEFT JOIN sys.databases d ON (r.database_id=d.database_id) WHERE r.session_id > 50 AND r.session_id <> @@SPID ORDER BY r.total_elapsed_time desc
相關連結
- Execution Related Dynamic Management Views and Functions (Transact-SQL)
- sys.dm_exec_requests (Transact-SQL)
- sys.dm_exec_sql_text (Transact-SQL)
- Use Undocumented SP_WHO2 Procedure Instead of SP_WHO for SQL Server 7.0
- Microsoft SQL Server - Wikipedia, the free encyclopedia
- SQL SERVER – 2005 – List all the database
- TSQL to get current executing statements - SQL Server 2005
沒有留言:
張貼留言