Nie można przywrócić (błąd 3456)

9

Mam sytuację, która nie jest łatwa do zrozumienia, i pomyślałem, że zapytam na tym forum, czy inni mogą mieć jakieś sugestie.

Używam SQL Server 2008 R2 Standard SP3 w systemie Windows Server 2008R2 Enterprise.

Baza danych wymagała konserwacji, a po fakcie musiałem ją przywrócić na innym serwerze. Mam pełną kopię zapasową bazy danych wykonaną za pomocą COPY_ONLY oraz zestaw 4 kopii zapasowych tlog.

  1. przed rozpoczęciem utwórz tlogbackup1
  2. zmienić FULLna BULK_LOGGEDmodel odzyskiwania
  3. dodaj nową aplikację
  4. dodaj plik do nowej grupy plików
  5. ustaw nową grupę plików na domyślną
  6. wybierz do tabeli (w nowej grupie plików)
  7. upuść oryginalny stół
  8. usuń oryginalny plik
  9. usuń oryginalną grupa plików
  10. zmień nazwę nowej tabeli, aby pasowała do oryginalnej tabeli
  11. zmień nazwę pliku nowej grupy plików, aby pasowała do oryginalnej grupy plików
  12. zmień nazwę pliku w katalogu, aby pasowała do oryginalnej nazwy pliku
  13. zmień nazwę pliku na poziomie systemu operacyjnego, aby pasowała do oryginalnej nazwy pliku
  14. ustaw domyślną grupa plików jako oryginalną
  15. włącz db online
  16. zmienić BULK_LOGGEDna FULLmodel odzyskiwania
  17. Po zakończeniu wszystkich kroków utwórz tlogbackup2

Przywracanie wszystkich kopii zapasowych musi być wykonywane Z PRZESUWANIEM, ze względu na zmiany liter dysków na serwerze przywracania.

Kroki odzyskiwania:

RESTORE database SomeDB FROM DISK = 'D:\REPRO\SomeDB.bak'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup1.trn'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup2.trn'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

Ostateczne przywracanie logów osiąga 100%, a następnie kończy się niepowodzeniem z błędem 3456:

Przetworzono 368 stron dla bazy danych „SomeDB”, plik „SystemData” w pliku 1.

Przetworzono 7656520 stron dla bazy danych „SomeDB”, plik „SystemDataPDS” w pliku 1.

Przetworzono 172430 stron dla bazy danych „SomeDB”, plik „SystemData_log” w pliku 1.

Msg 3456, poziom 16, stan 1, wiersz 1
Nie można ponownie wykonać rekordu dziennika (210388: 123648: 232), dla identyfikatora transakcji (0: 1016710921), na stronie (4: 8088), baza danych „SomeDB” (identyfikator bazy danych 6) . Strona: LSN = (0: 0: 1), typ = 11. Log: OpCode = 4, kontekst 11, PrevPageLSN: (210388: 122007: 1). Przywróć z kopii zapasowej bazy danych lub napraw bazę danych. Msg 3013, poziom 16, stan 1, wiersz 1 DZIENNIK PRZYWRACANIA kończy się nieprawidłowo.

Aby tylko sprawdzić, czy pełna kopia zapasowa bazy danych była w porządku, przywróciłem ją CHECKDBi nie wystąpiły błędy.

Wszystkie opinie są mile widziane.

Z góry dziękuję,

Ned Otter

NedOtter
źródło
1
Czy możesz wyjaśnić, dlaczego uważasz, że masz nieprzerwany łańcuch dziennika? W momencie, gdy przełączyłeś bazę danych w tryb BULK_LOGGED i zacząłeś mieszać się ze schematem, wszystkie zakłady na nieprzerwany łańcuch logów są wyłączone.
Thomas Kejser
Dzięki za odpowiedź, Thomas. Widzę teraz, że tytuł mojego postu był niepoprawny. Nie potrzebuję odzyskania punktu w czasie, ale pełne przywrócenie do końca 4. kopii zapasowej tlog. Zatem ustawienie BULK_LOGGED nie powinno powodować żadnych problemów z tym. Nie widzę, w jaki sposób to, co zrobiłem, spowodowałoby niepowodzenie 2. kopii zapasowej tlog - wszystkie polecenia były obsługiwane przez SQL Server, i wykonałem dokładnie te same kroki (choć nie na tych samych danych) na mniejszej bazie danych i byłem w stanie przywrócić 2. kopię zapasową tlog bez problemu.
NedOtter
Błąd wygląda jak zepsucie. To błąd wewnętrzny. Czy możesz zweryfikować integralność wszystkich plików kopii zapasowych? Czy są z sumami kontrolnymi?
usr
Sprawdziłem, czy pełna kopia zapasowa bazy danych zawierała 0 błędów, uruchamiając CHECKDB. Będę musiał sprawdzić, czy użyto CHECKSUM.
NedOtter
1
Jeśli kopie zapasowe mają włączoną sumę kontrolną, należy również użyć sumy kontrolnej do przywracania. Typ strony 11 to strona PFS, co oznacza, że ​​nie można tego naprawić, można jedynie wykonać pełne przywracanie. Nie powiesz też, kiedy wykonano kopię zapasową tylko kopii. Gdzie była ta kopia zapasowa na osi czasu?
Robert L. Davis,

