¿Restaurar la copia de seguridad diferencial crea el archivo de registro DEFUNCT?

11

Aquí está mi problema. Estoy tratando de mover una base de datos a un nuevo servidor a través de una restauración completa, luego pasar a una copia de seguridad / restauración diferencial rápida. Puedo hacer una restauración completa sin problemas, pero al restaurar la copia de seguridad diferencial, recibo la siguiente advertencia:

Msg 3127, Nivel 16, Estado 1, Línea 1 El archivo 'Database_Log2' de la base de datos restaurada 'DatabaseName' se deja en estado inactivo porque la base de datos está utilizando el modelo de recuperación simple y el archivo está marcado para acceso de lectura-escritura. Por lo tanto, solo los archivos de solo lectura se pueden recuperar mediante la restauración gradual.

La base de datos se restaura y se considera en línea, pero cualquier operación de copia de seguridad falla debido a este archivo DEFUNCT con el siguiente error:

Msg 3636, Nivel 16, Estado 2, Línea 1 Se produjo un error al procesar los metadatos 'BackupMetadata' para la identificación de la base de datos 10, identificación de archivo 6. Msg 3046, Nivel 16, Estado 2, Línea 1 Se han encontrado metadatos inconsistentes. La única operación de copia de seguridad posible es una copia de seguridad de registro de cola utilizando la opción WITH CONTINUE_AFTER_ERROR o NO_TRUNCATE. Msg 3013, Nivel 16, Estado 1, Línea 1 La BASE DE DATOS DE RESPALDO está finalizando de manera anormal.

Si hago un RESTORE FILELISTONLY en full y diferencial, ambos me dan el mismo resultado, que coincide con lo que veo de sys.database_files en la base de datos de origen. El servidor es SQL2012 SP1, en la edición Developer.

Puedo hacer una copia de seguridad completa, e inmediatamente después hacer un diferencial, y restaurar estos archivos a una base de datos diferente en el mismo servidor y ver exactamente el mismo problema, por lo que hay algo con la forma en que se crea el diferencial que está causando esto. Si restauro la copia de seguridad completa CON RECUPERACIÓN no hay problema. No sé si este archivo existía en esta base de datos, pero es muy posible que este archivo existiera y se eliminó hace mucho tiempo. Si consulto sys.database_files en la base de datos restaurada, el archivo DEFUNCT tiene un valor para drop_lsn, que parece confirmar esto. Actualmente en la base de datos de origen solo hay un grupo de archivos (PRIMARIO), 4 archivos de datos y un archivo de registro.

¿Algunas ideas?

FilamentUnities
fuente
¿Podría mostrarnos las declaraciones que está utilizando para hacer las copias de seguridad y las restauraciones?
Jon Seigel
Nada fuera de lo común. RESTAURAR BASE DE DATOS DatabaseName FROM DISK = 'D: \ Full.bak' CON REPLACE, NORECOVERY Luego RESTAURAR DATABASE DatabaseName FROM DISK = 'D: \ Diff.bak' CON RECUPERACIÓN
FilamentUnities

Respuestas:

5

Estos son los pasos para reproducir esto, probados en SQL 2012 SP1 Developer Edition. Esto no ocurre en SQL 2008. Para resumir, una base de datos creada en SQL 2012 mientras la base de datos modelo está en recuperación SIMPLE, que tiene una copia de seguridad completa tomada mientras existe un archivo de registro adicional, no puede crear copias de seguridad diferenciales utilizables si ese archivo de registro adicional es Alguna vez eliminado.

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

Envié un elemento de Connect para este error aquí . La única forma en que he podido eliminar este archivo difunto es desconectar la base de datos y volver a adjuntarla con ATTACH_REBUILD_LOG.

ACTUALIZACIÓN: El error que crea este escenario en mi script de repro parece haber sido corregido por este KB: https://support.microsoft.com/en-us/kb/2830400 . A partir de los comentarios que aparece una solución adicional está disponible para SQL2012 / 2014, los escenarios parecen muy similares: https://support.microsoft.com/en-us/kb/3009576

FilamentUnities
fuente
Incluiría su script en los comentarios de conexión para ayudar a las personas a reproducirse.
Kenneth Fisher
1
No recibo ningún error al ejecutar su script en SQL Server 2012 Enterprise Edition, 11.0.3412 (CU9 para SP1)
La secuencia de comandos de reproducción está en el elemento Conectar, si hace clic en el botón Detalles.
FilamentUnities
1
Shawn, mirando a través de las correcciones en las CU, creo que este probablemente solucionó este comportamiento: support.microsoft.com/kb/2830400
FilamentUnities
2
Tuve una batalla con esto la semana pasada y este hilo me ayudó a resolverlo, así que gracias. Parece que la solución está en SQL 2012 SP2 CU3: support.microsoft.com/en-us/kb/3009576
Richard