Truy vấn hiển thị thông tin sao lưu (thành công và thất bại) SQL Server


8

Tôi có hai công việc sao lưu hai cơ sở dữ liệu khác nhau.
Công việc 1 sao lưu DB1
Công việc 2 sao lưu DB2

DB1 không sao lưu do không gian trống trên Ổ đĩa 1 dẫn đến thất bại trong Công việc 1. Để khắc phục vấn đề đó, tôi chỉ cần thêm không gian. Không có vấn đề gì Tôi đã được nói về điều này ngày hôm nay khi vấn đề đã xảy ra trong một tháng. Vâng tôi biết điều đó thật điên rồ nhưng đó là dev


Tôi muốn có được một lịch sử sao lưu hoàn chỉnh cho DB1. Tôi biết rằng tôi có thể truy xuất thông tin sao lưu thành công từ bảng msdb.dbo.backupset nhưng tôi muốn biết liệu có một truy vấn hiển thị các bản sao lưu thất bại cho cơ sở dữ liệu hay không.

Truy vấn của tôi dưới đây hiển thị lịch sử sao lưu cho một cơ sở dữ liệu cụ thể từ 12/31 / 13-1 / 27/14. Thông tin bao gồm máy chủ, tên cơ sở dữ liệu, Thời gian bắt đầu và kết thúc sao lưu, Tổng thời gian cần thiết để các dbs được sao lưu, kích thước db và tên tập sao lưu.

SELECT  
   distinct CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS Server, 
   msdb.dbo.backupset.database_name,  
   msdb.dbo.backupset.backup_start_date,  
   msdb.dbo.backupset.backup_finish_date, 
 CAST((DATEDIFF(second,  msdb.dbo.backupset.backup_start_date,msdb.dbo.backupset.backup_finish_date)) AS varchar)+ ' secs  ' AS [Total Time] ,

   Cast(msdb.dbo.backupset.backup_size/1024/1024 AS numeric(10,2)) AS 'Backup Size(MB)',   
   msdb.dbo.backupset.name AS backupset_name
FROM   msdb.dbo.backupmediafamily  
   INNER JOIN msdb.dbo.backupset ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id   
--Enter your database below
--and database_name = 'db_name_here'
and msdb.dbo.backupset.backup_start_date>'2013-12-31' and msdb.dbo.backupset.backup_start_date<'2014-01-27 23:59:59'
ORDER BY  
   msdb.dbo.backupset.database_name, 
   msdb.dbo.backupset.backup_start_date

Có cách nào để có được thông tin đó bằng cách sửa đổi mã của tôi không? Tôi có thể truy xuất lịch sử của JOB1 bằng cách thực hiện một câu lệnh sql chạy với bảng sysjobhistory và sysjob. Đây có thể là một cú sút xa Có cách nào tôi có thể sử dụng các bảng sysjobhistory, sysjob, backupset và backupsetmediaf Family trong msdb để tạo ra kết quả tôi muốn không?

Câu trả lời:


15

Đáng buồn thay, backupsetkhông chứa các bản sao lưu thất bại và tôi không biết bất kỳ nơi nào khác trong msdbsố này có thể được lưu trữ, trừ khi bạn có thể dựa vào sysjobhistory, không chứa tất cả thời gian (tùy thuộc vào cài đặt duy trì của bạn) và sẽ bỏ qua mọi thứ các nỗ lực sao lưu được thực hiện bên ngoài bối cảnh của một công việc, và trong trường hợp một công việc sao lưu nhiều cơ sở dữ liệu - sẽ không cung cấp sự khác biệt về cơ sở dữ liệu nào thực sự thất bại, trừ khi nó xảy ra sớm trong công việc - đây là bởi vì tin nhắn khá dài dòng nhưng bị cắt ngắn.

Nếu bạn hoàn toàn biết rằng Job nchỉ sao lưu một cơ sở dữ liệu và mọi thất bại của công việc đó có nghĩa là cơ sở dữ liệu không được sao lưu (vì công việc cũng có thể thất bại sau khi sao lưu thành công, ví dụ: cố gắng thu nhỏ hoặc thực hiện bảo trì khác), sau đó bạn có thể sử dụng một truy vấn như thế này:

DECLARE @job SYSNAME, @db SYSNAME;

SELECT @job = N'Job 1', @db = N'db_name';

SELECT  
   bs.database_name,  
   bs.backup_start_date,  
   bs.backup_finish_date, 
   [Total Time] = CAST((DATEDIFF(SECOND, bs.backup_start_date,bs.backup_finish_date))
     AS VARCHAR(30))+ ' secs',
   CAST(bs.backup_size/1024/1024 AS NUMERIC(10,2)) AS 'Backup Size(MB)',   
   h.[message]
FROM msdb.dbo.sysjobhistory AS h
INNER JOIN msdb.dbo.sysjobs AS j
ON h.job_id = j.job_id
AND h.step_id = 0
LEFT OUTER JOIN msdb.dbo.backupset AS bs
ON bs.database_name = @db
AND ABS(DATEDIFF(SECOND, bs.backup_start_date, CONVERT(DATETIME,CONVERT(CHAR(8), h.run_date) 
  + ' ' + STUFF(STUFF(RIGHT('0'+CONVERT(VARCHAR(6),h.run_time),6),3,0,':'),6,0,':')))) < 5
