2010-09-23 5 views
7

Im essayant d'écrire une requête qui me dire combien de temps une restauration (complète ou journal) a pris sur le serveur SQL 2008.Comment puis-je demander combien de temps prend une restauration de base de données SQL Server?

Je peux exécuter cette requête pour savoir combien de temps la sauvegarde a pris:

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 

Cette requête me dira ce est restauré mais maintenant combien de temps il a fallu:

select * from msdb..restorehistory 

restorehistory a une colonne backup_set_id qui reliera à msdb..backupset, mais qui contiennent la date de début et de fin pour la sauvegarde pas la restauration.

Une idée où interroger l'heure de début et de fin pour les restaurations?

Répondre

12

Pour trouver le RESTORE temps DATABASE, j'ai trouvé que vous pouvez utiliser cette requête:

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; 

L'inconvénient est, vous remarquerez que, au moins sur mon serveur de test, le EndTime est toujours NULL . Donc, je suis venu avec une deuxième requête pour essayer de déterminer l'heure de fin. Tout d'abord, je m'excuse que c'est assez moche et imbriqué comme un fou.

La requête ci-dessous suppose ce qui suit:

  1. Lorsqu'une restauration est exécuté, pour que DatabaseID et ClientProcessID, la prochaine EventSequence contient le TransactionID nous avons besoin.
  2. Ensuite, je vais trouver le maximum EventSequence pour la transaction
  3. Enfin, je sélectionne l'enregistrement qui contient RESTORE DATABASE et la transaction maximale associée à cet enregistrement.

Je suis sûr que quelqu'un peut probablement prendre ce que je l'ai fait et l'affiner, mais cela semble fonctionner sur mon environnement de test:

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

J'ai fait quelques modifications apportées à la requête, car l'une des bases de données de test que j'ai utilisées est sensible à la casse et perdait certains enregistrements. J'ai aussi remarqué lors de la restauration à partir du disque que la DatabaseID est nulle, donc je me occupe maintenant ainsi:

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

C'est génial. Je vais lancer ceci dès que possible sur mon/mes serveur (s) – edosoft

+0

La première requête renvoie en effet l'heure de début des restaurations, la deuxième requête ne renvoie rien, peut-être en raison d'une jointure. J'étudie ... – edosoft

+0

La seule chose qui vient à l'esprit est si les ID de base de données ne correspondaient pas (parce qu'ils étaient null) - j'espère que mes modifications fonctionneront pour vous. – LittleBobbyTables

5

Faites-en un travail. Ensuite, exécutez-le comme le travail. Ensuite, vérifiez l'historique des tâches. Ensuite, regardez la colonne de durée.

+0

Merci. Est-ce vraiment le seul moyen? J'ai du mal à croire que SQL Server ne stocke pas ces informations quelque part .. – edosoft

+0

Pas le seul moyen; juste un moyen simple qui vous permet également de suivre les différences au fil du temps, puisque le système stocke l'historique des travaux pour une période de temps. –

3

Alors qu'il est en cours d'exécution, vous pouvez vérifier quelque chose comme ça 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%' 

Ou vous pouvez utiliser la magie vaudou et interpréter le journal des transactions dans la fonction tableau ci-dessous, mais la seule personne que je connaisse à comprendre toute information dans ce journal est Paul Randal. Je sais qu'il vérifie parfois Server Fault, mais ne sait pas s'il s'interroge sur StackOverflow.

select * from fn_dblog (NULL, NULL)

Hope this helps. Si vous parvenez à utiliser ceci et à trouver une solution, veuillez nous en informer.

Bonne chance!

Questions connexes