sql >> Databasteknik >  >> RDS >> Sqlserver

Fixar för SQL Server 2012 &2014 Online Index Rebuild Issue

Det finns en regressionsbugg i SQL Server 2012 och SQL Server 2014, där du kan uppleva dataförlust eller korruption . Detta borde vara ett relativt sällsynt scenario (Phil Brammer har en enkel repro i Connect #795134), men dataförlust är dataförlust, och jag är inte beredd att spela. Korrigeringen beskrivs i KB #2969896:FIX:Dataförlust i klustrade index uppstår när du kör onlinebyggindex i SQL Server 2012.

Alla behöver inte oroa sig för denna fråga. Om du inte kör Enterprise (eller motsvarande) Edition, kan du inte utföra parallella eller online-ombyggnader i första hand (och det finns förmodligen en del på Enterprise som inte bygger om eller inte bygger om online). Om du har instansomfattande MAXDOP satt till 1, kan de inte gå parallellt om du inte åsidosätter det på satsnivån. Men om du är på 2012 eller 2014 och kör en adekvat utgåva, och dina online-ombyggnader kan gå parallellt, är du sårbar för detta problem.

Som jag antydde ovan kunde detta problem manifestera sig i SQL Server 2012 RTM, Service Pack 1 och till och med Service Pack 2, som släpptes den 10 juni. Felet fixades inte förrän långt efter att SP2-koden frysts, så SP2 gör det. inkludera inte denna korrigering eller någon av korrigeringarna från SP1 CU #10 eller #11. Jag bloggade om detta här. RTM-grenen saknar officiellt stöd, så du kommer inte att se en fix där. Problemet kan också uppstå i SQL Server 2014.

Det finns nu kumulativa uppdateringar tillgängliga för SQL Server 2012 Service Pack 1 &2 samt SQL Server 2014. En snabb sammanfattning av alternativen jag rekommenderar:

Om din gren / @@VERSION är...

sårbar kanske inte sårbart
...du borde...
SQL Server 2012 RTM 11.0.2100 -> 11.0.2999
  1. Uppgradera till Service Pack 1 eller Service Pack 2 (RTM saknar stöd!) och tillämpa den relevanta korrigeringen från KB #2969896.
  2. Om du inte kan implementera 1., använd en eller flera av lösningarna nedan.
SQL Server 2012 Service Pack 1 11.0.3000 -> 11.0.3436
  1. Använd kumulativ uppdatering #11 (11.0.3449) från KB #2975396. Om du sedan installerar Service Pack 2 bör du följa upp med SP2 CU #1.*
  2. Om 1. misslyckas, använd en eller flera av lösningarna nedan.
11.0.3437 -> 11.0.5057 Gör ingenting; du har redan korrigeringen.
SQL Server 2012 Service Pack 2 11.0.5058 –> 11.0.5521
  1. Använd kumulativ uppdatering #1 (11.0.5532) från KB #2976982.
  2. Om 1. misslyckas, använd en eller flera av lösningarna nedan.
11.0.5522 eller senare Gör ingenting; du har redan korrigeringen.
SQL Server 2014 RTM 12.0.2000 –> 12.0.2369
  1. Använd kumulativ uppdatering #2 (12.0.2370) från KB #2967546.
  2. Om 1. misslyckas, använd en eller flera av lösningarna nedan.
12.0.2370 eller senare Gör ingenting; du har redan korrigeringen.
* Om du installerar SP1-snabbkorrigeringen eller kumulativ uppdatering #11 och sedan installerar SP2 kommer du att ångra dessa ändringar, inklusive denna fix.

Lösningar för snabbkorrigeringen/CU-averse

Eftersom alla berörda grenar (nåja, förutom 2012 RTM) har en snabbkorrigering på begäran och/eller en kumulativ uppdatering som åtgärdar problemet, är det enkla svaret att bara installera den relevanta uppdateringen. Men du kan vara i ett scenario där din företagspolicy eller testcykler hindrar dig från att distribuera dessa uppdateringar snabbt, eller kanske någonsin. Så vilka andra alternativ har du?

  • Du kan sluta utföra ombyggnader tills det finns ett nytt service pack tillgängligt för din filial (kanske kan du bara hålla fast vid REORGANIZE tills vidare). Tyvärr, om du är i ett "service pack only"-företag, är dina alternativ mycket begränsade:du kan kämpa hårdare för att ändra den policyn, eller så kan du vänta på SQL Server 2012 Service Pack 3 (vilket kan ta lång tid, eller kanske kom helt enkelt aldrig – se FAQ #21 här) eller SQL Server 2014 Service Pack 1 (som vi förmodligen inte kommer att se innan 2015 rullar runt).
  • Du kan ställa in den instansomfattande max degree of parallelism till 1, men detta kan ha en negativ effekt på resten av din arbetsbelastning – tänk på saker som flertrådad DBCC, parallella frågor mot eller mellan partitionerade tabeller och andra operationer där du kanske vill minska parallelliteten men inte eliminera den helt. Den här inställningen kommer inte heller att påverka en online-ombyggnad med till exempel en explicit MAXDOP = 8 hårdkodad i kommandot, eftersom detta kommer att åsidosätta sp_configure inställning.
  • Du kan lägga till WITH (MAXDOP = 1) alternativet manuellt till alla dina återuppbyggnadskommandon. (Obs:du behöver inte göra detta för XML-index, eftersom de i sig körs entrådade, men jag skulle bara tillämpa det på alla ombyggnader för konsekvens och för att undvika onödig villkorlig logik.)
  • Du kan ställa in dina indexunderhållsjobb så att de körs som en specifik inloggning och sedan använda Resource Governor för att skapa en arbetsbelastningsgrupp som begränsar inloggningens MAX_DOP till 1, oavsett vad de gör. Jag har ett exempel på detta i vitboken från 2008 som jag skrev tillsammans med Boris Baryshnikov, Using the Resource Governor, i avsnittet med rubriken "Limiting Parallelism for Intensive Background Jobs."
  • Om du använder Ola Hallengrens indexunderhållslösning kan du lägga till @MaxDop parameter till dina anrop till dbo.IndexOptimize :
    EXEC dbo.IndexOptimize
        /* other parameters */
        @MaxDop = 1;
  • Om du använder SQL Sentry Fragmentation Manager kan du diktera nivån för MAXDOP att använda under Inställningar – och du kan göra det här i hela företaget, per instans, per databas eller till och med per enskilt index (i det här fallet vill du antagligen ställa in detta per instans, för alla instanser utan en tillgänglig fix):


    Fragmentation Manager-inställningar för instansen (vänster) och ett individuellt index (höger).

  • Om du använder underhållsplaner för dina indexombyggnader, måste du ändra dem för att använda Execute T-SQL Statement Tasks, och skriv ditt ALTER INDEX ... WITH (ONLINE = ON, MAXDOP = 1); kommandon manuellt (så kan lika gärna byta till en automatiserad lösning). Se, Index Rebuild Task har inte en exponerad egenskap för MAXDOP , även om det har begärts flera gånger (senast 2012, av Alberto Morillo, och så långt tillbaka som 2006, av Linchi Shea). Och titta bara på alla dessa andra användbara egenskaper de avslöjar, som AdvSortInTempdb , ObjectTypeSelection och TaskAllowesDatbaseSelection [sic!]:


    Alla dessa alternativ, men fortfarande inget botemedel mot MAXDOP.


  1. Vad är ett index i SQL?

  2. Saker du måste veta om FND_LOBS Table i Oracle Apps

  3. Hur genererar man hela DDL för ett Oracle-schema (skriptbart)?

  4. Hur LOCATE() fungerar i MariaDB