代码之家  ›  专栏  ›  技术社区  ›  edosoft

如何查询SQL Server数据库还原需要多长时间?

  •  7
  • edosoft  · 技术社区  · 14 年前

    我正在尝试编写一个查询,它将告诉我在SQL Server 2008上恢复(完整或日志)所花费的时间。

    我可以运行此查询以了解备份所用的时间:

    select  database_name, 
            [uncompressed_size] = backup_size/1024/1024,
            [compressed_size] = compressed_backup_size/1024/1024, 
            backup_start_date, 
            backup_finish_date, 
            datediff(s,backup_start_date,backup_finish_date) as [TimeTaken(s)], 
    from    msdb..backupset b 
    where   type = 'L' -- for log backups
    order by b.backup_start_date desc
    

    这个问题会告诉我 什么 恢复,但现在需要多少时间:

    select * from msdb..restorehistory
    

    restorehistory 有一列 backup_set_id 将链接到 msdb..backupset 但它保留了 备份 不是还原。

    知道在哪里查询恢复的开始和结束时间吗?

    3 回复  |  直到 14 年前
        1
  •  12
  •   LittleBobbyTables - Au Revoir    14 年前

    要查找还原数据库时间,我发现您可以使用此查询:

    declare @filepath nvarchar(1000) 
    
    SELECT @filepath = cast(value as nvarchar(1000)) FROM [fn_trace_getinfo](NULL) 
    WHERE [property] = 2 and traceid=1 
    
    SELECT *
    FROM [fn_trace_gettable](@filepath, DEFAULT) 
    WHERE TextData LIKE 'RESTORE DATABASE%' 
    ORDER BY StartTime DESC; 
    

    缺点是,您会注意到,至少在我的测试服务器上, EndTime 始终为空。

    所以,我提出了第二个查询来尝试确定结束时间。首先,我很抱歉这很难看,而且嵌套得很疯狂。

    下面的查询假设如下:

    1. 当运行还原时,对于该databaseid和clientprocessid,下一个事件序列包含我们需要的transactionid。
    2. 然后我找到事务的最大事件序列
    3. 最后,我选择包含 RESTORE DATABASE 以及与该记录关联的最大事务。

    我确信有人可能会接受我所做的并对其进行改进,但这似乎适用于我的测试环境:

    declare @filepath nvarchar(1000) 
    
    SELECT @filepath = cast(value as nvarchar(1000)) FROM [fn_trace_getinfo](NULL) 
    WHERE [property] = 2 and traceid=1 
    
    SELECT *
    FROM [fn_trace_gettable](@filepath, DEFAULT) F5
    INNER JOIN 
    (
        SELECT F4.EventSequence MainSequence, 
             MAX(F3.EventSequence) MaxEventSequence, F3.TransactionID
        FROM [fn_trace_gettable](@filepath, DEFAULT) F3
        INNER JOIN 
        (
            SELECT F2.EventSequence, MIN(TransactionID) as TransactionID
            FROM [fn_trace_gettable](@filepath, DEFAULT) F1
            INNER JOIN 
            (
                SELECT DatabaseID, SPID, StartTime, ClientProcessID, EventSequence
                FROM [fn_trace_gettable](@filepath, DEFAULT)
                WHERE TextData LIKE 'RESTORE DATABASE%' 
            ) F2 ON F1.DatabaseID = F2.DatabaseID AND F1.SPID = F2.SPID 
                           AND F1.ClientProcessID = F2.ClientProcessID 
                           AND F1.StartTime > F2.StartTime
            GROUP BY F2.EventSequence
        ) F4 ON F3.TransactionID = F4.TransactionID 
        GROUP BY F3.TransactionID, F4.EventSequence
    ) F6 ON F5.EventSequence = F6.MainSequence 
        OR F5.EventSequence = F6.MaxEventSequence
    ORDER BY F5.StartTime
    

    编辑

    我对查询做了一些更改,因为我使用的一个测试数据库区分大小写,并且丢失了一些记录。我还注意到从磁盘恢复时, DatabaseID 是空的,所以我现在也在处理:

    SELECT * 
    FROM [fn_trace_gettable](@filepath, DEFAULT) F5 
    INNER JOIN  
    ( 
        SELECT F4.EventSequence MainSequence,  
             MAX(F3.EventSequence) MaxEventSequence, F3.TransactionID 
        FROM [fn_trace_gettable](@filepath, DEFAULT) F3 
        INNER JOIN  
        ( 
            SELECT F2.EventSequence, MIN(TransactionID) as TransactionID 
            FROM [fn_trace_gettable](@filepath, DEFAULT) F1 
            INNER JOIN  
            ( 
                SELECT DatabaseID, SPID, StartTime, ClientProcessID, EventSequence 
                FROM [fn_trace_gettable](@filepath, DEFAULT) 
                WHERE upper(convert(nvarchar(max), TextData)) 
                    LIKE 'RESTORE DATABASE%'  
            ) F2 ON (F1.DatabaseID = F2.DatabaseID OR F2.DatabaseID IS NULL) 
                       AND F1.SPID = F2.SPID  
                       AND F1.ClientProcessID = F2.ClientProcessID  
                       AND F1.StartTime > F2.StartTime 
            GROUP BY F2.EventSequence 
        ) F4 ON F3.TransactionID = F4.TransactionID  
        GROUP BY F3.TransactionID, F4.EventSequence 
    ) F6 ON F5.EventSequence = F6.MainSequence  
        OR F5.EventSequence = F6.MaxEventSequence 
    ORDER BY F5.StartTime 
    
        2
  •  5
  •   Jack Knows Jack    14 年前

    把它变成工作。然后把它作为作业运行。然后检查查看作业历史记录。然后查看“持续时间”列。

        3
  •  3
  •   Gabriel Guimarães    14 年前

    当它运行时,你可以检查像这个DMV一样的东西。

    select 
    d.name
    ,percent_complete
    ,dateadd(second,estimated_completion_time/1000, getdate())
    , Getdate() as now
    ,datediff(minute, start_time
    , getdate()) as running
    , estimated_completion_time/1000/60 as togo
    ,start_time
    , command 
    from sys.dm_exec_requests req
    inner join sys.sysdatabases d on d.dbid = req.database_id
    where 
    req.command LIKE '%RESTORE%'
    

    或者您可以使用一些神奇的巫术,并在下表函数中解释事务日志,但是我知道的唯一了解日志中任何信息的人是PaulRandal。 我知道他有时会检查服务器故障,但不知道他是否怀疑stackoverflow。

    从fn_dblog中选择*(空,空)

    希望这有帮助。 如果您能使用它并找到解决方案,请告诉我们。

    祝你好运!