SQL Server数据库判断最近一次的备份执行结果
1 麻烦的地方
在SQL Server的官方文档里面可以看到备份和还原的表,但是这些表里面只能找到备份成功的相关信息,无法找到备份失败的记录,比如msdb.dbo.backupset。对于一些监控系统未监控作业的情况下,想要监控数据库备份任务执行失败而触发告警规则,有些麻烦。
但是SQL server内部是可以通过查询errorlog来判断数据库备份作业是否成功:

2 获取errorlog的trace表
我们可以借助sys.traces定位到errorlog的trace文件路径,然后通过再通过fn_trace_gettable将errlog的trace文件转换为普通的表来查询即可。
- 定位errorlog的trace文件物理路径
SELECT
REVERSE(
SUBSTRING(
REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])),
260
)
) + N'log.trc'
FROM
sys.traces
WHERE
is_default = 1
输出结果:

2. 得到路径后,使用fn_trace_gettable将errolog的trace文件转换为普通的数据表
SELECT
*
FROM
sys.fn_trace_gettable(
'S:\MSSQL13.MSSQLSERVER\MSSQL\Log\log.trc',
default
)

3. 查找与备份相关的事件记录,在trace文件中对应的EventClass为115,并将所有备份开头的语句筛选出来
SELECT
TextData,Databasename,StartTime
FROM
sys.fn_trace_gettable(
'S:\MSSQL13.MSSQLSERVER\MSSQL\Log\log.trc',
default
)
WHERE
EventClass = 115
AND UPPER(CONVERT(nvarchar(max), TextData)) LIKE 'BACKUP%'

从返回的TextData中没有找到是否关于备份成功或者失败的说明,也没有在其它列中找到相关描述,需要结合msdb.dbo.backupset来判断。
3 结合备份表backupset,判断备份状态
- 筛选出所有数据库的备份任务执行情况

从查询的结果可知,每个成功的备份都有1个开始时间和结束时间,考虑将开始时间与trace文件转换的表进行对比:
A[trace表的获取备份记录和时间]--> B[取得StartTime列]
B[与backupset表对比判断]--> C{是否存在与StartTime列对应的值}
C--存在-->D[备份成功]
C--不存在-->E[备份失败]
从上面取得的结果中形成了具体的思路,下面将trace转换的表的StartTime列与backupset表的backup_start_date列进行对比判断
2. 判断存在对应的值则说明备份成功,不存在则备份失败
SELECT
dt.DatabaseName,
dt.StartTime,
bs.backup_start_date,
bs.backup_finish_date,
[Status] = CASE
WHEN bs.backup_start_date IS NULL THEN (dt.DatabaseName) + '数据库备份失败'
ELSE (dt.DatabaseName) + '数据库备份成功'
END
FROM
sys.fn_trace_gettable(
'S:\MSSQL13.MSSQLSERVER\MSSQL\Log\log.trc',
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
AND UPPER(CONVERT(nvarchar(max), dt.TextData)) LIKE N'BACKUP%'
ORDER BY
dt.StartTime DESC;

4 形成用于告警的SQL语句
完成上面的操作之后,我们已经能够看到所有数据库的备份是成功还是失败的状态,现在还需要将SQL再度细化,输出所有数据库最近一次备份执行成功或者失败的信息:即每个数据库只有一行记录用于说明最近一次的备份状态。
下面有两种写法可以实现,第1种是游标的写法,性能极差,后来找chatgpt一起讨论之后,采用了group by优化,形成第2种写法。
- 第1种,游标查看每个数据库最近一次备份状态
点击查看代码
DBCC FREE
DECLARE @databaseName1 nvarchar(100)
DECLARE @sql nvarchar(4000)
DECLARE db_cursor CURSOR FOR
SELECT name
FROM sys.databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @databaseName1
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = '
SELECT
TOP 1 dt.DatabaseName,
dt.StartTime,
bs.backup_start_date,
bs.backup_finish_date,
[Status] = CASE
WHEN bs.backup_start_date IS NULL THEN (dt.DatabaseName) + ''数据库备份失败''
ELSE (dt.DatabaseName) + ''数据库备份成功''
END
FROM
sys.fn_trace_gettable(
(
SELECT
REVERSE(
SUBSTRING(
REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])),
260
)
) + N''log.trc''
FROM
sys.traces
WHERE
is_default = 1
),
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
AND UPPER(CONVERT(nvarchar(max), dt.TextData)) LIKE N''BACKUP%''
AND dt.DatabaseName=''' + @databaseName1 +''' ORDER BY dt.StartTime DESC'
EXEC sp_executesql @sql
FETCH NEXT FROM db_cursor INTO @databaseName1
END
CLOSE db_cursor
DEALLOCATE db_cursor
可以看到性能极差,查询3条数据耗时24秒,每次游标都要到消耗临时表和进行大量的逻辑读取。
点击查看消耗的资源
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 14,逻辑读取 36 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 98 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 2,逻辑读取 30 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 7,逻辑读取 42 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 31 毫秒,占用时间 = 27 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 2,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 16 毫秒,占用时间 = 23 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(1 行受影响)
表 'backupset'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 468 毫秒,占用时间 = 678 毫秒。
SQL Server 执行时间:
CPU 时间 = 468 毫秒,占用时间 = 678 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 2,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 16 毫秒,占用时间 = 23 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(0 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 406 毫秒,占用时间 = 732 毫秒。
SQL Server 执行时间:
CPU 时间 = 406 毫秒,占用时间 = 732 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 2,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 16 毫秒,占用时间 = 21 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(0 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 422 毫秒,占用时间 = 659 毫秒。
SQL Server 执行时间:
CPU 时间 = 422 毫秒,占用时间 = 660 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 2,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 15 毫秒,占用时间 = 616 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(0 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 375 毫秒,占用时间 = 678 毫秒。
SQL Server 执行时间:
CPU 时间 = 375 毫秒,占用时间 = 678 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 2,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 16 毫秒,占用时间 = 1286 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(1 行受影响)
表 'backupset'。扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 375 毫秒,占用时间 = 781 毫秒。
SQL Server 执行时间:
CPU 时间 = 375 毫秒,占用时间 = 781 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 2,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 31 毫秒,占用时间 = 1608 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 13 毫秒,占用时间 = 13 毫秒。
(1 行受影响)
表 'backupset'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 390 毫秒,占用时间 = 737 毫秒。
SQL Server 执行时间:
CPU 时间 = 406 毫秒,占用时间 = 751 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysobjvalues'。扫描计数 2,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syspalvalues'。扫描计数 0,逻辑读取 14 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysguidrefs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysclsobjs'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'syssingleobjrefs'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'sysdbreg'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 16 毫秒,占用时间 = 20 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 12 毫秒,占用时间 = 12 毫秒。
(0 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 468 毫秒,占用时间 = 2492 毫秒。
SQL Server 执行时间:
CPU 时间 = 484 毫秒,占用时间 = 2505 毫秒。
表 'Worktable'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
SQL Server 执行时间:
CPU 时间 = 16 毫秒,占用时间 = 23 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

- 第2种,使用MAX函数和group by优化
SELECT
[Status] = MAX(CASE
WHEN bs.backup_start_date IS NULL THEN dt.DatabaseName+'数据库备份失败'
ELSE dt.DatabaseName+'数据库备份成功'
END)
FROM
sys.fn_trace_gettable(
(
SELECT
REVERSE(
SUBSTRING(
REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])),
260
)
) + N'log.trc'
FROM
sys.traces
WHERE
is_default = 1
),
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
AND UPPER(CONVERT(nvarchar(max), dt.TextData)) LIKE 'BACKUP%'
GROUP BY
dt.DatabaseName
这次执行只要1秒钟,占用的资源也极低。
SQL Server 分析和编译时间:
CPU 时间 = 15 毫秒,占用时间 = 20 毫秒。
(3 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'backupset'。扫描计数 1,逻辑读取 48 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
SQL Server 执行时间:
CPU 时间 = 469 毫秒,占用时间 = 935 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

截止到此,基本大功告成了。接下来要实现的就是监控系统怎么取得指标和触发告警,具体可以根据不同的监控平台进行配置。
实际上还可以通过xp_readerrorlog来读取errlog更加快速得筛选出备份失败的记录,但本次没有再测试,有兴趣的朋友可以自行参考测试。

SQL Server数据库判断最近一次的备份执行结果的更多相关文章
- 在.Net中进行SQL Server数据库备份与还原操作实用类
#region 类说明 //----------------------------------------------------------------------------- // // 项目 ...
- sql server如何判断数据库是否存在
如何判断数据库是否存在 执行下列的SQL,获得一张表,根据表的行数来判断. select * from master..sysdatabases where name=N'所查询的数据库名 ...
- 关于SQL SERVER数据库学习总结
对于SQL SERFVER数据库也学了有一阵子了,自己也对自己所学做了一些总结. 我们首先学习数据库设计的一些知识点和用SQL语句建库. 设计数据库步骤:需求分析阶段,概要设计阶段,详细设计阶段, 建 ...
- SQL SERVER 数据库备份的三种策略及语句
1.全量数据备份 备份整个数据库,恢复时恢复所有.优点是简单,缺点是数据量太大,非常耗时 全数据库备份因为容易实施,被许多系统优先采用.在一天或一周中预定的时间进行全数据库备份使你不用动什么脑筋 ...
- SQL Server数据库性能优化之SQL语句篇【转】
SQL Server数据库性能优化之SQL语句篇http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 近期项目需要, 做了一 ...
- 5、SQL Server数据库、T-SQL
SQL Server数据库基础 一.安装SQL Server数据库 setup.exe->安装->全新SQL Server独立安装或向现有安装添加功能->输入序列号->下一步- ...
- SQL Server - 数据库初识
在互联网笔试中,常遇到数据库的问题,遂来简单总结,注意,以 Sql Server 数据库为例. 数据库 数据库系统,Database System,由数据库和数据库管理系统组成. 数据库,Data ...
- 你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)
前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的一些问题和解决方法,可点击查看,我们此篇主要介绍的是SQL Server启动过程中关于用户数据库加载的流程, ...
- 转:SQL SERVER数据库中实现快速的数据提取和数据分页
探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页.以下代码说明了我们实例中数据库的“红头文件”一表的部分数据结构: CREATE TABLE [dbo]. ...
- SQL Server数据库学习总结
经过一段时间的学习,也对数据库有了一些认识,数据库基本是由表,关系,操作组成:对于初学者首先要学的 一图胜“十”言:SQL Server 数据库总结 一个大概的总结 经过一段时间的学习,也对数 ...
随机推荐
- Pytorch中tensor的打印精度
1. 设置打印精 Pytorch中tensor打印的数据长度需要使用torch.set_printoptions(precision=xx)进行设置,否则打印的长度会很短,给人一种精度不够的错觉: & ...
- Qt非主线程显示窗口的简易思路
首发于我的个人博客:xie-kang.com 博客内有更多文章,欢迎大家访问 原文地址 Qt 在非主线程是无法显示UI窗口的,如果我们在其它线程中处理完数据,需要使用窗口展示,或者在其它线程需要使用到 ...
- pandas 某几列转为json/dic 格式
#%% import pandas as pd df=pd.read_excel('工作表.xlsx') col_list=list(df.columns) del_col_list =['c','d ...
- 2.27总结——JDBC学习
今天初步了解了Javaweb的JDBC,了解其基础语句,以及连接数据库的方式,但是自我感觉很抽象,实际上手仍有些困难,需要参考模板,增删改查目前进度在增和查,继续努力,争取本学期尽快跟上同学学习进度!
- [ACTF2020 新生赛]Include 1
首先进入靶场可以看到trip 查看源码 点击进入提示我们能不能找到flag 可以看到这里是文件包含,想着包含index.php但是根目录是自动索引的,无论输入什么都是trip页面 又想着包含flag. ...
- jsp页面中的正则表达式--主要用于js判断文本格式
一.方括号[] 举例: 二.^ 三.元字符 举例的话,就可以这么说,要实现要表示整数的话: []就表示输入的文本框里面的数字的第一位,可以这么写--->[1-9] 然后已知\d表示的与[0-9] ...
- 一个由public关键字引发的bug
先来看一段代码: @Service @Slf4j public class AopTestService { public String name = "真的吗"; @Retrya ...
- Typora编辑区域空白过大问题
参考博客:https://blog.csdn.net/m0_55485287/article/details/115207178 在哪个文件编辑? 1.找到使用的主题,打开主题文件夹 2.找到对应的c ...
- Tesseract5+OpenCV4(VS2017+win10)实现OCR识别
一.环境配置 较之前采用cppan进行编译的方式,vcpkg的方式已经发生了许多变化,带来的最大不同就是便捷. 对于在NuGet中能够找到的Vcpkg的export,真的实现了开箱即用 这样的话对于普 ...
- 坚叔:让科幻片的概念变成产品丨编程挑战赛 x 嘉宾分享
前言 本文基于资深创业者@坚叔在「RTE 2022 创新编程挑战赛」宣讲活动中分享内容二次整理. 嘉宾简介:陈坚(坚叔),国内二次元 AR/VR 资深创业者,国内第一批空间虚拟数字化从业人员,获得政府 ...