Eu tenho um trabalho no SQL 2008 que executa um processo armazenado para fazer backup de todos os bancos de dados. Isso é executado diariamente através do trabalho do agente do servidor sql.
É encerrado com êxito todos os dias, mas alguns dias é encerrado com sucesso somente após o backup de alguns bancos de dados. Pode ser um número diferente de bancos de dados a cada vez. Na maioria dos dias, ele faz backups com êxito de todos os bancos de dados, mas às vezes 2 backups com êxito, às vezes 5, etc.
Não vejo nenhum erro no histórico de tarefas, no visualizador de eventos ou no log do servidor sql.
Os backups estão ocorrendo em um disco local, embora a pasta seja uma "junção" para uma pasta em um volume de armazenamento expansível.
O sistema operacional é o Windows 2003 64 bits executando o Sql Server 2008 web edition de 64 bits como uma máquina virtual em execução no host Vmware ESXi 5.
Procedimento armazenado:
ALTER PROCEDURE [dbo].[backup_all_databases]
@path VARCHAR(255)='c:\backups\'
AS
DECLARE @name VARCHAR(50) -- database name
DECLARE @fileName VARCHAR(256) -- filename for backup
DECLARE @fileDate VARCHAR(20) -- used for file name
DECLARE @dbIsReadOnly sql_variant -- is database read_only?
DECLARE @dbIsOffline sql_variant -- is database offline?
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name NOT IN ('tempdb')
AND version > 0 AND version IS NOT NULL
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @fileName = @path + @name + '.bak'
SET @dbIsReadOnly = (SELECT DATABASEPROPERTY(@name, 'IsReadOnly')) -- 1 = Read Only
SET @dbIsOffline = (SELECT DATABASEPROPERTY(@name, 'IsOffline')) -- 1 = Offline
IF (@dbIsReadOnly = 0 OR @dbIsReadOnly IS NULL) AND @dbIsOffline =0
BEGIN
BACKUP DATABASE @name TO DISK = @fileName WITH INIT
WAITFOR DELAY '00:00:20'
END
FETCH NEXT FROM db_cursor INTO @name
END
CLOSE db_cursor
DEALLOCATE db_cursor
Alguma sugestão, por favor?
fonte
Verifique se há erros após o comando "backup", envie seu próprio e-mail para detectar erros.
Isso fornecerá um ponto de partida para ver o que está acontecendo e garantirá alertá-lo sobre qualquer problema até que você resolva o problema do trabalho.
fonte
Coloque uma ordem no cursor. Já vi cursores para sys.databases terem "problemas" quando você permite que o SQL selecione a ordem em que os dados são retornados. Ordenação por nome deve ser suficiente.
fonte
O backup está sendo executado ao mesmo tempo em que o backup em fita ou algum outro processo está copiando ou acessando os arquivos de backup? Nesse caso, aposto que está falhando em substituir o arquivo porque está em uso. Se você tiver espaço para várias cópias de backup, poderá alterar seu processo para adicionar um carimbo de data ao arquivo de saída, mas precisará de uma rotina de limpeza.
fonte
Com a introdução do SQL Server 2005, o cursor percorreu sysdatabases e até sys.databases parecia mudar, por isso não era confiável - e essa mudança de comportamento também pode ser vista com sp_foreachdb.
Achei que mudar o tipo de cursor ajudou (acho que foi rápido), mas no final mudei para soluções como a solução de manutenção e backup de Ola Hallengren. Como a maioria das coisas críticas, como backups, você ainda precisa fazer uma verificação cruzada de todos os bancos de dados para garantir o backup mesmo com essas soluções em potencial - e você obviamente fez isso, muito bem!
Tipos de cursor: http://msdn.microsoft.com/en-us/library/ms378405(v=SQL.90).aspx
Solução de manutenção da Ola: http://ola.hallengren.com/
fonte
Eu tive o mesmo problema, especialmente ao fazer backup de bancos de dados grandes.
@@fetch_status
é uma variável GLOBAL, portanto, pode ser alterada (definida como 0) por outro cursor que não o seu. Eu o resolvi fazendo o seguinte (em pseudocódigo):fonte
Eu tentei descobrir esse problema e parece que muitas vezes os usuários postaram a solução que, se você tornar a declaração do cursor insensível, ela começará a funcionar. Então eu testei e sim, apenas certifique-se de que o cursor declare estático e comece a funcionar.
O fato pelo qual falha é: - Verifique a configuração de limite do cursor no nível do servidor - se estiver configurado como -1, significa que todos os cursores estão sendo preenchidos de forma síncrona em outras palavras, enquanto tentam ler os dados do conjunto de teclas do cursor são síncronos e tudo tenta leia ao mesmo tempo. Se alterarmos esse valor para 0, que informa ao SQL Server para preencher uma população assíncrona em palavras simples, o cursor pode buscar os registros enquanto o conjunto de chaves ainda está sendo preenchido e você verá que, após fazer essa alteração no nível do servidor, nunca perderá nenhum banco de dados usando cursores.
Soluções: declare a estática do cursor ou altere a configuração no nível do servidor "Limite do cursor" para 0 de -1.
Obrigado, Gaurav Mishra | DBA Sênior
fonte