Restaurar backup diferencial cria arquivo de log DEFUNCT?

11

Aqui está o meu problema. Estou tentando mover um banco de dados para um novo servidor por meio de uma restauração completa e, em seguida, com um rápido backup / restauração diferencial. Posso fazer uma restauração completa sem problemas, mas ao restaurar o backup diferencial, recebo o seguinte aviso:

Mensagem 3127, Nível 16, Estado 1, Linha 1 O arquivo 'Database_Log2' do banco de dados restaurado 'DatabaseName' está sendo deixado no estado defunct porque o banco de dados está usando o modelo de recuperação simples e o arquivo está marcado para acesso de leitura e gravação. Portanto, apenas os arquivos somente leitura podem ser recuperados pela restauração fragmentada.

O banco de dados restaura e é considerado online, mas qualquer operação de backup falha devido a esse arquivo DEFUNCT com o seguinte erro:

Msg 3636, Nível 16, Estado 2, Linha 1 Ocorreu um erro ao processar os metadados 'BackupMetadata' para o ID de banco de dados 10 ID do arquivo 6. Msg 3046, Nível 16, Estado 2, Linha 1 Metadados inconsistentes foram encontrados. A única operação de backup possível é um backup de log de cauda usando a opção WITH CONTINUE_AFTER_ERROR ou NO_TRUNCATE. A mensagem 3013, nível 16, estado 1, linha 1 BACKUP DATABASE está sendo finalizada de maneira anormal.

Se eu fizer um RESTORE FILELISTONLY no total e no diferencial, ambos me fornecerão a mesma saída, que corresponde ao que eu vejo em sys.database_files no banco de dados de origem. O servidor é o SQL2012 SP1, na edição Developer.

Posso fazer um backup completo e imediatamente fazer um diferencial, e restaurar esses arquivos em um banco de dados diferente no mesmo servidor e ver exatamente o mesmo problema; portanto, há algo na maneira como o diferencial é criado que está causando isso. Se eu restaurar o backup completo com recuperação, não há problema. Não sei se esse arquivo existia nesse banco de dados, mas é perfeitamente possível que ele existisse e foi excluído há muito tempo. Se eu consultar sys.database_files no banco de dados restaurado, o arquivo DEFUNCT terá um valor para drop_lsn, o que parece confirmar isso. Atualmente, no banco de dados de origem, existe apenas um grupo de arquivos (PRIMARY), 4 arquivos de dados e um arquivo de log.

Alguma ideia?

FilamentUnities
fonte
Você poderia nos mostrar as instruções que está usando para fazer backups e restaurações?
21416
Nada fora do comum. RESTAURAR DATABASE NomeBaseDados DE DISCO = 'D: \ Full.bak' COM SUBSTITUIÇÃO, NORECOVERY depois restaurar DATABASE NomeBaseDados DE DISCO = 'D: \ Diff.bak' COM RECUPERAÇÃO
FilamentUnities

Respostas:

5

Aqui estão as etapas para reproduzir isso, testadas no SQL 2012 SP1 Developer Edition. Isso não ocorre no SQL 2008. Para resumir, um banco de dados criado no SQL 2012 enquanto o banco de dados modelo está em recuperação SIMPLE, que possui um backup completo realizado enquanto existe um arquivo de log extra, não pode criar backups diferenciais utilizáveis ​​se esse arquivo de log extra estiver disponível. já excluído.

ALTER DATABASE [model] SET RECOVERY SIMPLE
GO
CREATE DATABASE [DefunctTest]
GO
ALTER DATABASE [DefunctTest] ADD LOG FILE ( NAME = N'DefunctTest_log2', FILENAME = N'D:\DefunctTest_log2.ldf' , SIZE = 25600KB , FILEGROWTH = 10%)
GO
BACKUP DATABASE [DefunctTest] TO DISK = 'D:\DefunctTestPostLogFile.bak' WITH INIT
GO
ALTER DATABASE [DefunctTest]  REMOVE FILE [DefunctTest_log2]
GO

BACKUP DATABASE [DefunctTest] TO DISK = 'D:\DefunctTestFull.bak' WITH INIT
GO
BACKUP DATABASE [DefunctTest] TO DISK = 'D:\DefunctTestDiff.bak' WITH DIFFERENTIAL, INIT
GO
--Show that the backups only have the one log file.
RESTORE FILELISTONLY FROM DISK = 'D:\DefunctTestFull.bak'
RESTORE FILELISTONLY FROM DISK = 'D:\DefunctTestDiff.bak'
GO
RESTORE DATABASE [DefunctTest2] FROM DISK = 'D:\DefunctTestFull.bak' WITH 
MOVE 'DefunctTest' TO 'D:\DefunctTest2.mdf',
MOVE 'DefunctTest_log' TO 'D:\DefunctTest2_log.ldf', REPLACE, NORECOVERY
GO
--This restore will have the error.
RESTORE DATABASE [DefunctTest2] FROM DISK = 'D:\DefunctTestDiff.bak' WITH RECOVERY
GO

USE [DefunctTest2]
SELECT * FROM sys.database_files
GO

Enviei um item do Connect para esse bug aqui . A única maneira de conseguir remover esse arquivo desativado é desanexar o banco de dados e reconectá-lo com ATTACH_REBUILD_LOG.

ATUALIZAÇÃO: O bug que cria esse cenário no meu script de reprodução parece ter sido corrigido por este KB: https://support.microsoft.com/en-us/kb/2830400 . Nos comentários, parece que uma correção adicional está disponível para o SQL2012 / 2014, os cenários parecem muito semelhantes: https://support.microsoft.com/en-us/kb/3009576

FilamentUnities
fonte
Eu incluiria seu script nos comentários de conexão para ajudar as pessoas a se reproduzirem.
Kenneth Fisher
1
Não recebo nenhum erro ao executar seu script no SQL Server 2012 Enterprise Edition, 11.0.3412 (CU9 para SP1)
O script de reprodução está no item Conectar, se você clicar no botão Detalhes.
FilamentUnities
1
Shawn, olhando através das correções no CU do, eu acho que este provavelmente fixo este comportamento: support.microsoft.com/kb/2830400
FilamentUnities
2
Eu tive uma batalha com isso na semana passada e esse tópico me ajudou a resolver o problema, então obrigado. Parece que a correção está no SQL 2012 SP2 CU3: support.microsoft.com/en-us/kb/3009576
Richard