显示备份信息(成功和失败)的查询SQL Server


9

我有两个备份两个不同数据库的作业。
作业1备份DB1
作业2备份DB2

由于驱动器1上的空间不足而导致作业1失败,因此DB1 备份失败。要解决该问题,我只需要添加空间。没关系 今天,当这个问题已经发生了一个月时,我被告知这一点。是的,我知道这很疯狂,但这是开发人员


我想要获得DB1的完整备份历史记录。我知道我可以从msdb.dbo.backupset表中检索成功的备份信息,但是我想知道是否存在一个查询,该查询显示数据库的备份失败。

我的下面查询显示了12/31 / 13-1 / 27/14中特定数据库的备份历史记录。信息包括服务器,数据库名称,备份开始和结束时间,备份数据库所需的总时间,数据库大小和备份集名称。

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

有什么办法可以通过修改我的代码来获取这些信息?通过执行针对sysjobhistory和sysjob表运行的sql语句,我能够检索JOB1的历史记录。这可能是一个长镜头。有什么方法可以使用msdb中的sysjobhistory,sysjob,backupset和backupsetmediafamily表生成所需的结果吗?

Answers:


15

令人遗憾的是,backupset它不包含失败的备份,而且我不知道msdb这些备份中还有其他任何存储方式,除非您可以依靠sysjobhistory,它不会包含所有时间(取决于您的保留设置),并且会忽略任何备份备份尝试是在作业上下文之外进行的,并且在备份多个数据库的作业的情况下,这些备份尝试无法区分哪个数据库实际失败,除非它碰巧发生在作业的早期。因为消息传递非常冗长,但却被截断。

如果您绝对知道Job n仅备份一个数据库,并且该作业的每次失败都意味着未备份该数据库(因为在备份成功后该作业也可能会失败,例如,尝试缩小或执行其他维护),那么您可以使用如下查询:

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;

是的,这确实很丑陋,因为sysjobhistory即使在SQL Server 2014中,也仍然存储run_daterun_time作为单独的整数。我敢打赌,做出这个决定的人仍然是整个35号楼的飞镖的背景。它还假设备份是工作的第一步,因此要确保我们正确地进行了比较科学的日期/时间比较,将作业的正确实例与备份的正确实例相关联。哦,我希望如何重新设计用于备份和作业的架构。

如果您想在工作之外扩大范围,则可以在SQL Server错误日志中查找失败的备份(如果尚未循环删除):

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

(但我不知道将输出合并到现有查询中的一种好方法。)

您还可以关联默认跟踪中“丢失”的成功备份,例如

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;

当然,这也依赖于默认跟踪中的数据循环运行,数据库名称未更改等。不幸的是,默认跟踪无法区分成功和失败的备份,并且开始时间将与MSDB不完全匹配数据,但只要您没有循环运行备份,就可以无视。我试图将这些问题合并到查询中。

最后,FULL OUTER JOIN如果backupset的历史记录比默认跟踪的历史记录长,则可能要使用那里。这[Status]稍微改变了语义。

您也可能想尝试一下这个讨厌的东西,尽管我不太幸运。我只能看到当前或最近的状态,所以只有当作业最后一次运行失败时,它才有帮助,并且-像sysjobhistory-无法获得有关任何已尝试但不是通过作业的备份的信息。


非常感谢您的详细说明,但是执行第一个查询时收到错误消息。消息139,级别15,状态1,行0无法将默认值分配给本地变量。消息137,级别15,状态2,第16行必须声明标量变量“ @db”
iamZel 2014年

@iamZel那么你的SQL Server 2005,SQL不Server 2008上
阿龙贝特朗

我是。我忘了提。我正在使用SQL2K5
iamZel 2014年

1
@iamZel我认为您使用SQL Server 2008的原因是因为您使用该版本标记了问题。请仔细标记。
亚伦·伯特兰

sp_readerrorlog对我来说已经足够了。非常感谢Aaron
iamZel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.