Operacja „ALTER INDEX ALL REBUILD” na SQL Server 2012 nie powiodła się, ponieważ w dzienniku transakcji zabrakło miejsca. Indeksy nigdy nie zostały zreorganizowane ani odbudowane, więc fragmentacja wynosi ponad 80% na prawie wszystkich z nich.
Baza danych wykorzystuje prosty model odzyskiwania. Zakładałem, że po każdej operacji indeksu wykonywanej przez komendę „WSZYSTKO” dane dziennika transakcji zostaną wyczyszczone przed kolejną odbudową indeksu. Czy tak to faktycznie działa, czy też rejestruje się przebudowy indeksu tak, jakby były częścią pojedynczej transakcji?
Innymi słowy, czy mogę zmniejszyć wzrost dziennika transakcji, pisząc skrypt wykonujący każdą przebudowę indywidualnie? Czy są jeszcze inne czynniki do rozważenia?
sql-server
index
Google Fail
źródło
źródło
Odpowiedzi:
1) Płukanie dziennika: model odzyskiwania SIMPLE nie usuwa dziennika po każdej transakcji, ale w punktach kontrolnych. ( link, aby uzyskać więcej informacji)
2a) ODBUDUJ WSZYSTKO: tak, ODBUDUJ WSZYSTKO działa jako pojedyncza transakcja. Indeks odbudowuje w ramach własnych transakcji, ale cała operacja nie jest w pełni zatwierdzona do końca. Tak, możesz ograniczyć wzrost pliku dziennika, odbudowując poszczególne indeksy (i ewentualnie wydając polecenia CHECKPOINT).
2b) Dowód! Tutaj masz skrypt demonstracyjny. (Wbudowane w 2016 dev) Najpierw skonfiguruj testową bazę danych z tabelą i indeksami:
Teraz możesz porównać aktywność dziennika między REBUILD ALL a odbudowaniem indywidualnie
Zwróć uwagę, że pierwsza otwarta transakcja (dla mnie identyfikator transakcji 0000: 000002fa) nie jest zatwierdzana do końca ODBUDUJ WSZYSTKO, ale w przypadku przebudowań indeks po indeksie są one zatwierdzane sukcesywnie.
źródło
W obecnej formie jest to pojedyncza transakcja.
źródło
Pytanie jest trywialne w przypadku przebudowy offline . Oczywiście jest to pojedyncza transakcja. Wyobraź sobie spustoszenie, które nastąpiłoby, gdyby operacja podzieliła każdy indeks na własną transakcję, ponieważ musiałby zwolnić blokady podczas zatwierdzania, a następnie je odzyskać. Chociaż zwolniono blokadę tabeli krytycznej SCH-M, indeksy mogą być usuwane i można tworzyć nowe indeksy. W jaki sposób instrukcja obsługiwałaby takie przypadki? Nie wspominając o tym, że tabela może zostać usunięta, a nawet odtworzona między dwiema transakcjami! W tym przypadek upuszczenia tabeli i utworzenia innej tabeli o tym samym identyfikatorze obiektu (tak, może się zdarzyć) ...
Co jeśli wzmocnisz pytanie, aby powiedzieć, co się stanie, jeśli odbudowa indeksu jest przebudową online ? Czy to pojedyncza transakcja czy wiele? Odpowiedź jest złożona, ponieważ w rzeczywistości zaangażowanych jest kilka transakcji wewnętrznych . Jednak kluczową kwestią jest to, że istnieje ogólna transakcja archiwizacji obejmująca całą operację (instrukcja ALTER), co powoduje przypięcie dziennika do miejsca (nie można go obciąć), dlatego operacja musi zostać odpowiednio zaplanowana, aby umożliwić ~ 1,6x danych rozmiar dla trybu odzyskiwania FULL lub rozmiar danych 0,2x dla trybu BULK_LOGGED / SIMPLE. Więcej informacji na ten temat znajduje się w powiązanym dokumencie
Możesz argumentować, że dlaczego kompilacja offline nie wykorzystuje tych samych transakcji wewnętrznych co tryb online i nie podzieliła operacji? Problemy, o których wspominałem o zmianie / upuszczeniu tabeli między poszczególnymi operacjami indeksu (tj. „Stabilność schematu”) nadal wymagałyby obejmowania transakcji obejmującej SCH-S na stole przez cały czas trwania instrukcji. Ponieważ ta transakcja musi przechowywać SCH-S również podczas odzyskiwania, musi zostać zarejestrowana, i jako taki będzie rekord BEGIN XACT, który przypina dziennik i zapobiega obcięciu przez cały czas trwania instrukcji. Wiem, że ten konkretny problem został rozwiązany w ramach czasowych SQL 2016-2017 (z powodu problemów z rozmiarem dziennika SQL Azure),
ale nie jestem pewien, jaki postęp został osiągnięty. Wygląda na to, że jest teraz w wersji zapoznawczej:Resumable Online Index Rebuild jest publicznie dostępny dla SQL Server 2017 CTP 2.0 .źródło
Tak, miałem ten sam problem z bardzo dużym stołem. Ilekroć wydawałem ALTER INDEX ALL, dziennik transakcji znacznie się rozwijał, ale jeśli wydawano by ALTER INDEX indywidualnie, użycie miejsca na dziennik byłoby mniejsze.
źródło
Wcześniejsza odpowiedź Remusa, że indeksowanie online wymaga 1,6-krotności rozmiaru indeksu w trybie PEŁNEGO odzyskiwania, jest nieprawidłowa. Odsetek miejsca do rejestrowania transakcji wymaganego do przebudowania indeksu online w trybie FULL może być znacznie wyższy i zaobserwowaliśmy wielokrotnie wielkość indeksu, szczególnie gdy kompilowany indeks jest kompresowany, ponieważ rejestrowanie transakcji nie jest kompresowane. Już samo to powinno wyjaśnić, że rejestrowanie transakcji podczas przebudowy online w trybie FULL może być co najmniej kilka razy większe niż indeks. Dodaj narzut rekordu tlog, który nie jest w pełni udokumentowany przez Microsoft, ale często jest szacowany na 60 bajtów na wiersz, a proporcjonalny rozmiar rejestrowania podczas przebudowywania indeksu online przy pełnym odzyskiwaniu może być wielokrotnie większy niż rozmiar przebudowywanego indeksu, szczególnie jeśli indeks jest skompresowany
źródło
Rdfozz ma rację, to najlepszy sposób, aby zdecydować, czy Twój największy indeks można odbudować na podstawie bieżącej pamięci. Wystarczy uruchomić
dm_exec_requests
podczas operacji (lub SQL Profiler), aby sprawdzić, czy wszystkie indeksy są przebudowywane. Zastanowiłbym się również nad zmianą modelu odzyskiwania na masowe logowanie. To właśnie robię i nadal istnieją kopie zapasowe dziennika transakcji w oknie. Zobacz poniższy artykuł https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspxźródło