W SQL Server 2012 i SQL Server 2014 występuje błąd regresji, w którym, jeśli równolegle przebudujesz indeks w trybie online, a także wystąpi błąd krytyczny, taki jak przekroczenie limitu czasu blokady, może wystąpić utrata lub uszkodzenie danych . To powinien być stosunkowo rzadki scenariusz (Phil Brammer ma prostą kopię w Connect #795134), ale utrata danych to utrata danych i nie jestem przygotowany na hazard. Poprawka jest opisana w KB #2969896:POPRAWKA:Utrata danych w indeksie klastrowym występuje po uruchomieniu indeksu kompilacji w trybie online w SQL Server 2012.
Nie wszyscy muszą się tym martwić. Jeśli nie używasz wersji Enterprise (lub jej odpowiednika), nie możesz przede wszystkim wykonywać przebudowy równoległej lub online (a prawdopodobnie niektórzy użytkownicy Enterprise nie przebudowują lub nie przebudowują online). Jeśli masz ogólnoinstancyjny MAXDOP
ustawione na 1, nie mogą działać równolegle, chyba że zastąpisz je na poziomie instrukcji. Ale jeśli jesteś w 2012 lub 2014, używasz odpowiedniej edycji, a twoje przebudowy online mogą przebiegać równolegle, jesteś podatny na ten problem.
Jak wspomniałem powyżej, problem ten mógł wystąpić w SQL Server 2012 RTM, Service Pack 1, a nawet Service Pack 2, który został wydany 10 czerwca. Błąd został naprawiony długo po zamrożeniu kodu SP2, więc SP2 nie nie uwzględniaj tej poprawki ani żadnej z poprawek z SP1 CU #10 lub #11. Pisałem o tym tutaj. Gałąź RTM jest oficjalnie nieobsługiwana, więc nie zobaczysz tam poprawki. Problem może również wystąpić w SQL Server 2014.
Dostępne są teraz zbiorcze aktualizacje dla SQL Server 2012 Service Pack 1 i 2 oraz SQL Server 2014. Krótkie podsumowanie opcji, które polecam:
Jeśli Twój oddział / @@VERSION to…
| …powinieneś… | ||||
---|---|---|---|---|---|
| |||||
| |||||
Nic nie rób; już masz poprawkę. | |||||
| |||||
Nic nie rób; już masz poprawkę. | |||||
SQL Server 2014 RTM |
| ||||
Nic nie rób; już masz poprawkę. | |||||
* Jeśli zainstalujesz poprawkę SP1 lub aktualizację zbiorczą nr 11, a następnie zainstalujesz dodatek SP2, cofniesz te zmiany, w tym ta poprawka. |
Rozwiązania dla poprawki/awersu CU
Ponieważ wszystkie gałęzie, których dotyczy problem (z wyjątkiem 2012 RTM) mają poprawkę na żądanie i/lub aktualizację zbiorczą, która rozwiązuje problem, łatwą odpowiedzią jest po prostu zainstalowanie odpowiedniej aktualizacji. Możesz jednak znaleźć się w scenariuszu, w którym polityka Twojej firmy lub cykle testowania uniemożliwiają szybkie wdrożenie tych aktualizacji, a może nigdy. Jakie masz inne opcje?
- Możesz przestać wykonywać przebudowy, dopóki nie pojawi się nowy dodatek Service Pack dla twojego oddziału (może możesz po prostu pozostać przy
REORGANIZE
Na razie). Niestety, jeśli pracujesz w firmie „tylko z dodatkiem Service Pack”, Twoje możliwości są bardzo ograniczone:możesz bardziej walczyć o zmianę tej polityki lub możesz poczekać na dodatek Service Pack 3 dla programu SQL Server 2012 (co może trwać długo lub po prostu nigdy nie nadejdzie — zobacz FAQ #21 tutaj) lub dodatek Service Pack 1 dla SQL Server 2014 (którego prawdopodobnie nie zobaczymy przed 2015 r.). - Możesz ustawić
max degree of parallelism
do 1, jednak może to mieć negatywny wpływ na resztę obciążenia — pomyśl o takich rzeczach, jak wielowątkowe DBCC, równoległe zapytania względem lub między partycjonowanymi tabelami i inne operacje, w których możesz chcieć zmniejszyć równoległość, ale nie eliminować jej całkowicie. Ponadto to ustawienie nie wpłynie na przebudowę online z, powiedzmy, jawnymMAXDOP = 8
zakodowane na stałe w poleceniu, ponieważ zastąpi tosp_configure
ustawienie.
- Możesz dodać
WITH (MAXDOP = 1)
opcję ręcznie do wszystkich poleceń odbudowy. (Uwaga:nie musisz tego robić w przypadku indeksów XML, ponieważ z natury działają one w trybie jednowątkowym, ale po prostu zastosowałbym to do wszystkich przebudów w celu zapewnienia spójności i uniknięcia niepotrzebnej logiki warunkowej.)
- Możesz ustawić zadania konserwacji indeksu tak, aby były uruchamiane jako określony login, a następnie użyć Resource Governor do utworzenia grupy obciążenia, która ogranicza
MAX_DOP
tego loginu do 1, niezależnie od tego, co robią. Mam na to przykład w białej księdze z 2008 r., którą napisałem z Borisem Barysznikowem, Korzystanie z gubernatora zasobów, w sekcji zatytułowanej „Ograniczanie równoległości w przypadku intensywnych prac w tle”.
- Jeśli korzystasz z rozwiązania do obsługi indeksów Ola Hallengren, możesz dodać
@MaxDop
parametr do wywołańdbo.IndexOptimize
:
EXEC dbo.IndexOptimize /* other parameters */ @MaxDop = 1;
- Jeśli używasz SQL Sentry Fragmentation Manager, możesz dyktować poziom
MAXDOP
do użycia w Ustawieniach – i możesz to zrobić w całym przedsiębiorstwie, na instancję, na bazę danych, a nawet na pojedynczy indeks (w tym przypadku prawdopodobnie chciałbyś ustawić to na instancję, dla wszystkich instancji bez dostępnej poprawki):
Ustawienia Menedżera fragmentacji dla instancji (po lewej) i indywidualny indeks (po prawej). - Jeśli używasz planów konserwacji do przebudowy indeksu, będziesz musiał je zmienić, aby użyć zadań wykonywania instrukcji T-SQL i napisać swój
ALTER INDEX ... WITH (ONLINE = ON, MAXDOP = 1);
polecenia ręcznie (więc równie dobrze można przełączyć się na rozwiązanie automatyczne). Zobacz, zadanie przebudowy indeksu nie ma ujawnionej właściwości dlaMAXDOP
, mimo że był wielokrotnie proszony (ostatnio w 2012 r. przez Alberto Morillo, a już w 2006 r. przez Linchi Shea). I spójrz tylko na wszystkie inne przydatne właściwości, które ujawniają, takie jakAdvSortInTempdb
,ObjectTypeSelection
iTaskAllowesDatbaseSelection
[sic!]:
Wszystkie te opcje, ale nadal nie ma lekarstwa na MAXDOP.