Es gibt einen Regressionsfehler in SQL Server 2012 und SQL Server 2014, bei dem, wenn Sie einen Index parallel online neu erstellen und auch ein schwerwiegender Fehler wie ein Sperrtimeout auftritt, Datenverlust oder -beschädigung . Dies sollte ein relativ seltenes Szenario sein (Phil Brammer hat eine einfache Repro in Connect #795134), aber Datenverlust ist Datenverlust, und ich bin nicht bereit, zu spielen. Der Fix wird in KB #2969896 beschrieben:FIX:Datenverlust im gruppierten Index tritt auf, wenn Sie den Online-Build-Index in SQL Server 2012 ausführen.
Nicht jeder muss sich um dieses Problem kümmern. Wenn Sie nicht Enterprise (oder eine gleichwertige) Edition ausführen, können Sie überhaupt keine parallelen oder Online-Neuerstellung durchführen (und es gibt wahrscheinlich einige Leute auf Enterprise, die nicht neu erstellen oder nicht online neu erstellen). Wenn Sie instanzweites MAXDOP
haben auf 1 gesetzt, können sie nicht parallel gehen, es sei denn, Sie überschreiben es auf Anweisungsebene. Wenn Sie jedoch 2012 oder 2014 verwenden, eine angemessene Edition ausführen und Ihre Online-Neuaufbauten parallel ausgeführt werden könnten, sind Sie für dieses Problem anfällig.
Wie ich oben angedeutet habe, könnte sich dieses Problem in SQL Server 2012 RTM, Service Pack 1 und sogar Service Pack 2 manifestieren, das am 10. Juni veröffentlicht wurde. Der Fehler wurde erst lange nach dem Einfrieren des SP2-Codes behoben, also SP2 Diesen Fix oder einen der Fixes von SP1 CU Nr. 10 oder Nr. 11 nicht enthalten. Ich habe hier darüber gebloggt. Der RTM-Zweig wird offiziell nicht mehr unterstützt, sodass Sie dort keinen Fix sehen werden. Das Problem kann auch in SQL Server 2014 auftreten.
Es sind jetzt kumulative Updates für SQL Server 2012 Service Pack 1 &2 sowie SQL Server 2014 verfügbar. Eine kurze Zusammenfassung der von mir empfohlenen Optionen:
Wenn Ihr Zweig / @@VERSION … ist
| … sollten Sie… | ||||
---|---|---|---|---|---|
| |||||
| |||||
Nichts tun; Sie haben die Lösung bereits. | |||||
| |||||
Nichts tun; Sie haben die Lösung bereits. | |||||
SQL Server 2014 RTM |
| ||||
Nichts tun; Sie haben die Lösung bereits. | |||||
* Wenn Sie den SP1-Hotfix oder das kumulative Update Nr. 11 installieren und dann SP2 installieren, werden diese Änderungen rückgängig gemacht, einschließlich diese Korrektur. |
Lösungen für Hotfix/CU averse
Da alle betroffenen Zweige (mit Ausnahme von 2012 RTM) über einen On-Demand-Hotfix und/oder ein kumulatives Update verfügen, das das Problem behebt, ist die einfache Antwort, einfach das entsprechende Update zu installieren. Möglicherweise befinden Sie sich jedoch in einem Szenario, in dem Ihre Unternehmensrichtlinie oder Testzyklen Sie daran hindern, diese Updates schnell oder vielleicht überhaupt bereitzustellen. Welche anderen Möglichkeiten haben Sie also?
- Sie können mit der Durchführung von Neuaufbauten aufhören, bis ein neues Service Pack für Ihren Zweig verfügbar ist (vielleicht können Sie einfach bei
REORGANIZE
bleiben zur Zeit). Wenn Sie in einem „nur Service Pack“-Unternehmen arbeiten, sind Ihre Optionen leider sehr begrenzt:Sie können härter kämpfen, um diese Richtlinie zu ändern, oder Sie können auf SQL Server 2012 Service Pack 3 warten (was lange dauern kann oder kann einfach nie kommen – siehe FAQ #21 hier) oder SQL Server 2014 Service Pack 1 (das wir wahrscheinlich nicht vor 2015 sehen werden). - Sie können den instanzweiten
max degree of parallelism
festlegen auf 1, dies kann sich jedoch negativ auf den Rest Ihrer Arbeitslast auswirken – denken Sie an Dinge wie Multithread-DBCC, parallele Abfragen für oder zwischen partitionierten Tabellen und andere Vorgänge, bei denen Sie die Parallelität reduzieren, aber nicht ganz eliminieren möchten. Außerdem wirkt sich diese Einstellung nicht auf einen Online-Neuaufbau mit beispielsweise einem explizitenMAXDOP = 8
aus in den Befehl fest codiert, da dies densp_configure
überschreibt Einstellung.
- Sie können den
WITH (MAXDOP = 1)
hinzufügen Option manuell auf alle Ihre Wiederherstellungsbefehle. (Hinweis:Sie müssen dies nicht für XML-Indizes tun, da sie von Natur aus Single-Threaded ausführen, aber ich würde es einfach auf alle Neuaufbauten anwenden, um die Konsistenz zu gewährleisten und unnötige bedingte Logik zu vermeiden.)
- Sie können Ihre Indexwartungsjobs so einstellen, dass sie als ein bestimmtes Login ausgeführt werden, und dann die Ressourcenkontrolle verwenden, um eine Workload-Gruppe zu erstellen, die den
MAX_DOP
dieses Logins begrenzt auf 1, unabhängig davon, was sie tun. Ich habe ein Beispiel dafür in dem White Paper von 2008, das ich mit Boris Baryshnikov geschrieben habe, Using the Resource Governor, im Abschnitt mit dem Titel „Limiting Parallelism for Intensive Background Jobs.“
- Wenn Sie die Indexwartungslösung von Ola Hallengren verwenden, können Sie den
@MaxDop
hinzufügen Parameter für Ihre Aufrufe vondbo.IndexOptimize
:
EXEC dbo.IndexOptimize /* other parameters */ @MaxDop = 1;
- Wenn Sie den SQL Sentry Fragmentation Manager verwenden, können Sie die Stufe von
MAXDOP
vorgeben unter Einstellungen verwenden – und Sie können dies unternehmensweit, pro Instanz, pro Datenbank oder sogar pro einzelnem Index tun (in diesem Fall möchten Sie dies wahrscheinlich pro Instanz festlegen, für alle Instanzen ohne verfügbaren Fix):
Fragmentierungs-Manager-Einstellungen für die Instanz (links) und einen individuellen Index (rechts). - Wenn Sie Wartungspläne für Ihre Indexerneuerungen verwenden, müssen Sie sie ändern, um Aufgaben zum Ausführen von T-SQL-Anweisungen zu verwenden, und Ihren
ALTER INDEX ... WITH (ONLINE = ON, MAXDOP = 1);
Befehle manuell (kann also auch zu einer automatisierten Lösung wechseln). Sehen Sie, der Index-Wiederaufbau-Task hat keine exponierte Eigenschaft fürMAXDOP
, obwohl es mehrfach angefordert wurde (zuletzt 2012 von Alberto Morillo und bereits 2006 von Linchi Shea). Und schauen Sie sich all diese anderen nützlichen Eigenschaften an, die sie offenlegen, wieAdvSortInTempdb
,ObjectTypeSelection
undTaskAllowesDatbaseSelection
[sic!]:
All diese Optionen, aber immer noch kein Heilmittel für MAXDOP.