Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Dziennik transakcji SQL Server, część 3:Podstawy rejestrowania

W drugiej części tej serii opisałem strukturalną hierarchię dziennika transakcji. Ponieważ ten post dotyczy głównie wirtualnych plików dziennika (VLF), które opisałem, zalecam przeczytanie drugiej części przed kontynuowaniem.

Kiedy wszystko jest w porządku, dziennik transakcji będzie się nieskończenie zapętlać, ponownie wykorzystując istniejące VLF. To zachowanie nazywam kolistym charakterem dziennika . Czasami jednak coś się wydarzy, aby temu zapobiec i dziennik transakcji rośnie i rośnie, dodając coraz więcej VLF. W tym poście wyjaśnię, jak to wszystko działa, a czasami nie.

VLF i obcinanie dziennika

Wszystkie VLF mają strukturę nagłówka zawierającą metadane dotyczące VLF. Jednym z najważniejszych pól w strukturze jest stan VLF, a interesujące nas wartości wynoszą zero, co oznacza, że ​​VLF jest nieaktywny i dwa, co oznacza, że ​​VLF jest aktywny . Jest to ważne, ponieważ nieaktywny VLF można ponownie wykorzystać, ale aktywny nie. Zauważ, że VLF jest całkowicie aktywny lub całkowicie nieaktywny.

VLF pozostanie aktywny, gdy znajdują się w nim wymagane rekordy dziennika, więc nie można go ponownie wykorzystać i nadpisać (następnym razem omówię same rekordy dziennika). Przykłady powodów, dla których mogą być wymagane zapisy dziennika, obejmują:

  • Istnieje długotrwała transakcja, której częścią są zapisy dziennika, więc nie można ich zwolnić, dopóki transakcja nie zostanie zatwierdzona lub nie zostanie wycofana
  • Kopia zapasowa dziennika nie utworzyła jeszcze kopii tych rekordów dziennika
  • Ta część dziennika nie została jeszcze przetworzona przez agenta odczytu dziennika w celu replikacji transakcyjnej lub zmiany przechwytywania danych
  • Ta część dziennika nie została jeszcze wysłana do asynchronicznej kopii lustrzanej bazy danych lub repliki grupy dostępności

Należy zauważyć, że jeśli nie ma powodów, aby VLF pozostał aktywny, nie przełączy się ponownie w stan nieaktywny, dopóki nie nastąpi proces zwany obcinaniem dziennika wystąpi – więcej na ten temat poniżej.

Używając prostego hipotetycznego dziennika transakcji z tylko pięcioma numerami sekwencyjnymi VLF i VLF zaczynającymi się od 1 (pamiętaj, że w rzeczywistości nigdy tak się nie dzieje), po utworzeniu dziennika transakcji VFL 1 jest natychmiast oznaczany jako aktywny, ponieważ zawsze ma być co najmniej jednym aktywnym VLF w dzienniku transakcji — VLF, w którym aktualnie zapisywane są bloki dziennika. Nasz przykładowy scenariusz pokazano na rysunku 1 poniżej.

Rysunek 1:Hipotetyczny, zupełnie nowy dziennik transakcji z 5 plikami VLF, numery sekwencyjne 1 do 5.

Ponieważ tworzonych jest więcej rekordów dziennika i więcej bloków dziennika jest zapisywanych w dzienniku transakcji, VLF 1 zapełnia się, więc VLF 2 musi stać się aktywny, aby można było zapisywać więcej bloków dziennika, jak pokazano na rysunku 2 poniżej.

Rysunek 2:Aktywność przechodzi przez dziennik transakcji.

SQL Server śledzi początek najstarszej niezatwierdzonej (aktywnej) transakcji, a ta LSN jest utrwalana na dysku za każdym razem, gdy wystąpi operacja w punkcie kontrolnym. Numer LSN najnowszego rekordu dziennika zapisanego w dzienniku transakcji jest również śledzony, ale jest śledzony tylko w pamięci, ponieważ nie ma możliwości utrwalenia go na dysku bez uruchamiania różnych warunków wyścigu. Nie ma to znaczenia, ponieważ jest używane tylko podczas odzyskiwania po awarii, a SQL Server może wyliczyć LSN „końca” dziennika transakcji podczas odzyskiwania po awarii. Punkty kontrolne i przywracanie po awarii to tematy dla przyszłych postów w serii.

