我有一个这样的作业脚本,它应该使用存储密钥凭据将 SQL Server 2016 dbs 备份到 Azure blob 存储。通常它工作正常,但有时会丢失一些备份(我的意思是存储帐户上没有备份文件)并且我没有得到任何类型或作业失败或作业日志文件上的错误。数据库只是被跳过。我注意到,当备份工作与维护程序重叠时,当我更改时间时,这种情况经常发生,它每月或更少发生一次。但我不确定维护(索引维护、dbcc、统计更新)是导致此异常的原因。
我想知道你之前有没有这样的经历,可能知道核心原因是什么?
有趣的部分是我恢复了verifyonly,它也只是跳过了数据库。它不会尝试恢复那些数据库,这就是为什么我没有收到失败错误,只是跳过
DECLARE @dbname sysname
DECLARE @path nvarchar(120)
DECLARE @credential sysname = 'BackupStorageCredential'
DECLARE @date nvarchar(250) = CAST( GETDATE() AS Date )
SET @path = N'[my_storage_url]'
DECLARE db_cursor CURSOR FOR
SELECT name FROM sys.databases
WHERE name IN ('db1','db2','db3')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @query_backupToAzBLOB NVARCHAR(max)
DECLARE @query_verify NVARCHAR(max)
SET @query_backupTOAzBLOB = 'BACKUP DATABASE [' + @dbname + '] TO URL =''' + @path + @dbname + '/' + @dbname + '_' + @date +'.bak''
WITH CREDENTIAL = ''' + @credential + ''',NOFORMAT, NOINIT, NAME =''' + @dbname + ''',
NOSKIP, NOREWIND, NOUNLOAD, COMPRESSION, STATS = 10, CHECKSUM'
EXEC (@query_backupTOAzBLOB)
SET @query_verify = 'RESTORE VERIFYONLY FROM URL =''' + @path + @dbname + '/' + @dbname + '_' + @date +'.bak''
WITH CREDENTIAL = ''' + @credential + ''', FILE = 1, NOUNLOAD, STATS = 5'
EXEC(@query_verify)
FETCH NEXT FROM db_cursor INTO @dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor
在 sys.databases 上声明游标是经典的。有时,出于某种原因,某些数据库会被跳过。
将游标类型更改为 STATIC,您可能会发现这不会发生。要确定这是原因,请在游标内使用 INSERT 登录到您的表,以绝对确定从游标查询返回(或不返回)数据库名称。即,排除所有与备份相关的问号。
在此期间,您可能希望为数据库添加一个在线条件。这是我的 sp_dbinfo 过程中的一个示例:
您的代码有两个问题。
您的主要问题:使用非
STATIC
光标悬停sys.databases
可能会导致数据库被跳过。您有 SQL 注入漏洞。您可以使用 引用所有参数
QUOTENAME
,但BACKUP
实际上无论如何都允许对所有参数进行参数化,因此您实际上可以BACKUP
直接使用参数执行,不需要动态 SQL。您可能还应该考虑将时间附加到 URL,因为执行两次将失败。