Query che visualizza le informazioni di backup (riuscite e non riuscite) SQL Server


9

Ho due lavori che eseguono il backup di due database diversi.
Il processo 1 esegue il backup del DB1 Il
processo 2 esegue il backup del DB2 Il

DB1 non riesce a eseguire il backup a causa dello spazio insufficiente sull'unità 1 che causa un errore del processo 1. Per risolvere il problema, ho dovuto solo aggiungere spazio. Nessun problema. Mi è stato detto di questo oggi quando il problema si è verificato per un mese. Sì, lo so che è pazzo ma è dev


Voglio ottenere una cronologia di backup completa per DB1. So che posso recuperare informazioni di backup riuscite dalla tabella msdb.dbo.backupset ma voglio sapere se esiste una query che visualizza backup non riusciti per un database.

La mia query di seguito mostra la cronologia dei backup per un determinato database dal 12/31 / 13-1 / 27/14. Le informazioni includono il server, il nome del database, i tempi di inizio e fine del backup, il tempo totale impiegato per il backup dei dbs, le dimensioni del db e il nome del set di backup.

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'è un modo per ottenere tali informazioni modificando il mio codice? Sono in grado di recuperare la cronologia di JOB1 eseguendo un'istruzione sql che funziona con la tabella sysjobhistory e sysjob. Potrebbe trattarsi di una possibilità. C'è un modo in cui posso usare le tabelle sysjobhistory, sysjob, backupset e backupsetmediafamily in msdb per produrre i risultati che desidero?

Risposte:


15

Purtroppo, backupsetnon contiene backup non riusciti e non sono a conoscenza di nessun altro in msdbquesti casi che può essere archiviato, a meno che tu non possa fare affidamento su di esso sysjobhistory, che non contiene sempre (a seconda delle impostazioni di conservazione) e che ignorerebbe qualsiasi i tentativi di backup effettuati al di fuori del contesto di un lavoro e che - nel caso di un lavoro che esegue il backup di molti database - non fornirebbero una differenziazione su quale database sia effettivamente fallito, a meno che non sia accaduto all'inizio del lavoro - questo è perché la messaggistica è piuttosto dettagliata ma viene troncata.

Se si sa assolutamente che Job nesegue il backup del solo database e che ogni errore di quel processo significa che non è stato eseguito il backup del database (poiché il processo potrebbe anche fallire dopo il backup riuscito, ad esempio tentando di ridurre o eseguire altri interventi di manutenzione), allora potresti usare una query come questa:

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;

Sì, è davvero brutto, perché sysjobhistoryancora, anche in SQL Server 2014, memorizza run_datee run_timecome numeri interi separati. Scommetto che chiunque abbia preso questa decisione è ancora sullo sfondo di freccette in tutto l'edificio 35. Presuppone anche che il backup sia il primo passo nel lavoro, quindi il confronto data / ora piuttosto meno scientifico per assicurarsi che abbiamo correttamente correlata l'istanza corretta del lavoro all'istanza corretta del backup. Oh, come vorrei poter ridisegnare lo schema per backup e lavori.

Se si desidera un ambito più ampio al di fuori del processo, è possibile cercare backup non riusciti nel registro errori di SQL Server (se non sono stati eliminati ciclicamente):

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

(Ma non conosco un modo semplice e piacevole per incorporare quell'output nella tua query esistente.)

È inoltre possibile correlare backup riusciti "mancanti" dalla traccia predefinita, ad es

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;

Naturalmente questo si basa anche sui dati della traccia predefinita che si sposta ciclicamente, sul nome del database che non è stato modificato, ecc. E sfortunatamente, la traccia predefinita non distingue tra backup riusciti e falliti e l'ora di inizio non corrisponderà esattamente all'MSDB dati, ma fintanto che non si eseguono backup in un ciclo, questo dovrebbe andare bene per il bulbo oculare. Ho provato a incorporare questi problemi nella query.

Infine, potresti voler utilizzare un FULL OUTER JOINlì, nel caso in cui il set di backup abbia una cronologia più lunga rispetto alla traccia predefinita. Questo cambia [Status]leggermente la semantica di .

Potresti anche provare questa brutta cosa , anche se non ho avuto molta fortuna. Sono stato in grado di vedere solo lo stato corrente o più recente, in modo che mi sia stato d'aiuto solo quando il lavoro è fallito l'ultima volta che è stato eseguito e - come sysjobhistory- non sono stato in grado di ottenere informazioni su eventuali backup che sono stati tentati ma non attraverso un lavoro.


La ringrazio molto per la spiegazione dettagliata ma ricevo un errore quando eseguo la prima query. Messaggio 139, livello 15, stato 1, riga 0 Impossibile assegnare un valore predefinito a una variabile locale. Messaggio 137, livello 15, stato 2, riga 16 Deve dichiarare la variabile scalare "@db"
iamZel

@iamZel allora sei su SQL Server 2005, non su SQL Server 2008.
Aaron Bertrand

Sì, lo sono. Ho dimenticato di menzionarlo. Sono su SQL2K5
iamZel

1
@iamZel Il motivo per cui pensavo fossi su SQL Server 2008 è perché hai taggato la tua domanda con quella versione. Si prega di taggare attentamente.
Aaron Bertrand

sp_readerrorlog è abbastanza buono per me. Grazie mille Aaron
iamZel
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.