以下情况:我们有一台带有db的azure服务器,并且TempDB驱动器已满。此时,我们可以在活动监视器中找到一个需要大量资源的流程。该过程不可终止,因为无法完成回滚,导致驱动器已满。
现在我有两个问题:
附带的内容是活动监视器的屏幕快照和过程代码。 使用sql server代理每10秒启动一次该过程。该过程内部的循环并不是很好,但是我们需要统计数据,并且在过去3周中运行良好。
CREATE PROCEDURE Log_Blocking_Processes
AS
BEGIN
IF OBJECT_ID('dbo.Log_Blocked_Processes', 'U') IS NULL
BEGIN
SELECT GETDATE() as Tag,
db.name DBName,
tl.request_session_id,
wt.blocking_session_id,
OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
tl.resource_type,
h1.TEXT AS RequestingText,
h2.TEXT AS BlockingText,
tl.request_mode,
er.transaction_id as Requesting_Transaction_ID,
tst.transaction_id as Blocking_Transaction_ID,
tat.name as Blocking_Transaction_Name,
er.wait_time/1000 as Wait_Time_SEC
INTO Log_Blocked_Processes
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
INNER JOIN sys.dm_exec_requests er ON er.session_id = tl.request_session_id AND er.blocking_session_id = wt.blocking_session_id AND er.blocking_session_id <> 0
INNER JOIN sys.dm_tran_session_transactions tst ON tst.session_id = wt.blocking_session_id
INNER JOIN sys.dm_tran_active_transactions tat ON tat.transaction_id = tst.transaction_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
WHERE db.database_id = DB_ID();
RETURN;
END;
DECLARE @DBName nvarchar(128),
@request_session_id int,
@blocking_session_id smallint,
@BlockedObjectName nvarchar(128),
@resource_type nvarchar(60),
@RequestingText nvarchar(MAX),
@BlockingText nvarchar(MAX),
@request_mode nvarchar(60),
@Requesting_Transaction_ID bigint,
@Blocking_Transaction_ID bigint,
@Blocking_Transaction_Name nvarchar(32),
@Wait_Time_SEC int,
@Tag DATE,
@Mycount int,
@LastInsertDay DATE,
@counter int = 1;
DECLARE blocked_processes_cursor CURSOR FOR
SELECT cast(GETDATE() as DATE) as Tag,
db.name DBName,
tl.request_session_id,
wt.blocking_session_id,
OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
tl.resource_type,
h1.TEXT AS RequestingText,
h2.TEXT AS BlockingText,
tl.request_mode,
er.transaction_id as Requesting_Transaction_ID,
tst.transaction_id as Blocking_Transaction_ID,
tat.name as Blocking_Transaction_Name,
er.wait_time/1000 as Wait_Time_SEC
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
INNER JOIN sys.dm_exec_requests er ON er.session_id = tl.request_session_id AND er.blocking_session_id = wt.blocking_session_id AND er.blocking_session_id <> 0
INNER JOIN sys.dm_tran_session_transactions tst ON tst.session_id = wt.blocking_session_id
INNER JOIN sys.dm_tran_active_transactions tat ON tat.transaction_id = tst.transaction_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
WHERE db.database_id = DB_ID();
WHILE @counter <= 4
BEGIN
OPEN blocked_processes_cursor
FETCH NEXT FROM blocked_processes_cursor INTO @Tag, @DBName, @request_session_id, @blocking_session_id, @BlockedObjectName, @resource_type, @RequestingText, @BlockingText, @request_mode, @Requesting_Transaction_ID, @Blocking_Transaction_ID, @Blocking_Transaction_Name, @Wait_Time_SEC;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Mycount = count(*), @LastInsertDay = cast(max(Tag) as date) FROM Log_Blocked_Processes WHERE Requesting_Transaction_ID = @Requesting_Transaction_ID AND Blocking_Transaction_ID = @Blocking_Transaction_ID;
IF @Mycount > 0 AND @LastInsertDay = cast(getdate() as date)
BEGIN
UPDATE Log_Blocked_Processes
SET Wait_Time_SEC = @Wait_Time_SEC
WHERE Requesting_Transaction_ID = @Requesting_Transaction_ID
AND Blocking_Transaction_ID = @Blocking_Transaction_ID;
END;
ELSE
BEGIN
INSERT INTO [Log_Blocked_Processes]([Tag],[DBName],[request_session_id],[blocking_session_id],[BlockedObjectName],[resource_type],[RequestingText],[BlockingText],[request_mode],[Requesting_Transaction_ID],[Blocking_Transaction_ID],[Blocking_Transaction_Name],[Wait_Time_SEC])
VALUES(GETDATE(),@DBName,@request_session_id,@blocking_session_id,@BlockedObjectName,@resource_type,@RequestingText,@BlockingText,@request_mode,@Requesting_Transaction_ID,@Blocking_Transaction_ID,@Blocking_Transaction_Name,@Wait_Time_SEC)
END;
FETCH NEXT FROM blocked_processes_cursor INTO @Tag, @DBName, @request_session_id, @blocking_session_id, @BlockedObjectName, @resource_type, @RequestingText, @BlockingText, @request_mode, @Requesting_Transaction_ID, @Blocking_Transaction_ID, @Blocking_Transaction_Name, @Wait_Time_SEC;
END;
SET @counter = @counter + 1;
CLOSE blocked_processes_cursor;
WAITFOR DELAY '00:00:02';
END;
DEALLOCATE blocked_processes_cursor;
END;