Często widzę takie oświadczenia, jak log serwera SQL, który rejestruje każdą transakcję i operację.
Ale jestem mylić o tym, co się dzieje, gdy transakcja zostanie ostatecznie walcowane powrotem .
Powiedzmy wyraźna transakcja ma 3 oświadczenia: statement A
, statement B
, statement C
, i wreszcie rollback
statement D
.
Teraz powiedz, kiedy wykonanie nie osiągnęło rollback statement D
, czy modyfikacje wynikające z statements A through C
zapisania w dzienniku serwera SQL?
Zrozumienie 1 :
Wszystkie wyciągi od A do D są rejestrowane. SQL Server rejestruje wszystko, bez względu na wszystko.
Zrozumienie 2 : Modyfikacje są przechowywane tylko gdzieś w pamięci i rejestrowane tylko w celu zalogowania, gdy SQL Server wyświetli commit
instrukcję. Jeśli okaże się, że jest to rollback
instrukcja, SQL Server po prostu zignoruje transakcję, nie nastąpi zapis do dziennika, ponieważ nie służy to żadnemu celowi. Innymi słowy, SQL Server loguje się, gdy wynik netto przed i po transakcjach.
Oba wydają się logiczne, przynajmniej dla mnie, ale oba nie mogą mieć racji. Dziękuję za wszelką pomoc.
źródło
Odpowiedzi:
Zrozumienie 1 jest poprawne. SQL Server rejestruje każdą operację, która zmienia dane w dzienniku transakcji. Wycofanie jest zmianą danych, więc zapisuje to również w dzienniku transakcji. Jako instrukcja A zapisuje dane w dzienniku transakcji, a także rezerwuje dane w dzienniku transakcji na wypadek, gdyby instrukcja A musiała zostać wycofana. To samo dotyczy B i C. Po wycofaniu transakcji więcej informacji zostanie zapisanych w dzienniku.
Istnieje wiele sposobów, aby zobaczyć to w akcji, dlatego poniżej znajduje się szybka prezentacja. Oto zapytanie, którego użyję, aby zobaczyć, co zostało zapisane w dzienniku:
Mój stół:
Zapytanie A korzysta z minimalnego rejestrowania:
Po:
Kwerenda B nie używa rejestrowania minimalnego:
Po B:
Zapytanie C zmienia mniej danych:
Po C:
Teraz wydam
ROLLBACK
i zapytam DMV podczas wycofywania. Poniżej znajduje się tabela kilku migawek:W ciągu
ROLLBACK
używanych bajtów wzrasta, a zarezerwowana liczba bajtów maleje. Wynika to z faktu, że SQL Server wykorzystuje wcześniej zarezerwowane miejsce do cofnięcia transakcji. Aby cofnąć transakcję, musi zmienić dane, aby zapisać więcej danych w dzienniku.źródło
Modyfikacje tabel bazy danych są zapisywane najpierw w pliku dziennika, a następnie w samych tabelach, najpierw w pamięci, a następnie w asynchronicznym procesie nazywanym
CHECKPOINT
na dysku. Ten mechanizm jest znany jako WAL (Write-Ahead Logging) i jest wspólny dla wszystkich relacyjnych baz danych.Sam dziennik jest najpierw zapisywany w pamięci (dokładnie w buforze dziennika), a następnie na dysku, ale tabele bazy danych nie są dotykane, dopóki dziennik nie zostanie zapisany na dysku.
Ten mechanizm umożliwia zarówno wycofanie zatwierdzonych transakcji, jak i wycofanie niezatwierdzonych transakcji podczas procesu odzyskiwania. Jeśli chodzi o twój przykład, jeśli coś złego wydarzyło się później
statement C
icommit
zamiast tegorollback
(nie możesz tego wiedzieć wcześniej), bez zapisywania każdego kroku transakcji, RDBMS nie miałby sposobu na odzyskanie bazy danych w spójny sposób sposób, a transakcja nie spełniałabyD
(trwałości) wACID
.Kiedy niektóre operacje są wycofywane, to plik danych otrzymuje zmiany netto (via
CHECKPOINT
), a nie plik dziennika.źródło
Zrozumienie 1 jest poprawne, a spaghettidba i Joe mają dobre wyjaśnienia.
Jeśli chcesz przetestować dla siebie (na instancji testowej), możesz użyć poniższego skryptu:
Zobaczysz, że SQL Server rejestruje wszystko, nawet kroki podjęte w celu cofnięcia operacji.
źródło