Przywrócenie różnicowej kopii zapasowej powoduje utworzenie pliku dziennika DEFUNCT?

11

Oto mój problem. Próbuję przenieść bazę danych na nowy serwer za pomocą pełnego przywracania, a następnie przełączania z szybką różnicową kopią zapasową / przywracaniem. Mogę wykonać pełne przywracanie bez problemu, ale podczas przywracania różnicowej kopii zapasowej pojawia się następujące ostrzeżenie:

Msg 3127, poziom 16, stan 1, wiersz 1 Plik „Database_Log2” przywróconej bazy danych „DatabaseName” jest pozostawiony w stanie nieczynnym, ponieważ baza danych korzysta z prostego modelu odzyskiwania, a plik jest oznaczony do odczytu i zapisu. Dlatego tylko fragmentaryczne przywracanie można odzyskać.

Baza danych zostaje przywrócona i jest uważana za online, ale żadna operacja tworzenia kopii zapasowej kończy się niepowodzeniem z powodu tego pliku DEFUNCT z następującym błędem:

Msg 3636, poziom 16, stan 2, wiersz 1 Wystąpił błąd podczas przetwarzania metadanych „BackupMetadata” dla identyfikatora pliku identyfikatora bazy danych o identyfikatorze 6. Msg 3046, poziom 16, stan 2, wiersz 1 Wystąpiły niespójne metadane. Jedyną możliwą operacją tworzenia kopii zapasowej jest tworzenie kopii zapasowej dziennika ogona przy użyciu opcji Z CONTINUE_AFTER_ERROR lub NO_TRUNCATE. Msg 3013, poziom 16, stan 1, wiersz 1 KOPIA ZAPASOWA kończy się nieprawidłowo.

Jeśli wykonam RESTORE FILELISTONLY na pełny i różnicowy, oba dają mi takie same dane wyjściowe, co odpowiada temu, co widzę z sys.database_files w źródłowej bazie danych. Serwer to SQL2012 SP1 w wersji dla programistów.

Mogę wykonać pełną kopię zapasową, a następnie natychmiast wykonać różnicę i przywrócić te pliki do innej bazy danych na tym samym serwerze i zobaczyć dokładnie ten sam problem, więc przyczyną tego jest sposób tworzenia różnic. Jeśli przywrócę pełną kopię zapasową Z ODZYSKIEM, nie będzie problemu. Nie wiem, czy ten plik istniał w tej bazie danych, ale jest całkiem możliwe, że ten plik istniał i został usunięty dawno temu. Jeśli zapytam sys.database_files w przywróconej bazie danych, plik DEFUNCT ma wartość drop_lsn, co wydaje się to potwierdzać. Obecnie w źródłowej bazie danych znajduje się tylko jedna grupa plików (PODSTAWOWA), 4 pliki danych i jeden plik dziennika.

Jakieś pomysły?

FilamentUnities
źródło
Czy możesz nam pokazać wyciągi, których używasz do tworzenia kopii zapasowych i przywracania?
Jon Seigel
Nic niezwykłego. PRZYWRÓĆ BAZY DANYCH nazwa bazy danych Z DYSKU = „D: \ Full.bak” Z WYMIANY, NORECOVERY Następnie PRZYWRÓĆ BAZY DANYCH baza danych Z DYSKU = „D: \ Diff.bak” Z ODZYSKU
FilamentUnities

Odpowiedzi:

5

Oto kroki, aby odtworzyć to, przetestowane na SQL 2012 SP1 Developer Edition. Nie występuje to w SQL 2008. Podsumowując, baza danych utworzona w SQL 2012, gdy modelowa baza danych jest w trybie PROSTEGO odzyskiwania, która ma pełną kopię zapasową wykonaną, gdy istnieje dodatkowy plik dziennika, nie może utworzyć użytecznych różnicowych kopii zapasowych, jeśli ten dodatkowy plik dziennika jest kiedykolwiek usunięty.

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

Poddałem pozycję Połącz z tego buga tutaj . Jedynym sposobem, w jaki udało mi się usunąć ten nieistniejący plik, jest odłączenie bazy danych i ponowne dołączenie za pomocą ATTACH_REBUILD_LOG.

AKTUALIZACJA: Błąd, który tworzy ten scenariusz w moim skrypcie repro, wydaje się być naprawiony przez ten KB: https://support.microsoft.com/en-us/kb/2830400 . Z komentarzy wynika, że ​​dostępna jest dodatkowa poprawka dla SQL2012 / 2014, scenariusze wydają się bardzo podobne: https://support.microsoft.com/en-us/kb/3009576

FilamentUnities
źródło
Zamieszczę Twój skrypt w komentarzach Connect, aby pomóc ludziom się rozmnażać.
Kenneth Fisher
1
Nie otrzymuję żadnych błędów podczas uruchamiania skryptu w SQL Server 2012 Enterprise Edition, 11.0.3412 (CU9 dla SP1)
Skrypt repro znajduje się w elemencie Connect, jeśli klikniesz przycisk Szczegóły.
FilamentUnities,
1
Shawn, przeglądając poprawki w CU, myślę, że to prawdopodobnie naprawiło to zachowanie: support.microsoft.com/kb/2830400
FilamentUnities
2
W zeszłym tygodniu miałem bitwę i ten wątek pomoże mi to rozwiązać, więc dziękuję. Wygląda na to, że poprawka znajduje się w SQL 2012 SP2 CU3: support.microsoft.com/en-us/kb/3009576
Richard