web-dev-qa-db-ja.com

差分バックアップを復元すると、DEFUNCTログファイルが作成されますか?

これが私の問題です。完全な復元を介してデータベースを新しいサーバーに移動してから、差分バックアップ/復元をすばやく実行しようとしています。問題なく完全に復元できますが、差分バックアップを復元すると、次の警告が表示されます。

メッセージ3127、レベル16、状態1、行1復元されたデータベース 'DatabaseName'のファイル 'Database_Log2'は、データベースが単純復旧モデルを使用しており、ファイルが読み取り/書き込みアクセス用にマークされているため、無効な状態のままです。そのため、断片的な復元で復元できるのは読み取り専用ファイルのみです。

データベースは復元され、オンラインと見なされますが、このDEFUNCTファイルが原因でバックアップ操作が失敗し、次のエラーが発生します。

メッセージ3636、レベル16、状態2、行1データベースID 10ファイルID 6の「BackupMetadata」メタデータの処理中にエラーが発生しました。メッセージ3046、レベル16、状態2、行1一貫性のないメタデータが検出されました。可能なバックアップ操作は、WITH CONTINUE_AFTER_ERRORまたはNO_TRUNCATEオプションを使用したログ末尾のバックアップのみです。メッセージ3013、レベル16、状態1、行1のBACKUP DATABASEが異常終了しています。

フルと差分でRESTORE FILELISTONLYを実行すると、同じ出力が得られます。これは、ソースデータベースのsys.database_filesから見たものと一致します。サーバーはSQL2012 SP1のDeveloperエディションです。

フルバックアップを実行してすぐに差分を作成し、これらのファイルを同じサーバー上の別のデータベースに復元すると、まったく同じ問題が発生するため、差分の作成方法に原因があります。 RECOVERYを使用して完全バックアップを復元しても問題はありません。このファイルが以前このデータベースに存在していたかどうかはわかりませんが、このファイルが以前から存在し、かなり前に削除された可能性は十分にあります。復元されたデータベースでsys.database_filesを照会すると、DEFUNCTファイルにはdrop_lsnの値があり、これはこれを確認しているようです。現在、ソースデータベースには、ファイルグループ(PRIMARY)が1つ、データファイルが4つ、ログファイルが1つしかありません。

何か案は?

11
FilamentUnities

これを再現する手順を以下に示します。SQL2012 SP1 Developer Editionでテストされています。これはSQL 2008では発生しません。要約すると、モデルデータベースが単純復旧中にSQL 2012で作成されたデータベースは、追加のログファイルが存在する間に完全バックアップが作成され、追加のログファイルが存在する場合、使用可能な差分バックアップを作成できません。削除されました。

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

このバグの接続アイテムを送信しました here 。この無効なファイルを削除できる唯一の方法は、データベースをデタッチし、ATTACH_REBUILD_LOGを使用して再アタッチすることです。

更新:この再現スクリプトでこのシナリオを作成するバグは、このKB: https://support.Microsoft.com/en-us/kb/28304 で修正されたようです。コメントから、SQL2012/2014に追加の修正が利用可能であるように見えますが、シナリオは非常に似ています: https://support.Microsoft.com/en-us/kb/3009576

5
FilamentUnities