2010-09-23 37 views
7

Im cố gắng để viết một truy vấn mà sẽ cho tôi biết bao nhiêu thời gian khôi phục (đầy đủ hoặc đăng nhập) đã đưa vào SQL server 2008.Tôi làm cách nào để truy vấn thời gian khôi phục cơ sở dữ liệu máy chủ SQL?

tôi có thể chạy truy vấn này để tìm hiểu bao nhiêu thời gian sao lưu mất:

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 

truy vấn này sẽ cho tôi biết những gì được phục hồi nhưng bây giờ bao nhiêu thời gian nó mất:

select * from msdb..restorehistory 

restorehistory có một cột backup_set_id đó sẽ liên kết đến msdb..backupset, nhưng giữ ngày bắt đầu và ngày kết thúc để sao lưu không phải là khôi phục.

Bất kỳ ý tưởng nào để truy vấn thời gian bắt đầu và kết thúc để khôi phục?

Trả lời

12

Để tìm RESTORE DATABASE thời gian, tôi đã phát hiện ra rằng bạn có thể sử dụng truy vấn này:

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; 

Nhược điểm là, bạn sẽ nhận thấy rằng, ít nhất là trên máy chủ thử nghiệm của tôi, EndTime luôn là NULL .

Vì vậy, tôi đã đưa ra một truy vấn thứ hai để thử và xác định thời gian kết thúc. Trước hết, tôi xin lỗi rằng điều này là khá xấu xí và lồng nhau như điên.

Các truy vấn dưới đây giả định như sau:

  1. Khi khôi phục được điều hành, cho rằng DatabaseID và ClientProcessID, các EventSequence tiếp theo chứa các transactionId chúng ta cần.
  2. Sau đó tôi đi và tìm EventSequence tối đa cho Giao dịch
  3. Cuối cùng, tôi chọn bản ghi có chứa RESTORE DATABASE và giao dịch tối đa được liên kết với hồ sơ đó.

tôi chắc chắn rằng một người nào đó có lẽ có thể lấy những gì tôi đã thực hiện và hoàn thiện nó, nhưng điều này dường như làm việc trên môi trường thử nghiệm của tôi:

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

tôi thực hiện một số thay đổi đối với truy vấn, vì một trong các cơ sở dữ liệu thử nghiệm mà tôi đã sử dụng phân biệt chữ hoa chữ thường và nó đã mất một số bản ghi. Tôi cũng nhận thấy khi khôi phục từ đĩa rằng DatabaseID là null, vì vậy tôi xử lý mà bây giờ cũng như:

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

Thật tuyệt vời. Tôi sẽ chạy asap này trên máy chủ của tôi (s) – edosoft

+0

Truy vấn đầu tiên thực sự trả về thời gian bắt đầu của khôi phục, truy vấn thứ hai trả về không có gì, có thể do tham gia. Tôi đang điều tra ... – edosoft

+0

Điều duy nhất có trong đầu là nếu ID cơ sở dữ liệu không khớp nhau (vì chúng không có giá trị) - hy vọng các chỉnh sửa của tôi sẽ hoạt động cho bạn. – LittleBobbyTables

5

Biến nó thành Công việc. Sau đó, chạy nó như là công việc. Sau đó kiểm tra Xem Lịch sử công việc. Sau đó, xem cột thời lượng.

+0

Cảm ơn. Đây có phải là cách duy nhất không? Tôi thấy khó tin rằng máy chủ SQL không lưu trữ thông tin này ở đâu đó .. – edosoft

+0

Không phải cách duy nhất; chỉ là một cách đơn giản cũng cho phép bạn theo dõi sự khác biệt theo thời gian, vì hệ thống lưu trữ lịch sử công việc trong một khoảng thời gian. –

3

Trong khi nó đang chạy, bạn có thể kiểm tra một cái gì đó giống như DMV này.

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

Hoặc bạn có thể sử dụng ma thuật ma thuật và diễn giải nhật ký giao dịch trong hàm bảng sau, tuy nhiên người duy nhất tôi biết để hiểu bất kỳ thông tin nào trong nhật ký này là Paul Randal. Tôi biết đôi khi anh ta kiểm tra Lỗi máy chủ, nhưng không biết liệu anh ta có tự hỏi StackOverflow hay không.

chọn * từ fn_dblog (NULL, NULL)

Hy vọng điều này sẽ hữu ích. Nếu bạn quản lý để sử dụng điều này và tìm một giải pháp xin vui lòng cho chúng tôi biết.

Chúc may mắn!

Các vấn đề liên quan