w świecie SQL Server istnieje trwały mit, że zarówno poleceniaDROP TABLE
ITRUNCATE TABLE
są niezalogowane.
nie są. Oba są w pełni zalogowane, ale sprawnie zalogowane.
możesz to sobie łatwo udowodnić., Uruchom następujący kod, aby skonfigurować testową bazę danych i tabelę i pokaż, że mamy 10 000 wierszy w naszej tabeli:
wyniki:
—-
10000
a następnie następujący kod, który obcina tabelę w transakcji i sprawdza liczbę wierszy:
BEGIN TRAN;GOTRUNCATE TABLE ;GO SELECT COUNT (*) AS N'RowCount'FROM ;GO
wyniki:
—-
0
teraz tabela jest pusta., Ale mogę cofnąć transakcję i umieścić wszystkie dane z powrotem:
ROLLBACK TRAN;GO SELECT COUNT (*) AS N'RowCount'FROM ;GO
wyniki:
—-
10000
oczywiście operacja TRUNCATE
musi być zapisana w przeciwnym razie operacja cofania nie zadziała.
skąd się bierze błędne przekonanie?
wynika to z zachowania operacjiDROP
ITRUNCATE
na dużych tabelach., Zostaną one zakończone niemal natychmiast, a jeśli zajrzysz do dziennika transakcji za pomocą fn_dblog
zaraz po tym, zobaczysz tylko niewielką liczbę rekordów dziennika wygenerowanych podczas operacji. Ta mała liczba nie koreluje z rozmiarem ściętej lub upuszczonej tabeli, więc wygląda na to, że operacje DROP
I TRUNCATE
są niezalogowane.
ale są w pełni zalogowane, jak pokazałem powyżej. Gdzie są zapisy operacji?,
odpowiedź jest taka, że rekordy logów będą tworzone, tylko nie od razu, za pomocą mechanizmu o nazwie 'deferred drop', który został dodany w SQL Server 2000 SP3.
gdy tabela jest upuszczana lub obcinana, wszystkie strony Plików danych przydzielone do tabeli muszą być dealokowane.,
nie zwalniaj blokady zakresu, gwarantując, że nikt inny nie będzie mógł użyć tego zakresu
koniec
ponieważ wszystkie blokady zakresu były utrzymywane do końca operacji, a każda blokada zajmuje niewielką ilość pamięci, możliwe było, że menedżer blokady wyczerpał pamięć, gdy blokada została zablokowana.
div id=”c46cdb1324″ >
lub TRUNCATE
z bardzo dużej tabeli wystąpił., Niektórzy klienci SQL Server zaczęli zauważać, że na SQL Server 2000 napotkali warunki braku pamięci, ponieważ tabele rosły bardzo duże i znacznie przewyższały wzrost pamięci systemowej.
mechanizm deferred-drop symuluje operację DROP
lub TRUNCATE
zakończoną natychmiast, poprzez odłączenie alokacji dla tabeli i umieszczenie ich w 'deferred-Drop queue', do późniejszego przetworzenia przez zadanie w tle. Ta operacja odhaok-and-transfer generuje tylko garść rekordów dziennika., Jest to operacja, która jest wykonywana i wycofywana w moim powyższym przykładzie kodu.
zadanie „deferred-drop background task” obraca się co kilka sekund i dealokuje wszystkie strony i zakresy w kolejce deferred-drop w małych partiach, gwarantując, że operacja nie skończy się na pamięci. Wszystkie te dealokacje są w pełni zalogowane, ale pamiętaj, że dealokacja strony pełnej danych lub rekordów indeksowych nie rejestruje pojedynczych usunięć tych rekordów; zamiast tego cała strona jest po prostu oznaczona jako dealokacja w odpowiedniej mapie bajtowej alokacji PFS (Page Free Space).,
począwszy od SQL Server 2000 SP3, kiedy wykonasz DROP
lub TRUNCATE
tabeli, zobaczysz tylko kilka rekordów dziennika generowanych. Jeśli odczekasz minutę lub dłużej, a następnie ponownie zajrzysz do dziennika transakcji, zobaczysz, że tysiące rekordów dziennika zostały wygenerowane przez operację deferred-drop, z których każda dealokuje stronę lub zakres. Operacja jest w pełni i sprawnie rejestrowana.,
oto przykład, używając scenariusza, który stworzyliśmy powyżej:
CHECKPOINT;GOTRUNCATE TABLE ;GOSELECT COUNT (*) AS N'LogRecCount'FROM fn_dblog (NULL, NULL);GO
wyniki:
—-
25
jak widać, ewidentnie nie ma zapisów dziennika deallokujących 10 000 stron, plus 1 250 zakresów w tabeli testtable.
Jeśli poczekam kilka sekund, a następnie ponownie uruchomię kodfn_dblog
, otrzymuję:
—-
3811
możesz się zastanawiać, dlaczego nie ma co najmniej 10 000 rekordów dziennika – po jednym dla każdej dealokowanej strony., Dzieje się tak dlatego, że dealokacje stron są nawet skutecznie rejestrowane – z jednym rekordem dziennika odzwierciedlającym zmiany alokacji stron PFS dla 8 kolejnych stron plików danych, zamiast jednego rekordu dziennika dla każdej strony pliku danych odzwierciedlającego zmianę statusu alokacji na stronie PFS.
SQL Server zawsze stara się produkować jak najmniej logów transakcji, przy jednoczesnym przestrzeganiu zasad dotyczących pełnego lub minimalnego logowania w oparciu o bieżący model odzyskiwania., Jeśli chcesz spojrzeć na rzeczywiste rekordy dziennika wygenerowane przez mechanizmy odhaok-and-transfer i deferred-drop, po prostu zamień * na COUNT ( * ) w powyższym kodzie fn_dblog i poszukaj transakcji z nazwą transakcji ustawioną na DeferredAllocUnitDrop::Process
.
w kolejnych postach omówię wewnętrzne aspekty, które leżą u podstaw innych trwałych mitów dotyczących aspektów wydajności silnika pamięci masowej SQL Server.
Dodaj komentarz