Eu tenho um script de trabalho como este que deve fazer backup do SQL Server 2016 dbs para o armazenamento de blobs do Azure com credencial de chave de armazenamento. Geralmente funciona bem, mas às vezes alguns backups são perdidos (quer dizer, não há arquivo de backup na conta de armazenamento) e não recebo nenhum tipo ou falha de trabalho ou erros no arquivo de log de trabalho. Dbs são apenas ignorados. Percebi que quando o trabalho de backup se sobrepõe aos procedimentos de manutenção, isso acontece com bastante frequência quando altero as vezes em que aconteceu uma vez por mês ou menos. Mas não tenho certeza de que a manutenção (manutenção do índice, dbcc, atualização de estatísticas) seja o motivo dessa anomalia.
Eu gostaria de saber se você teve alguma experiência anterior como essa e pode saber qual é o motivo principal?
A parte interessante é que eu restaurei o checkonly, que também pula bancos de dados. Ele não tenta restaurar esses dbs é por isso que não recebo erros de falha, apenas pula
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
Declarar um cursor sobre sys.databases é um clássico. Às vezes, por qualquer motivo, alguns bancos de dados são ignorados.
Altere o tipo de cursor para STATIC e você provavelmente verá que isso não acontece. Para ter certeza de que esse é o motivo, registre-se em uma tabela sua usando um INSERT dentro do cursor para ter certeza absoluta de que o nome do banco de dados foi retornado (ou não) da consulta do cursor. Ou seja, exclua todos os pontos de interrogação relacionados ao backup.
Enquanto isso, você pode querer adicionar uma condição para o banco de dados estar online. Aqui está um exemplo do meu procedimento sp_dbinfo:
Há dois problemas com seu código.
Seu principal problema: usar um
STATIC
cursor nãosys.databases
pode fazer com que os bancos de dados sejam ignorados.Você tem vulnerabilidades de injeção de SQL. Você poderia citar todos os parâmetros usando
QUOTENAME
, masBACKUP
na verdade permite que tudo seja parametrizado de qualquer maneira, então você pode realmente executarBACKUP
diretamente usando parâmetros, não há necessidade de SQL dinâmico.Você provavelmente deve considerar anexar o tempo ao URL também, pois a execução disso duas vezes falhará.