SQL Server:TempDB驱动器已满-程序需要多少性能?

时间:2019-03-07 13:29:25

标签: sql sql-server performance stored-procedures tempdb

以下情况:我们有一台带有db的azure服务器,并且TempDB驱动器已满。此时,我们可以在活动监视器中找到一个需要大量资源的流程。该过程不可终止,因为无法完成回滚,导致驱动器已满。

现在我有两个问题:

  1. 该过程可能是造成大量tempdb文件的原因吗?
  2. 有人可以解释为什么该过程需要这么多资源吗?

附带的内容是活动监视器的屏幕快照和过程代码。 使用sql server代理每10秒启动一次该过程。该过程内部的循环并不是很好,但是我们需要统计数据,并且在过去3周中运行良好。

enter image description here

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;

0 个答案:

没有答案