mit, który DROP i TRUNCATE TABLE są Niezalogowane

wpis w: Articles | 0

w świecie SQL Server istnieje trwały mit, że zarówno poleceniaDROP TABLEITRUNCATE 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:

RowCount
—-
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:

ROWCOUNT
—-
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:

RowCount
—-
10000

oczywiście operacja TRUNCATEmusi 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:

LogRecCount
—-
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ę:

LogRecCount
—-
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

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *