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 数据库总结 一个大概的总结 经过一段时间的学习,也对数 ...
随机推荐
- 测试环境docker化实践
测试环境对于任何一个软件公司来讲,都是核心基础组件之一.测试环境伴随着发展也从单一的几套环境发展成现在的任意的docker动态环境+docker稳定环境环境体系.期间环境系统不断的演进,去适应集群扩张 ...
- AreEngine 求最小面积的外接矩形,非IEnvelope,表达不清楚了
1,总是会得到一些奇奇怪怪的要求,求一个面对象的外接最小面积的矩形,和ArcToolBox中的Mininum Bounding Geometry功能下的RECTANGLE_BY_AREA想似.具体看下 ...
- springboot整合flowable-初步入门
最近工作中有用到工作流的开发,引入了flowable工作流框架,在此记录一下springboot整合flowable工作流框架的过程,以便后续再次使用到时可以做一些参考使用,如果项目中有涉及到流程审批 ...
- XSS(Cross-site Scripting)-跨站脚本
XSS介绍 XSS 是基于 JavaScript 的,因此对该语言有基本的了解会很有帮助.了解XSS需要对客户端-服务器请求和响应有基本的了解 跨站点脚本,在网络安全社区中更广为人知的是 XSS,被归 ...
- Matlab笔记--Matlab概述(初登场)
Matlab概述 安装MATLAB教程 可以参考这里:https://www.cnblogs.com/sixuwuxian/p/15858196.html Matlab的启动 右键图标,选择属性,可以 ...
- 关于Spring注解的基础详解(补充上次并不清楚的内容)
注解,需要在.xml文件里面加这么一句话:<context:component-scan base-package=""/>(组件) Component注解 主要用于接 ...
- Linux0.11源码学习(四)
Linux0.11源码学习(四) linux0.11源码学习笔记 参考资料: https://github.com/sunym1993/flash-linux0.11-talk https://git ...
- 19.new和delete用于数组
程序1: //2022年9月20日22:06:27 #include <iostream> #pragma warning(disable:4996) using namespace st ...
- Spring 依赖注入有哪几种方式
1. 构造器注入 /*带参数,方便利用构造器进行注入*/ public CatDaoImpl(String message){ this. message = mess ...
- 集成Health Kit时因证书问题出现错误码50063的解决方案
一.问题描述及操作 应用集成Health Kit SDK后,在华为手机上进行登录授权时,返回错误码50063. 1.查看相关错误码.'50063'在Health Kit错误码中的描述是"安装 ...