2010-09-23 27 views
7

Im tratando de escribir una consulta que me diga cuánto tiempo una restauración (completa o de registro) ha tomado en el servidor SQL 2008.¿Cómo puedo consultar cuánto tiempo tarda una restauración de la base de datos del servidor SQL?

puedo ejecutar esta consulta para averiguar cuánto tiempo tomó la copia de seguridad:

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 

Esta consulta me dirá lo que se restaura pero ahora la cantidad de tiempo que tomó:

select * from msdb..restorehistory 

restorehistory tiene una columna backup_set_id que unirá a msdb..backupset, pero que contienen la fecha de inicio y finalización para la copia de seguridad y no la restauración.

¿Alguna idea de dónde consultar el tiempo de inicio y finalización de las restauraciones?

Respuesta

12

para encontrar el tiempo RESTORE DATABASE, he encontrado que se puede utilizar esta consulta:

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; 

La desventaja es, usted notará que, al menos en mi servidor de prueba, el EndTime siempre es NULL .

Entonces, se me ocurrió una segunda consulta para tratar de determinar la hora de finalización. Antes que nada, me disculpo porque esto es bastante feo y anidado como loco.

La consulta siguiente se supone lo siguiente:

  1. Cuando una restauración se ejecuta, para que DatabaseID y ClientProcessID, el siguiente EventSequence contiene TransactionID que necesitamos.
  2. Luego, voy y encuentro el máximo EventSequence para la transacción
  3. Finalmente, selecciono el registro que contiene RESTORE DATABASE y la transacción máxima asociada con ese registro.

estoy seguro de que alguien probablemente puede tomar lo que he hecho y refinarlo, pero esto parece funcionar en mi entorno de prueba:

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 

EDITAR

hice un poco cambios en la consulta, ya que una de las bases de datos de prueba que utilicé distingue entre mayúsculas y minúsculas y estaba perdiendo algunos registros. También me di cuenta al restaurar desde el disco que la DatabaseID es nula, por lo que estoy manejando ahora así:

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

Eso es asombroso. Lo ejecutaré lo antes posible en mi (s) servidor (es) – edosoft

+0

La primera consulta realmente devuelve la hora de inicio de las restauraciones, la segunda consulta no devuelve nada, tal vez debido a una unión. Estoy investigando ... – edosoft

+0

Lo único que me viene a la mente es si las ID de la base de datos no coincidían (porque eran nulas); espero que mis ediciones funcionen para usted. – LittleBobbyTables

5

Make it a Job. Luego ejecútalo como el Trabajo. Luego, verifique el historial de trabajos. Luego mira la columna de duración.

+0

Gracias. ¿Es esta realmente la única manera? Me resulta difícil creer que el servidor SQL no almacena esta información en algún lugar. – edosoft

+0

No es la única manera; solo una forma sencilla que también le permite rastrear las diferencias a lo largo del tiempo, ya que el sistema almacena el historial de trabajo por un período de tiempo. –

3

Mientras se está ejecutando se puede comprobar algo como esto 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%' 

O puede usar un poco de magia vudú e interpretar el registro de transacciones en la siguiente función de tabla, sin embargo, la única persona que conozco para comprender cualquier información en este registro es Paul Randal. Sé que a veces comprueba la falla del servidor, pero no sé si se pregunta StackOverflow.

SELECT * FROM fn_dblog (NULL, NULL)

Espero que esto ayude. Si logras utilizar esto y encuentras una solución, dínoslo.

¡Buena suerte!

Cuestiones relacionadas