Как узнать, сколько времени занимает восстановление базы данных сервера SQL? - PullRequest
7 голосов
/ 23 сентября 2010

Я пытаюсь написать запрос, который скажет мне, сколько времени заняло восстановление (полное или журнал) на 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 ]

12 голосов
/ 30 сентября 2010

Чтобы найти время восстановления базы данных, я обнаружил, что вы можете использовать этот запрос:

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 всегда равен NULL.

Итак, я пришел ко второму запросу, чтобы попытаться определить время окончания. Прежде всего, я прошу прощения, что это довольно уродливо и вложено как сумасшедший.

В приведенном ниже запросе предполагается следующее:

  1. Когда выполняется восстановление, для этого DatabaseID и ClientProcessID следующая EventSequence содержит требуемый TransactionID.
  2. Затем я иду и нахожу максимальную EventSequence для транзакции
  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

EDIT

Я внес некоторые изменения в запрос, поскольку одна из используемых мной тестовых баз данных чувствительна к регистру и теряет некоторые записи. Я также заметил, что при восстановлении с диска DatabaseID имеет значение null, поэтому сейчас я также обрабатываю это:

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 
5 голосов
/ 25 сентября 2010

Сделай это работой.Затем запустите его как Иов.Затем проверьте View Job History.Затем посмотрите на столбец длительности.

3 голосов
/ 05 октября 2010

Пока он работает, вы можете проверить что-то вроде этого 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%'

Или вы можете использовать магическое вуду и интерпретировать журнал транзакций в следующей табличной функции, однако единственный человек, которого я знаю, понимаетлюбая информация в этом журнале Пол Рэндал.Я знаю, что он иногда проверяет сбой сервера, но не знаю, интересуется ли он StackOverflow.

select * from fn_dblog (NULL, NULL)

Надеюсь, это поможетЕсли вам удастся воспользоваться этим и найти решение, пожалуйста, сообщите нам.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...