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

Dziennik transakcji SQL Server — część 1

Każda baza danych SQL Server zawiera jeden lub więcej plików dziennika transakcji oprócz plików danych. Pliki dziennika rejestrują wszystkie transakcje i modyfikacje bazy danych dokonane przez każdą z nich.

Ten artykuł skupia się na dzienniku transakcji i sposobie, w jaki SQL Server rejestruje modyfikacje danych w celu wykorzystania danych do odzyskiwania po awarii bazy danych.

Wprowadzenie do pliku dziennika transakcji SQL Server

Jak pamiętamy, każda transakcja to „wszystko albo nic”. Jeśli część transakcji się nie powiedzie, cała transakcja się nie powiedzie, a stan bazy danych pozostanie niezmieniony.

SQL Server przechowuje w pliku dziennika zapis każdej transakcji wykonanej w bazie danych. Jeśli jakaś awaria pociąga za sobą zamknięcie programu SQL Server, używa on dziennika transakcji do przywrócenia bazy danych do spójnego stanu z integralnością danych.

Po ponownym uruchomieniu SQL Server rozpoczyna proces odzyskiwania po awarii. Odczytuje plik dziennika transakcji, aby upewnić się, że wszystkie prawidłowe dane są przechowywane w plikach danych, a niezatwierdzone transakcje są wycofywane.

Podczas normalnej pracy SQL Server również korzysta z dziennika transakcji. Informacje zawarte w pliku są niezbędne do określenia, co SQL Server musi zrobić, gdy transakcja zostanie wycofana z powodu błędu lub określonej przez użytkownika instrukcji ROLLBACK.

Jak SQL Server wykorzystuje dziennik transakcji

Dziennik transakcji to fizyczny plik z rozszerzeniem LDF . SQL Server tworzy go automatycznie dla każdej nowej bazy danych wraz z podstawowym plikiem danych (.MDF ), który przechowuje obiekty bazy danych i same dane.

Za każdym razem, gdy kod T-SQL zmienia obiekt bazy danych lub zawarte w nim dane, szczegóły zmiany są rejestrowane jako rekord dziennika w pliku dziennika transakcji.

Rekord dziennika zawiera informacje o określonej zmianie dokonanej w bazie danych (np. wstawienie pojedynczego wiersza). Dlatego będziemy mieć serię zapisów dziennika, aby w pełni opisać efekty pojedynczej transakcji.

Architektura dziennika transakcji

Numery sekwencji dziennika

Rekord dziennika ma unikalny, automatycznie zwiększający się numer sekwencji dziennika (LSN ), co pozwala nam znaleźć ten rekord w dzienniku transakcji. LSN opisuje zmianę danych i zawiera następujące informacje:

  • operacja i wiersz, na który ma wpływ
  • stare i nowe wersje danych
  • transakcja, która wykonała modyfikację

LSN składa się z trzech numerów:

LSN =::

Każda strona pliku danych ma w nagłówku numer LSN, który identyfikuje najnowszy rekord dziennika, którego zmiana jest odzwierciedlona na stronie. Ma to kluczowe znaczenie dla odzyskiwania po awarii.

Po uruchomieniu odzyskiwania po awarii porównuje LSN rekordów dziennika dla zatwierdzonych lub niezatwierdzonych transakcji z numerami LSN na stronach plików danych, aby określić, czy należy wykonać cofnięcie lub cofnięcie na tych konkretnych rekordach dziennika.

Podczas tworzenia bazy danych dobrą praktyką jest określenie rozmiaru dziennika transakcji . Jeśli tego nie zrobisz, SQL Server automatycznie utworzy dziennik transakcji o domyślnym rozmiarze.

Domyślny rozmiar dziennika transakcji nowej bazy danych jest większy z 0,5 MB lub 25% całkowitego rozmiaru wszystkich plików danych utworzonych w tej samej instrukcji CREATE DATABASE.

Musisz być bardzo ostrożny, ponieważ nowe części dziennika transakcji są zawsze inicjalizowane od zera . Jeśli masz instrukcję CREATE DATABASE bez określenia rozmiaru pliku dziennika i utworzysz na przykład bazę danych o pojemności 1 TB, SQL Server utworzy dziennik transakcji o pojemności 250 GB.

Ponieważ dziennik musi być inicjowany od zera, nie korzysta z natychmiastowej inicjalizacji pliku. Ta funkcja została dodana w SQL Server 2005, aby umożliwić niemal natychmiastowe tworzenie lub powiększanie plików danych.

Możemy zobaczyć, co się dzieje, gdy TWORZYMY BAZĘ DANYCH – inicjalizacja zera w naszym logu za pomocą flagi śledzenia 3004 który wyświetla komunikaty o inicjalizacji zerowej i flaga śledzenia 3605 która pozwala na drukowanie tych komunikatów dziennika za pomocą flagi śledzenia 3004.

Poniższa prezentacja pokazuje, jak można zobaczyć, jak dzieje się zerowanie pliku dziennika.

1. Wykonaj następujący skrypt, aby upewnić się, że nie mamy bazy danych o nazwie DBTest2014

USE master;
GO
 
IF DATABASEPROPERTY(N'DBTest2014', N'Version')>0
  BEGIN
    ALTER DATABASE DBTest2014 SET SINGLE_USER
      WITH ROLLBACK IMMEDIATE;
    DROP DATABASE DBTest2014;
  END
GO

2. Włącz flagi śledzenia, aby oglądać inicjalizację zerową

DBCC TRACEON (3605, 3004, -1);
GO
3. Flush the error log
EXEC sp_cycle_errorlog;
GO

3. Utwórz bazę danych

CREATE DATABASE DBTest2014 ON PRIMARY (
  NAME = N'DBTest2014',
  FILENAME = N'D:\DBTest2014_data.mdf')
LOG ON (
  NAME= N'DBTest2014_log',
  FILENAME= N'D:\DBTest2014_log.ldf',
  SIZE = 10MB,
  FILEGROWTH = 10 MB);
GO

4. Przeczytaj plik dziennika błędów

EXEC sys.xp_readerrorlog;
GO

Wirtualne pliki dziennika

Dziennik transakcji jest podzielony wewnętrznie na szereg porcji zwanych plikami dziennika wirtualnego (VLF ) w celu uproszczenia zarządzania.

Za każdym razem, gdy tworzony jest dziennik transakcji, daje określoną liczbę VLF. Nowo utworzone VLF są nieaktywne i nieużywane. Aktywny VLF nie może być ponownie użyty, dopóki nie zostanie dezaktywowany przez wyczyszczenie dziennika.

Jest jednak jeden wyjątek – pierwszy VLF w nowej bazie danych jest zawsze aktywny, ponieważ każdy dziennik transakcji musi mieć co najmniej jeden aktywny VLF.

Każdy plik dziennika ma również stronę nagłówka pliku co zajmuje 8 KB na początku pliku dziennika transakcji. Strona nagłówka pliku przechowuje metadane dotyczące pliku, takie jak rozmiar i ustawienia automatycznego wzrostu.

Liczba i rozmiar plików VLF w nowej części dziennika transakcji są określane przez program SQL Server. Nie można go skonfigurować.

Jeśli nowo dodany rozmiar to:

  • <1 MB nie ma znaczenia dla dyskusji
  • <64 MB będą 4 nowe VLF (każdy 1/4 rozmiaru wzrostu)
  • Od 64 MB do 1 GB będzie 8 nowych plików VLF (każdy 1/8 rozmiaru wzrostu)
  • > 1 GB będzie 16 nowych VLF (każdy 1/16 rozmiaru wzrostu)

Dotyczy to początkowo utworzonego dziennika transakcji oraz każdego ręcznego lub automatycznego wzrostu, który ma miejsce. Znając wzór na potencjalną liczbę VLF i ich potencjalną wielkość, zarządzanie dziennikiem pomaga. Zbyt mało lub zbyt wiele plików VLF może powodować problemy z wydajnością operacji w dzienniku transakcji.

Numer sekwencyjny VLF

Każdy VLF ma numer sekwencyjny, który jednoznacznie identyfikuje VLF w dzienniku transakcji. Numer sekwencyjny zwiększa się o jeden za każdym razem, gdy system zarządzania dziennikiem aktywuje następny VLF. Łańcuch numerów sekwencyjnych daje aktualnie aktywny zestaw VLF.

Początek aktywnej części dziennika transakcji zaczyna się od VLF, który ma najniższy numer sekwencji i jest nadal aktywny. Nieaktywne pliki VLF mają numery sekwencyjne, ale nie są częścią aktywnej części dziennika.

Aktywna część dziennika zawiera rekordy dziennika wymagane z jakiegoś powodu przez SQL Server.

Kiedy po raz pierwszy tworzysz nową bazę danych, numery sekwencyjne VLF nie zaczynają się od 1. Zaczynają się od najwyższego numeru sekwencyjnego VLF w dzienniku transakcji bazy danych modelu, plus 1 . Nie można zabraknąć numerów sekwencyjnych VLF. SQL Server ma kod, który wymusi zamknięcie instancji, jeśli numer sekwencyjny VLF kiedykolwiek zostanie zawinięty do zera (jeśli następny numer sekwencyjny VLF jest mniejszy niż poprzedni).

VLF i bloki dziennika

W VLF istnieją bloki dziennika o zmiennej wielkości. Minimalny rozmiar bloku dziennika to 512 bajty i bloki dziennika rosną do maksymalnego rozmiaru 60 KB . Rozmiar jest ustawiany w jednym z następujących przypadków:

  • Transakcja generuje zapis dziennika w celu zatwierdzenia zakończenia przerwania transakcji
  • Rozmiar bloku dziennika osiąga 60 KB bez zatwierdzania lub przerywania transakcji

W bloku dziennika znajdują się zapisy dziennika (pokolorowane na schemacie). Rekordy dziennika mają również zmienną wielkość. Diagram pokazuje, że rekordy dziennika z wielu współbieżnych transakcji mogą istnieć w tym samym bloku dziennika. Rekordy dziennika są przechowywane w kolejności zapisywania podobnej do pliku strony danych.

Każdy VLF zawiera nagłówek VLF z następującymi informacjami:

  • Czy VLF jest aktywny, czy nie.
  • Numer sekwencyjny dziennika podczas tworzenia VLF.
  • Aktualne bity parzystości dla wszystkich 512-bajtowych bloków w VLF.

Bity parzystości zaczynają się od 64 po pierwszym użyciu VLF. Jeśli VLF stanie się nieaktywny, ale zostanie ponownie aktywowany, bity parzystości staną się 128. Są one używane podczas odzyskiwania po awarii.

Badanie szczegółów dziennika transakcji – DBCC LOGINFO

Jedynym sposobem sprawdzenia struktury dziennika transakcji jest użycie nieudokumentowanego DBCC LOGINFO Komenda. Składnia polecenia to:

DBCC LOGINFO [({'dbname | dbid'})]

Jeśli nie określisz nazwa bazy danych i dbid , zrzuci zawartość dziennika dla bieżącej bazy danych.

Wynikiem jest jeden wiersz na każdy plik VLF znajdujący się w dzienniku transakcji dla tej bazy danych. Zwrócone pola to:

  • RecoveryUnitId — dodane w SQL Server 2012, ale obecnie nieużywane
  • Identyfikator pliku — identyfikator pliku dziennika transakcji w bazie danych.
  • Rozmiar pliku — Rozmiar VLF w bajtach.
  • StartOffset — początkowe przesunięcie VLF w pliku dziennika transakcji, w bajtach
  • Nr Seq — Numer sekwencyjny VLF
  • Stan — Czy VLF jest aktywny czy nie (0 =nieaktywny, 2 =aktywny, 1 – nie jest używany)
  • Parytet — bieżąca parzystość (64 lub 128 lub 0, jeśli VLF nigdy nie był aktywny)
  • Utwórz LSN — LSN, gdy tworzony był plik VLF (0 =VLF został utworzony podczas początkowego tworzenia pliku dziennika transakcji). Wszystkie inne VLF dodane po początkowym utworzeniu pliku dziennika transakcji będą miały niezerową wartość CreateLSN.

Możemy wykonać następujące polecenie dla DBTest2014 baza danych, którą stworzyliśmy wcześniej:

DBCC LOGINFO (N'DBTest2014');
GO

Zobacz wynik:

DBCC SQLPERF (przestrzeń logu)

Jedynym sposobem w Transact-SQL na sprawdzenie ilości używanego dziennika jest DBCC SQLPERF. Składnia polecenia to:

DBCC SQLPERF
(
     [ LOGSPACE ]
     |
          [ "sys.dm_os_latch_stats" , CLEAR ]
     |
     [ "sys.dm_os_wait_stats" , CLEAR ]
)
     [WITH NO_INFOMSGS ]

Polecenie zwraca zestaw wyników z jednym wierszem na bazę danych:

  • Nazwa bazy danych
  • Rozmiar dziennika (MB)
  • Wykorzystana przestrzeń w dzienniku (%)
  • Stan:zawsze ustawiony na zero

W moim środowisku następująca komenda:

DBCC SQLPERF (LOGSPACE);
GO

Zwraca następujący wynik:

W następnym artykule przyjrzymy się zapisom dziennika.


  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 działa funkcja NCHAR() w SQL Server (T-SQL)

  2. Wydajność serwera SQL — testowanie w chmurze

  3. Korzystanie z PIVOT w SQL Server 2008

  4. Błąd serwera SQL 206:konflikt typu operandu

  5. Projekt bazy danych dla ustawień użytkownika