2010-09-23 23 views
7

Im Versuch, eine Abfrage zu schreiben, die mir sagen, wie viel Zeit ein (voll oder log) wiederherstellen auf SQL Server 2008Wie kann ich abfragen, wie lange eine SQL Server-Datenbankwiederherstellung dauert?

genommen hat, kann ich diese Abfrage ausführen, wie viel Zeit, um herauszufinden, die Sicherung nahm:

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 

Diese Abfrage wird mir sagen, was wiederhergestellt wird, aber jetzt, wie viel Zeit es dauerte:

select * from msdb..restorehistory 

restorehistory hat eine Spalte backup_set_id die auf 0 verbinden wird, aber das halten das Start- und Enddatum für die Sicherung nicht die Wiederherstellung.

Haben Sie eine Idee, wo Sie die Start- und Endzeit für Wiederherstellungen abfragen können?

Antwort

12

Um die Datenbank zu Zeit RESTORE, ich habe herausgefunden, dass finden Sie diese Abfrage verwenden können:

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; 

Der Nachteil ist, werden Sie feststellen, dass, zumindest auf meinem Test-Server, ist die EndTime immer NULL .

Also kam ich mit einer zweiten Abfrage, um zu versuchen, die Endzeit zu bestimmen. Vor allem entschuldige ich mich, dass dies ziemlich hässlich und verschachtelt ist.

Die Abfrage unter nimmt die folgenden:

  1. Wenn eine Wiederherstellung ausgeführt wird, für die DatabaseID und ClientProcessID, der nächste EventSequence enthält die TransactionID wir brauchen.
  2. Ich gehe dann und finde die maximale EventSequence für die Transaktion
  3. Schließlich wähle ich den Datensatz, der RESTORE DATABASE enthält und die maximale Transaktion mit diesem Datensatz verbunden ist.

Ich bin sicher, dass jemand kann wohl nehmen, was ich habe es getan und verfeinern, aber das ist in meiner Testumgebung zu arbeiten:

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

ich einige gemacht Änderungen an der Abfrage, da eine der Testdatenbanken die Groß-/Kleinschreibung berücksichtigt und einige Datensätze verloren hat. Ich habe auch bemerkt, wenn von der Festplatte wiederherstellen, die DatabaseID null ist, also bin ich Umgang dass jetzt auch:

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 
+0

Das ist großartig. Ich werde das so bald wie möglich auf meinem Server (n) ausführen – edosoft

+0

Die erste Abfrage gibt tatsächlich die Startzeit der Wiederherstellungen zurück, die zweite Abfrage gibt nichts zurück, möglicherweise aufgrund eines Joins. Ich untersuche ... – edosoft

+0

Die einzige Sache, die in den Sinn kommt, ist, wenn die Datenbank-IDs nicht übereinstimmten (weil sie null waren) - hoffentlich werden meine Änderungen für Sie arbeiten. – LittleBobbyTables

5

Machen Sie es zu einem Job. Dann führe es als Job aus. Dann überprüfen Sie den Jobverlauf anzeigen. Dann schau dir die Dauerspalte an.

+0

Danke. Ist das wirklich der einzige Weg? Ich finde es schwer zu glauben, dass SQL Server diese Information nicht irgendwo speichert. – edosoft

+0

Nicht der einzige Weg; Auf diese einfache Weise können Sie auch Unterschiede im Zeitverlauf verfolgen, da das System die Jobhistorie für einen bestimmten Zeitraum speichert. –

3

Während es läuft, können Sie so etwas wie dieses DMV überprüfen.

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%' 

Oder Sie können etwas Magie Voodoo verwenden und das Transaktionsprotokoll in der folgenden Tabelle Funktion interpretieren, aber die einzige Person, die ich kenne alle Infos in diesem Protokoll zu verstehen ist Paul Randal. Ich weiß, er überprüft manchmal Serverfehler, aber weiß nicht, ob er StackOverflow wundert.

select * from fn_dblog (NULL, NULL)

Hoffnung, das hilft. Wenn Sie es schaffen und eine Lösung finden, teilen Sie uns dies bitte mit.

Viel Glück!