Co to jest dziennik transakcji?
W systemach relacyjnych baz danych istnieje wymóg, aby transakcje były trwałe. To jest „D” we właściwościach ACID transakcji. System musi zapewnić, że w przypadku nagłej awarii transakcję będzie można odtworzyć. SQL Server spełnia to wymaganie, przechwytując wszystkie transakcje w fizycznym pliku zwanym plikiem dziennika transakcji .
Zasadniczo, za każdym razem, gdy transakcja jest zatwierdzona, SQL Server rejestruje zmiany wytworzone przez tę transakcję w dzienniku transakcji. Nawet jeśli transakcja nie została utrwalona w pliku danych, jest dostępna w dzienniku transakcji i może zostać odtworzona w przypadku nagłej awarii.
Modele odzyskiwania i dzienniki transakcji
SQL Server działa w ramach trzech modeli odzyskiwania — pełnego, zbiorczego i prostego.
W trybie pełnego odzyskiwania rejestrowane są WSZYSTKIE transakcje. Dzięki temu bazę danych można w pełni odzyskać w przypadku awarii. Oznacza to również, że kopię zapasową bazy danych można przywrócić do określonego punktu w czasie, jeśli transakcja lub powiązana kopia zapasowa jest dostępna. W trybach pełnego i zbiorczego odzyskiwania dzienniki transakcji są obcinane za każdym razem, gdy wykonywana jest kopia zapasowa dziennika.
W trybie prostego odzyskiwania WSZYSTKIE transakcje są nadal rejestrowane. Jednak operacja dziennika transakcji jest obcinana za każdym razem, gdy baza danych wykonuje punkt kontrolny.
Punkt kontrolny występuje, gdy SQL Server zapisuje brudne bufory do pliku danych. Brudne bufory to niezbędne strony przechowywane w pamięci, które zostały zmienione przez transakcje, na przykład stan w pamięci nie jest zgodny ze stanem na dysku. Jednak nie będziemy tego tutaj omawiać. W trybie prostego odzyskiwania SQL Server rejestruje wszystkie te zmiany w dzienniku transakcji, aby zachować je do czasu ich utrwalenia.
Struktura dziennika transakcji
Dziennik transakcji to fizyczny plik widoczny w warstwie systemu operacyjnego serwera, na którym znajduje się baza danych SQL Server. Każda baza danych posiada jeden dziennik transakcji, ale istnieje możliwość skonfigurowania większej liczby. Rzecz w tym, że posiadanie wielu dzienników transakcji SQL nie przynosi żadnych korzyści w zakresie wydajności. SQL Server zapisuje w dzienniku transakcji sekwencyjnie — jeden plik musi być pełny, zanim następny zostanie użyty. Jednak wiele plików znajdujących się na osobnych dyskach może uratować sytuację, jeśli pierwszy plik zostanie zapełniony.
Wewnętrznie plik dziennika transakcji to seria wirtualnych plików dziennika. Rozmiar i liczba tych plików mają wpływ na czas potrzebny na wykonanie kopii zapasowej bazy danych lub jej udostępnienie w trybie online. Zawsze dobrze jest odpowiednio dobrać rozmiar dziennika transakcji i upewnić się, że ustawienia automatycznego wzrostu odpowiadają oczekiwanemu poziomowi aktywności. Wtedy wzrosty plików nie będą się zdarzać zbyt często.
Co sprawia, że dziennik rośnie?
Zacznijmy od stworzenia małej bazy danych przy użyciu kodu z Listingu 1. Plik danych ma rozmiar 4 MB, plik dziennika ma na początek 2 MB. Twoje produkcyjne bazy danych nigdy nie miałyby takiego rozmiaru, zwłaszcza w przypadku popularnej praktyki wstępnej alokacji . Wybraliśmy takie rozmiary jedynie w celach demonstracyjnych.
-- Listing 1: Create a Small Database
create database tranlogexperiment
on primary
( name = N'tranlogexperiment', filename = N'C:\MSSQL\Data\tranlogexperiment.mdf', size = 4MB , FILEGROWTH = 1024KB )
log on
( name = N'Test1_log', filename = N'E:\MSSQL\Log\Test1_log.ldf' , size = 2MB , FILEGROWTH = 1024KB );
go
W tej bazie danych tworzymy pojedynczą tabelę dla dalszych instrukcji języka manipulacji danymi (DML) (Listing 2).
-- Listing 2: Create a Table
use tranlogexperiment
go
create table txn_log (
ID int
, FName varchar(50)
, LName varchar(50)
, CountryCode char (2)
)
Wykonując kod z Listingu 3, sprawdzamy i weryfikujemy, co zrobiliśmy.
-- Listing 3: Check Recovery Model and File Sizes
select name, recovery_model_desc, log_reuse_wait_desc from sys.databases where name='tranlogexperiment';
select DB_NAME(database_id) [Database Name]
, type_desc [Database Name]
, name [Logical file Name]
, physical_name [Physical file Name]
, size*8/1024 [File Size (MB)]
, growth*8/1024 [File Growth (MB)]
from sys.master_files where database_id=DB_ID('tranlogexperiment');
Zwróć uwagę na rozmiar pliku kolumna. Kontynuujemy wywoływanie wzrostu dziennika transakcji, uruchamiając INSERT i DELETE 100 000 razy (Listing 4).
-- Listing 4: Create a Small Table
use tranlogexperiment
go
insert into txn_log values (1, 'Kenneth','Igiri', 'NG');
delete from txn_log where ID=1;
go 100000
Listing 4 wstawia pojedynczy wiersz do txn_log tabeli i usuwa ten sam wiersz, powtarzając tę czynność 100 000 razy.
Ogólnie rzecz biorąc, tabela nie powiększa się z powodu tej aktywności, ale dziennik transakcji znacznie się powiększa. Kiedy powtarzamy zapytanie z Listingu 3 po uruchomieniu instrukcji DML z Listingu 4, widzimy, jak bardzo urósł dziennik transakcji:
Dziennik transakcji rozrósł się z 4 MB do 40 MB z powodu tej aktywności, mimo że rozmiar pliku danych nie został zmieniony. To pokazuje nam wyraźnie, że rozmiar dziennika transakcji ma niewiele wspólnego z rozmiarem danych. Wpływ na rozmiar wynika z aktywności (DML) zachodzącej w bazie danych.
Jak zarządzamy dziennikami transakcji?
Administratorzy baz danych, którzy zarządzają lokalnymi wystąpieniami SQL Server instalacji IaaS, powinni regularnie tworzyć kopie zapasowe dzienników transakcji. Pomocne są konfiguracje odzyskiwania po awarii, takie jak Log Shipping lub AlwaysOn AG . Takie konfiguracje automatycznie wykonują kopie zapasowe.
W trybie pełnego odzyskiwania kopia zapasowa dziennika programu SQL Server obcina części dziennika transakcji, które nie są już potrzebne do odzyskiwania. Obcięcie dziennika powoduje usunięcie nieaktywnych wirtualnych plików dziennika. W ten sposób zwalnia miejsce w dziennikach transakcji do ponownego wykorzystania.
Kod z Listingu 6 pokazuje rozmiar dziennika transakcji i ilość wolnego miejsca w nim.
-- Listing 6: Change Recovery Model
USE [tranlogexperiment]
GO
SELECT DB_NAME() AS [Database Name],
name AS [Logical File Name],
type_desc,
size/128.0 AS [Current Size (MB)],
size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT)/128.0 AS [Free Space (MB)]
FROM sys.database_files
WHERE type IN (0,1);
Możemy również zmniejszyć fizyczny dziennik transakcji, korzystając z kodu z Listingu 7. Przed zmniejszeniem upewnij się, że masz kopię zapasową dziennika transakcji. W środowisku produkcyjnym najlepiej jest zaplanować tworzenie kopii zapasowych dziennika, aby uniknąć niekontrolowanego fizycznego wzrostu pliku dziennika i zapewnić zachowanie danych. Z opcją odzyskiwania po awarii, taką jak Log Shipping lub AlwaysOn AG skonfigurowane, to zostało już przyznane.
Możemy wysłać zapytanie do log_reuse_wait_desc kolumna w sys.databases widok katalogu, aby określić warunki, które uniemożliwiają zmniejszenie dziennika transakcji. Zauważ, że zapytaliśmy tę kolumnę na liście 3.
Takimi warunkami mogą być oczekujący punkt kontrolny, oczekująca kopia zapasowa dziennika, trwająca kopia zapasowa lub przywracanie, aktywna długotrwała transakcja i podobne działania w bazie danych.
-- Listing 7: Change Recovery Model
USE [tranlogexperiment]
GO
DBCC SHRINKFILE (N'Test1_log' , 0, TRUNCATEONLY)
GO
Używamy kodu z Listingu 8 do tworzenia kopii zapasowej bazy danych. W naszym konkretnym przypadku najpierw musimy wykonać pełną kopię zapasową, ponieważ kopie zapasowe dziennika zawsze odwołują się do pełnej kopii zapasowej. „Ostatnia” pełna kopia zapasowa rozpoczyna łańcuch, gdy mamy do czynienia z odzyskiwaniem do określonego momentu.
-- Listing 8: Backup Transaction Log
backup database tranlogexperiment to disk='tranlogexperiment.bkp';
backup log tranlogexperiment to disk='tranlogexperiment_log.trn';
Podczas uruchamiania bazy danych w trybie prostego odzyskiwania dziennik transakcji jest obcinany w każdym punkcie kontrolnym . W tym trybie tworzenie kopii zapasowych dziennika nie jest możliwe.
Lokalizacja pliku dziennika transakcji powinna mieć odpowiedni rozmiar, aby pomieścić długotrwałe transakcje, które zdarzają się sporadycznie. W przeciwnym razie dziennik transakcji może nadal zapełnić miejsce na dysku. Rysunek 4 pokazuje, co dzieje się wewnętrznie z dziennikiem po utworzeniu kopii zapasowej. Zauważ, że fizyczny plik nadal ma 40 MB, ale mamy teraz około 37 MB wolnego miejsca.
Co się dzieje w prostym trybie odzyskiwania?
Teraz ustawmy tranlogexperiment bazy danych do trybu prostego odzyskiwania.
-- Listing 9: Change Recovery Model
use master
go
alter database tranlogexperiment set recovery simple;
Gdy wykonamy kod przedstawiony wcześniej na Listingu 4, uzyskamy nieco inne zachowanie.
Rysunek 6 pokazuje wzrost liczby dzienników transakcji w trybie Simple Recovery, gdy wykonujemy kod z Listingu 4. Rozmiar fizycznego pliku dziennika to zaledwie 15 MB. To o połowę mniej niż wcześniej w modelu pełnego odzyskiwania. Zwróć także uwagę na 11,5 MB wolnego miejsca.
Czy to oznacza, że przyrost logów był mniejszy?
Nie. Rysunek 7 pokazuje, że podczas wykonywania sesji nasz SQL Server wykonał również kilka punktów kontrolnych. Spowodowało to obcięcie dziennika i dało miejsce dla transakcji na wznawianie rosnącego dziennika w określonych odstępach czasu.
Wniosek
Dziennik transakcji jest niezwykle ważnym elementem bazy danych SQL Server. Wpływa na wszystko, co wymaga odzyskiwania lub od niego zależy — kopie zapasowe, przywracanie, odzyskiwanie po awarii i tak dalej. Możesz także rejestrować aktywność bazy danych.
W tym artykule omówiliśmy naturę dziennika transakcji, aspekty prawidłowego zarządzania nim i zademonstrowaliśmy zachowanie DML w bazach danych z wdrożonymi trybami pełnego lub prostego odzyskiwania. Jednak o dzienniku transakcji można dowiedzieć się znacznie więcej. Wpisy w odnośnikach byłyby dla Ciebie dobrym punktem wyjścia.
Odniesienie s
- Dziennik transakcji
- Bazy danych i pamięć masowa SQL Server
Przeczytaj również
Znaczenie dziennika transakcji w SQL Server