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.
- przed rozpoczęciem utwórz tlogbackup1
- zmienić
FULL
naBULK_LOGGED
model odzyskiwania - dodaj nową aplikację
- dodaj plik do nowej grupy plików
- ustaw nową grupę plików na domyślną
- wybierz do tabeli (w nowej grupie plików)
- upuść oryginalny stół
- usuń oryginalny plik
- usuń oryginalną grupa plików
- zmień nazwę nowej tabeli, aby pasowała do oryginalnej tabeli
- zmień nazwę pliku nowej grupy plików, aby pasowała do oryginalnej grupy plików
- zmień nazwę pliku w katalogu, aby pasowała do oryginalnej nazwy pliku
- zmień nazwę pliku na poziomie systemu operacyjnego, aby pasowała do oryginalnej nazwy pliku
- ustaw domyślną grupa plików jako oryginalną
- włącz db online
- zmienić
BULK_LOGGED
naFULL
model odzyskiwania - 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ą CHECKDB
i nie wystąpiły błędy.
Wszystkie opinie są mile widziane.
Z góry dziękuję,
Ned Otter
źródło
Odpowiedzi:
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 jestPageLSN
.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 (
PrevPageLSN
kontynuacja). 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
PageLSN
iPrevPageLSN
powiązane: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
PageLSN
na stronie pasuje doPrevPageLSN
rekordu 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:
Pogrubiłem dwa fragmenty danych, które mają nierówności powodujące błąd. Możesz zobaczyć, że naszym
PageLSN
jest 0: 0: 1 (znaleziono go w nagłówku strony), a naszymPrevPageLSN
jest 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.
źródło