W końcu VLF 2 zapełni się, a VLF 3 stanie się aktywny i tak dalej. Sednem cyklicznego charakteru dziennika transakcji jest to, że wcześniejsze pliki VLF w dzienniku transakcji stają się nieaktywne, dzięki czemu można je ponownie wykorzystać. Odbywa się to za pomocą procesu o nazwie obcinanie dziennika , które jest również powszechnie nazywane czyszczeniem dziennika . Niestety, oba te terminy są strasznie mylące, ponieważ nic nie jest tak naprawdę obcinane ani usuwane.

Obcinanie dziennika to po prostu proces sprawdzania wszystkich plików VLF w dzienniku transakcji i określania, które aktywne VLF można teraz ponownie oznaczyć jako nieaktywne, ponieważ żadna z ich zawartości nie jest nadal wymagana przez SQL Server. Kiedy wykonywane jest obcinanie dziennika, nie ma gwarancji, że jakiekolwiek aktywne pliki VLF mogą stać się nieaktywne — wszystko zależy od tego, co dzieje się z bazą danych.

Istnieją dwa powszechne błędne przekonania dotyczące obcinania dziennika:

  1. Dziennik transakcji staje się mniejszy (błędna koncepcja „obcinania”). Nie, nie zmienia się – nie ma zmiany rozmiaru po obcięciu dziennika. Jedyną rzeczą, która może zmniejszyć rozmiar dziennika transakcji, jest jawny plik DBCC SHRINKFILE.
  2. Nieaktywne VLF są w pewien sposób wyzerowane (błędne przekonanie o „czyszczeniu”). Nie – nic nie jest zapisywane w VLF, gdy jest on nieaktywny, z wyjątkiem kilku pól w nagłówku VLF.

Rysunek 3 poniżej pokazuje nasz dziennik transakcji, w którym VLF 3 i 4 są aktywne, a obcięcie dziennika mogło oznaczyć VLF 1 i 2 jako nieaktywne.

Rysunek 3:Obcięcie dziennika oznacza wcześniejsze pliki VLF jako nieaktywne.

To, kiedy nastąpi obcięcie dziennika, zależy od modelu odzyskiwania używanego w bazie danych:

  • Prosty model:obcinanie dziennika następuje po zakończeniu operacji w punkcie kontrolnym
  • Model pełny lub model z logowaniem zbiorczym:obcinanie dziennika następuje po zakończeniu tworzenia kopii zapasowej dziennika (o ile nie jest uruchomiona jednoczesna pełna lub różnicowa kopia zapasowa, w którym to przypadku obcinanie dziennika jest odraczane do czasu zakończenia tworzenia kopii zapasowej danych)

Nie ma od tego wyjątków.

Kołowy charakter kłody

Aby uniknąć rozrostu dziennika transakcji, obcinanie dziennika musi umożliwiać oznaczenie VLF jako nieaktywnego. Pierwszy fizyczny VLF w dzienniku musi być nieaktywny, aby dziennik transakcji miał charakter cykliczny.

Rozważ rysunek 4 poniżej, który pokazuje, że VLF 4 i 5 są w użyciu, a obcinanie dziennika oznaczyło VLF 1 do 3 jako nieaktywne. Generowanych jest więcej rekordów dziennika, więcej bloków dziennika jest zapisywanych w VLF 5 i ostatecznie się zapełnia.

Rysunek 4:Aktywność wypełnia najwyższy fizyczny VLF w dzienniku transakcji.

W tym momencie menedżer dziennika bazy danych sprawdza stan pierwszego fizycznego pliku VLF w dzienniku transakcji, którym w naszym przykładzie jest VLF 1 o numerze porządkowym 1. VLF 1 jest nieaktywny, więc dziennik transakcji może zostać zawinięty i zacznij napełniać ponownie od początku. Menedżer dziennika zmienia pierwszy VLF na aktywny i zwiększa jego numer sekwencyjny o jeden wyższy niż bieżący najwyższy numer sekwencyjny VLF. Tak więc staje się VLF 6, a rejestrowanie jest kontynuowane, a blok dziennika jest zapisywany w tym VLF. Jest to cykliczny charakter dziennika, jak pokazano poniżej na rysunku 5.

Rysunek 5:Cykliczny charakter dziennika transakcji i ponowne wykorzystanie VLF.

Gdy coś pójdzie nie tak

Gdy pierwszy fizyczny plik VLF w dzienniku transakcji nie jest nieaktywny, dziennik transakcji nie może się zawijać, więc będzie rósł (o ile jest tak skonfigurowany i jest wystarczająca ilość miejsca na dysku). Dzieje się tak często, ponieważ coś uniemożliwia obcięcie dziennika przed dezaktywacją VLF. Jeśli zauważysz, że dziennik transakcji dla bazy danych rośnie, możesz zapytać SQL Server, aby dowiedzieć się, czy występuje problem z obcięciem dziennika, używając tego prostego kodu poniżej:

SELECT
      [log_reuse_wait_desc]
  FROM [master].[sys].[databases]
  WHERE [name] = N'MyDatabase';

Jeśli obcięcie dziennika mogło dezaktywować jeden lub więcej plików VLF, wynikiem będzie NIC. W przeciwnym razie , otrzymasz powód, dla którego obcięcie dziennika nie mogło dezaktywować żadnych plików VLF. Istnieje długa lista możliwych przyczyn opisanych tutaj w sekcji Czynniki, które mogą opóźnić obcinanie dziennika.

Ważne jest, aby zrozumieć semantykę wyniku:jest to powód, dla którego obcięcie dziennika nie mogło nic zrobić przy ostatniej próbie uruchomienia . Na przykład wynikiem może być ACTIVE_BACKUP_OR_RESTORE, ale wiesz, że ta długotrwała pełna kopia zapasowa została zakończona. Oznacza to po prostu, że podczas ostatniej próby obcięcia dziennika kopia zapasowa była nadal uruchomiona.

Z mojego doświadczenia wynika, że ​​najczęstszą przyczyną zapobiegania obcinaniu dziennika jest LOG_BACKUP; czyli wykonaj kopię zapasową dziennika! Ale jest też ciekawe, dziwne zachowanie zLOG_BACKUP . Jeśli ciągle widzisz wynik LOG_BACKUP ale wiesz, że tworzenie kopii zapasowych dziennika przebiega pomyślnie, dzieje się tak, ponieważ w bazie danych jest bardzo mało aktywności, a bieżący plik VLF jest taki sam, jak podczas ostatniej kopii zapasowej dziennika. A więc LOG_BACKUP oznacza „przejdź i wykonaj kopię zapasową dziennika” lub „wszystkie zapisane w kopii zapasowej rekordy dziennika pochodzą z bieżącego pliku VLF, więc nie można go dezaktywować”. Kiedy dzieje się to drugie, może to być mylące.

Zataczając się…

Utrzymanie cyklicznego charakteru dziennika transakcji jest bardzo ważne, aby uniknąć kosztownego wzrostu liczby dzienników i konieczności podejmowania działań naprawczych. Zwykle oznacza to regularne tworzenie kopii zapasowych dziennika, aby ułatwić obcinanie dziennika i zmianę rozmiaru dziennika transakcji, aby móc przechowywać dowolne duże, długotrwałe operacje, takie jak odbudowa indeksu lub operacje ETL, bez wzrostu dziennika.

W następnej części serii omówię zapisy dziennika, sposób ich działania i kilka interesujących przykładów.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak określić niezmienną kulturę podczas korzystania z FORMAT() w SQL Server

  2. Czy można używać agregatów zdefiniowanych przez użytkownika (clr) z funkcjami okna (over)?

  3. Konwertuj „datetime2” na „datetimeoffset” w SQL Server (przykłady T-SQL)

  4. Jak mogę używać jednej puli połączeń mssql na kilku trasach w aplikacji internetowej Express 4?

  5. Jak wygenerować plan wykonania w SQL Server