WHERE j.name = @job
ORDER BY bs.backup_start_date;

Vâng, nó thực sự xấu, bởi vì sysjobhistory, trong SQL Server 2014 thậm chí, lưu trữ run_daterun_timedưới dạng các số nguyên riêng biệt. Tôi cá là bất cứ ai đưa ra quyết định đó vẫn ở trên nền tảng của phi tiêu trên toàn tòa nhà 35. Nó cũng cho rằng sao lưu là bước đầu tiên trong công việc, do đó, so với việc so sánh ngày / giờ khoa học để đảm bảo rằng chúng tôi đúng tương quan với thể hiện đúng của công việc với thể hiện đúng của bản sao lưu. Ồ, làm thế nào tôi muốn tôi có thể thiết kế lại lược đồ cho các bản sao lưu và công việc.

Nếu bạn muốn phạm vi rộng hơn ngoài công việc, bạn có thể tìm kiếm các bản sao lưu thất bại trong nhật ký lỗi Máy chủ SQL (nếu chúng chưa được chuyển đi):

EXEC sp_readerrorlog 0, 1, 'BACKUP failed'; -- current
EXEC sp_readerrorlog 1, 1, 'BACKUP failed'; -- .1 (previous)
EXEC sp_readerrorlog 2, 1, 'BACKUP failed'; -- .2 (the one before that)
....

(Nhưng tôi không biết một cách hay và dễ dàng để kết hợp đầu ra đó vào truy vấn hiện tại của bạn.)

Bạn cũng có thể tương quan các bản sao lưu thành công "thiếu" từ theo dõi mặc định, ví dụ:

DECLARE @path NVARCHAR(260);

SELECT 
   @path = REVERSE(SUBSTRING(REVERSE([path]), 
   CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM    sys.traces
WHERE   is_default = 1;

SELECT dt.DatabaseName, dt.StartTime, bs.backup_start_date, bs.backup_finish_date, 
  [Status] = CASE WHEN bs.backup_start_date IS NULL 
    THEN 'Probably failed'
    ELSE 'Seems like success'
  END
FROM sys.fn_trace_gettable(@path, DEFAULT) AS dt
LEFT OUTER JOIN msdb.dbo.backupset AS bs
ON dt.DatabaseName = bs.database_name
AND ABS(DATEDIFF(SECOND, dt.StartTime, bs.backup_start_date)) < 5
WHERE dt.EventClass = 115 -- backup/restore events
AND UPPER(CONVERT(NVARCHAR(MAX),dt.TextData)) LIKE N'BACKUP%DATABASE%'
--AND dt.DatabaseName = N'db_name' -- to filter to a single database
--AND bs.database_name = N'db_name'
ORDER BY dt.StartTime;

Tất nhiên, điều này cũng dựa trên dữ liệu từ dấu vết mặc định đang quay vòng, tên cơ sở dữ liệu không bị thay đổi, v.v. Và thật không may, dấu vết mặc định không phân biệt giữa các bản sao lưu thành công và thất bại và thời gian bắt đầu sẽ không khớp chính xác với MSDB dữ liệu, nhưng miễn là bạn không chạy các bản sao lưu trong một vòng lặp, điều này sẽ ổn cho việc đánh cầu mắt. Tôi đã cố gắng kết hợp những vấn đề này vào truy vấn.

Cuối cùng, bạn có thể muốn sử dụng FULL OUTER JOINở đó, trong trường hợp backupset có lịch sử lâu hơn dấu vết mặc định. Điều này thay đổi ngữ nghĩa của [Status]một chút.

Bạn cũng có thể muốn thử điều khó chịu này , mặc dù tôi không gặp nhiều may mắn với nó. Tôi chỉ có thể thấy trạng thái hiện tại hoặc gần đây nhất, vì vậy chỉ có ích khi công việc thất bại lần trước khi nó chạy, và - như sysjobhistory- không thể có được thông tin về bất kỳ bản sao lưu nào đã cố gắng nhưng không thông qua công việc.


Cảm ơn bạn rất nhiều vì đã giải thích chi tiết nhưng tôi nhận được một lỗi khi tôi thực hiện truy vấn đầu tiên. Msg 139, Cấp 15, Trạng thái 1, Dòng 0 Không thể gán giá trị mặc định cho biến cục bộ. Msg 137, Cấp 15, Trạng thái 2, Dòng 16 Phải khai báo biến vô hướng "@db"
iamZel

@iamZel thì bạn đang ở trên SQL Server 2005, không phải SQL Server 2008
Aaron Bertrand

Đúng là tôi. Tôi quên đề cập đến. Tôi đang sử dụng SQL2K5
iamZel

1
@iamZel Lý do tôi nghĩ bạn tham gia SQL Server 2008 là vì bạn đã gắn thẻ câu hỏi của mình với phiên bản đó. Vui lòng gắn thẻ cẩn thận.
Aaron Bertrand

sp_readerrorlog là đủ tốt cho tôi. Cảm ơn rất nhiều Aaron
iamZel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.