Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Fixes für SQL Server 2012 &2014 Online Index Rebuild Problem

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

anfällig vielleicht nicht anfällig
… sollten Sie…
SQL Server 2012 RTM 11.0.2100 -> 11.0.2999
  1. Führen Sie ein Upgrade auf Service Pack 1 oder Service Pack 2 durch (RTM wird nicht mehr unterstützt!) und wenden Sie den relevanten Fix aus KB #2969896 an.
  2. Wenn Sie 1. nicht implementieren können, wenden Sie eine oder mehrere der folgenden Problemumgehungen an.
SQL Server 2012 Service Pack 1 11.0.3000 -> 11.0.3436
  1. Kumulatives Update Nr. 11 (11.0.3449) von KB Nr. 2975396 anwenden. Wenn Sie dann Service Pack 2 installieren, sollten Sie mit SP2 CU #1.*
  2. fortfahren
  3. Falls 1. fehlschlägt, wenden Sie eine oder mehrere der folgenden Problemumgehungen an.
11.0.3437 -> 11.0.5057 Nichts tun; Sie haben die Lösung bereits.
SQL Server 2012 Service Pack 2 11.0.5058 –> 11.0.5521
  1. Kumulatives Update Nr. 1 (11.0.5532) von KB Nr. 2976982 anwenden.
  2. Falls 1. fehlschlägt, wenden Sie eine oder mehrere der folgenden Problemumgehungen an.
11.0.5522 oder höher Nichts tun; Sie haben die Lösung bereits.
SQL Server 2014 RTM 12.0.2000 –> 12.0.2369
  1. Kumulatives Update Nr. 2 (12.0.2370) von KB Nr. 2967546 anwenden.
  2. Falls 1. fehlschlägt, wenden Sie eine oder mehrere der folgenden Problemumgehungen an.
12.0.2370 oder höher 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 expliziten MAXDOP = 8 aus in den Befehl fest codiert, da dies den sp_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 von dbo.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ür MAXDOP , 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, wie AdvSortInTempdb , ObjectTypeSelection und TaskAllowesDatbaseSelection [sic!]:


    All diese Optionen, aber immer noch kein Heilmittel für MAXDOP.