Odpowiedzi:

9

Aby zrozumieć, dlaczego zostanie zgłoszony błąd 3456, musimy cofnąć się o krok i zrozumieć, w jaki sposób SQL Server obsługuje ten etap odzyskiwania.

Gdy SQL Server wykonuje operację, a ta operacja jest modyfikacją strony, następuje szybkie sprawdzenie. W nagłówku strony pojawi się ostatecznie znak PageLSN, który wskazuje ostatni numer LSN, który zmodyfikował tę stronę, zarejestrowany przez stronę. Pomyśl o tym w ten sposób, strona śledzi ostatni LSN, który dokonał modyfikacji. To jest PageLSN.

Za każdym razem, gdy wykonywana jest operacja modyfikacji strony, ten rekord dziennika zawiera kilka LSN. Mianowicie, LSN rekordu dziennika (pomyśl ... Bieżący LSN ), a następnie ma tak zwaną LSN Poprzedniej strony ( PrevPageLSNkontynuacja). Kiedy więc modyfikujemy stronę, jednym z elementów danych, które są umieszczane w rekordzie dziennika, jest to, co strona wskazuje jako ostatni LSN przed modyfikacją strony .

Pomyśl o tym w ten sposób ... Twój samochód musi mieć nad tym wykonaną pracę. Mechanik John pracuje nad twoim samochodem, a we wnęce silnika ma małą etykietkę, a Mechanik John pisze: „John pracował nad tym samochodem jako ostatni”. Następnym razem, gdy zawieziesz samochód do innego sklepu, Mechanik Mark zagląda do przedziału silnikowego i widzi, że Mechanik John pracował nad tym samochodem jako ostatni. W swoim arkuszu danych zapisuje te informacje. Ten sam pomysł z SQL Server.

Może to być nieco mylące, więc spójrz na poniższy obrazek z sekwencyjnymi modyfikacjami strony oraz jak PageLSNi PrevPageLSNpowiązane:

wprowadź opis zdjęcia tutaj

Wróćmy, ponieważ wszystko to wchodzi w grę, gdy trzeba powtórzyć operację na stronie (przywracanie, odzyskiwanie, HA itp.). Gdy SQL Server musi ponownie wykonać operację strony, sprawdza poprawność poczytalności, aby sprawdzić, czy PageLSNna stronie pasuje do PrevPageLSNrekordu dziennika. Jeśli to nie jest równe, zobaczysz błąd 3456 wyrzucony.

Czy PageLSN jest równy PrevPageLSN ? Nie??? Błąd zatrzymania i podniesienia 3456 ...

Przeanalizujmy twój komunikat o błędzie, który obejmuje:

Nie można ponownie wykonać rekordu dziennika (210388: 123648: 232) dla identyfikatora transakcji (0: 1016710921), na stronie (4: 8088), baza danych „SomeDB” (identyfikator bazy danych 6). Strona: LSN = (0: 0: 1) , typ = 11. Log: OpCode = 4, kontekst 11, PrevPageLSN: (210388: 122007: 1) . Przywróć z kopii zapasowej bazy danych lub napraw bazę danych. Msg 3013, poziom 16, stan 1, wiersz 1 DZIENNIK PRZYWRACANIA kończy się nieprawidłowo.

Pogrubiłem dwa fragmenty danych, które mają nierówności powodujące błąd. Możesz zobaczyć, że naszym PageLSNjest 0: 0: 1 (znaleziono go w nagłówku strony), a naszym PrevPageLSNjest 210388: 122007: 1 (znaleziono go w danych w rekordzie dziennika, który próbował zostać ponownie wykonany). Oczywiście nie są one równe, stąd err3456.

Tak więc, aby dowiedzieć się, dlaczego to wydarzenie, byłoby dowiedzieć się, dlaczego istnieje tutaj rozbieżność. Naprawdę musimy prześledzić cykl życia strony 4: 8088 i sprawdzić, gdzie jest rozłączenie. Niestety bez dalszych informacji lub praktycznego rozwiązywania problemów nie mogę zrobić nic więcej poza podaniem tła operacji odzyskiwania i przyczyny błędu.

Thomas Stringer
źródło
Wiem, że minęło trochę czasu, ale wciąż ... dobre rzeczy, dzięki za dokładne wyjaśnienie!
RThomas,