Kueri yang menampilkan informasi cadangan (berhasil dan gagal) SQL Server

9

Saya memiliki dua pekerjaan yang mendukung dua basis data yang berbeda.
Pekerjaan 1 mencadangkan DB1
Pekerjaan 2 mencadangkan DB2

DB1 gagal mencadangkan karena ruang yang rendah pada Drive 1 mengakibatkan kegagalan pekerjaan 1. Untuk memperbaiki masalah itu, saya hanya perlu menambah ruang. Bukan masalah besar. Saya diberitahu tentang ini hari ini ketika masalah telah terjadi selama sebulan. Ya saya tahu ini gila tapi dev


Saya ingin mendapatkan riwayat cadangan lengkap untuk DB1. Saya tahu bahwa saya dapat mengambil informasi cadangan yang berhasil dari tabel msdb.dbo.backupset tetapi saya ingin tahu apakah ada kueri yang menampilkan cadangan gagal untuk database.

Kueri saya di bawah ini menampilkan riwayat cadangan untuk database tertentu mulai 12/31 / 13-1 / 27/14. Info termasuk server, nama database, waktu mulai dan akhir Pencadangan, Total waktu yang dibutuhkan untuk membuat cadangan dbs, ukuran db, dan nama cadangan.

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

Apakah ada cara untuk mendapatkan informasi itu dengan memodifikasi kode saya? Saya dapat mengambil sejarah JOB1 dengan mengeksekusi pernyataan sql yang bertentangan dengan tabel sysjobhistory dan sysjob. Ini mungkin merupakan pukulan panjang. Apakah ada cara saya dapat menggunakan tabel sysjobhistory, sysjob, backupset dan backupsetmediafamily di msdb untuk menghasilkan hasil yang saya inginkan?

iamZel
sumber

Jawaban:

15

Sayangnya, backupsettidak mengandung cadangan yang gagal, dan saya tidak tahu di mana pun di dalamnya msdbdapat disimpan, kecuali jika Anda dapat mengandalkan sysjobhistory, yang tidak mengandung semua waktu (tergantung pada pengaturan penyimpanan Anda), dan yang akan mengabaikan upaya cadangan yang dilakukan di luar konteks pekerjaan, dan yang - dalam kasus pekerjaan yang membuat cadangan banyak basis data - tidak akan memberikan diferensiasi tentang basis data yang sebenarnya gagal, kecuali jika itu terjadi pada awal pekerjaan - ini adalah karena pesannya cukup bertele-tele tetapi akan terpotong.

Jika Anda benar-benar tahu bahwa Job nhanya membuat cadangan satu database, dan bahwa setiap kegagalan pekerjaan itu berarti bahwa database tidak didukung (karena pekerjaan itu juga bisa gagal setelah cadangan berhasil, misalnya mencoba mengecilkan atau melakukan pemeliharaan lainnya), maka Anda dapat menggunakan kueri seperti ini:

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 decimal(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(char(6),h.run_time),6),3,0,':'),6,0,':')))) < 5
WHERE j.name = @job
ORDER BY bs.backup_start_date;

Ya, ini benar-benar jelek, karena sysjobhistorymasih, bahkan di SQL Server 2014, menyimpan run_datedan run_timesebagai bilangan bulat terpisah. Saya bertaruh siapa pun yang membuat keputusan itu masih berlatar belakang papan dart di seluruh gedung 35. Ini juga mengasumsikan bahwa cadangan adalah langkah pertama dalam pekerjaan, maka perbandingan tanggal / waktu yang kurang ilmiah untuk memastikan kami sudah benar mengkorelasikan instance pekerjaan yang tepat dengan instance cadangan yang tepat. Oh, betapa aku berharap bisa mendesain ulang skema untuk cadangan dan pekerjaan.

Jika Anda ingin cakupan yang lebih luas di luar pekerjaan, Anda dapat mencari cadangan yang gagal di log galat SQL Server (jika belum didaur ulang):

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)
....

(Tapi saya tidak tahu cara yang bagus dan mudah untuk memasukkan output itu ke dalam permintaan Anda yang sudah ada.)

Anda juga dapat mengkorelasikan cadangan yang "hilang" yang berhasil dari jejak default, misalnya

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;

Tentu saja ini juga bergantung pada data dari jejak default yang hilang, nama basis data tidak berubah, dll. Dan sayangnya, jejak default tidak membedakan antara cadangan yang berhasil dan yang gagal, dan waktu mulai tidak akan sama persis dengan MSDB data, tetapi selama Anda tidak menjalankan cadangan dalam satu lingkaran, ini seharusnya baik-baik saja untuk eyeballing. Saya sudah mencoba memasukkan masalah ini ke dalam kueri.

Akhirnya, Anda mungkin ingin menggunakan FULL OUTER JOINsana, jika backupset memiliki riwayat yang lebih lama daripada jejak default. Ini mengubah semantik [Status]sedikit.

Anda juga mungkin ingin mencoba hal jahat ini , meskipun saya tidak beruntung dengan itu. Saya hanya dapat melihat status saat ini atau terbaru, sehingga hanya membantu ketika pekerjaan gagal saat terakhir kali dijalankan, dan - seperti sysjobhistory- tidak dapat memperoleh informasi tentang cadangan yang dicoba tetapi tidak melalui pekerjaan.

Aaron Bertrand
sumber
Terima kasih banyak untuk penjelasan terperinci tetapi saya menerima kesalahan ketika saya menjalankan permintaan pertama. Msg 139, Level 15, State 1, Line 0 Tidak dapat menetapkan nilai default ke variabel lokal. Msg 137, Level 15, State 2, Line 16 Harus mendeklarasikan variabel skalar "@db"
iamZel
@iamZel maka Anda menggunakan SQL Server 2005, bukan SQL Server 2008.
Aaron Bertrand
Ya, benar. Saya lupa menyebutkan itu. Saya menggunakan SQL2K5
iamZel
1
@iamZel Alasan saya pikir Anda menggunakan SQL Server 2008 adalah karena Anda menandai pertanyaan Anda dengan versi itu. Harap beri tag dengan hati-hati.
Aaron Bertrand
sp_readerrorlog cukup baik untuk saya. Terima kasih banyak Aaron
iamZel