sql >> Databasteknik >  >> RDS >> Sqlserver

Utforska alternativ för lågprioriterade lås väntan i SQL Server 2014 CTP1

SQL Server 2014 CTP1 introducerar lågprioriterade väntealternativ för lås för användning med onlineindexoperationer och partitionsväxlar.

För dem som utnyttjar onlineindexhantering eller indexpartitionering och partitionsväxlingsoperationer i SQL Server 2012 Enterprise Edition, kan du vid ett tillfälle ha upplevt blockering av din DDL-operation eftersom dessa operationer fortfarande har vissa låsningskrav.

För att illustrera, föreställ dig att jag kör följande online-indexombyggnad med en partition i SQL Server 2014 CTP1:

ÄNDRA INDEX [ClusteredIndex_on_ps_ShipDate]PÅ [dbo].[FactInternetSales]BYGGA OM PARTITION =(37) MED (ONLINE=PÅ);

Och låt oss ta en titt på låsen som förvärvades och släpptes under den här ombyggnadsoperationen med hjälp av Extended Events och följande sessionsdefinition (detta är en session utan mål och jag såg resultaten via rutan "Titta på Live Data" i SQL Server Management Studio):

SKAPA EVENT SESSION [Online_Index_Rebuild_Locks_Taken] PÅ SERVER LÄGG TILL HÄNDELSE sqlserver.lock_acquired( WHERE ([object_id]=(309576141))),ADD EVENT sqlserver.lock_released( WITHERE_09TH)(WITHERE)(WITHERE)(WITHERE) 4096 KB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY=30 SEKUNDER, MAX_EVENT_SIZE=0 KB, MEMORY_PARTITION_MODE=INGEN, TRACK_CAUSALITY=AV, STARTUP_STATE=OFF);GO

Värdet 309576141 representerar objekt-ID för tabellen FactInternetSales.

Min online-indexombyggnad av en enskild partition tog 56 sekunder att slutföra och efter slutförandet såg jag följande låsupptagnings- och frigöringsaktivitet:


Lås aktivitet för online-ombyggnad med en partition

Som du kan se från resultatet, även om ombyggnaden är en onlineoperation, innebär den att man skaffar lås i olika lägen under operationens livscykel. Helst är låstiden minimal (till exempel – tidsstämpeln är identisk för den första SCH_S lås förvärvat och släppt). Men även med en minimal mängd låsning kan du säkert stöta på samtidighetsproblem beroende på vilka transaktioner som körs mot indexet som byggs om eller växlas till.

Jag nämnde i början av det här inlägget att Microsoft introducerade lågprioriterade låsväntningsalternativ för onlineoperationer och partitionsväxlingsoperationer i SQL Server 2014 CTP1. När det gäller partitionsväxlar, föreställ dig att jag utför följande operation:

ÄNDRA TABELL [AdventureWorksDW2012].[dbo].[FactInternetSales] BYT PARTITION 37 TILL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales];

För att se låsen som förvärvats och släppts för denna operation, modifierade jag min tidigare definierade utökade händelsesession för att inkludera tillämpliga objekt (källa och måltabell). Jag såg följande:


Lås aktivitet för en partitionsväxlingsoperation

Bytet till en tom partition skedde på mindre än en sekund, men vi ser fortfarande att SCH_S och SCH_M lås krävdes under operationens livscykel på både källan och destinationen (309576141 är FactInternetSales och 398624463 är staging_FactInternetSales).

Så återigen, även om varaktigheten av låsningen kan vara extremt kort när det inte finns några samtidiga transaktioner som kommer åt objekten i fråga, vet vi att detta inte alltid är möjligt och så vår online-indexombyggnad och partitionsväxlingsoperationer kan verkligen blockeras.

Så med denna verklighet introducerar SQL Server 2014 WAIT_AT_LOW_PRIORITY argument som kan justeras med MAX_DURATION och ABORT_AFTER_WAIT alternativ för både ALTER INDEX och ALTER TABLE kommandon som vi kan använda för både onlineindex och partitionsväxlingsoperationer.

Vad tillåter detta oss att göra? Först och främst, låt oss prata om hur beteendet var före SQL Server 2014. Föreställ dig som ett exempel att jag har följande transaktion öppen och oengagerad:

BÖRJA TRANSAKTION;RADERA [dbo].[staging_FactInternetSales];

Om jag försökte utföra en ALTER TABLE SWITCH till tabellen staging_FactInternetSales som en destination i en separat session, kommer jag att blockeras och förfrågan kommer bara att vänta. Specifikt för det här exemplet skulle jag vänta med en LCK_M_SCH_M vänta typ. När jag återställer eller genomför min transaktion kan operationen gå framåt och slutföras.

Om jag nu använder SQL Server 2014:s WAIT_AT_LOW_PRIORITY med MAX_DURATION och ABORT_AFTER_WAIT , jag kan utnyttja några olika alternativ beroende på mina applikationskrav.

MAX_DURATION tillåter mig att ange hur många minuter onlineindexombyggnaden eller partitionsväxlingsoperationen kommer att vänta. Om MAX_DURATION värdet nås, kan vi ställa in vad som händer härnäst baserat på inställningen för ABORT_AFTER_WAIT , som kan vara värdet NONE , SELF eller BLOCKERS :

  • NONE betyder att indexoperationen kommer att fortsätta att försöka åtgärden.
  • SELF betyder att om MAX_DURATION är uppnådd, avbryts operationen (onlineindexombyggnaden eller partitionsväxeln).
  • Om BLOCKERS används, kommer det att döda alla transaktioner som blockerar online-indexombyggnaden eller partitionsväxlingsoperationen (inte ett alternativ, enligt min mening, att användas lätt). BLOCKERS kräver också ALTER ANY CONNECTION behörighet för begäran som utfärdar onlineindexombyggnaden eller partitionsväxlingsoperationen.

Följande kodexempel visar olika konfigurationsvariationer.

    Standardbeteende före 2014 (vänta på obestämd tid)

      Att köra följande kommer att resultera i beteendet vi är vana vid att se pre-SQL Server 2014 – och det kan fortfarande vara vad du vill eller förväntar dig för vissa scenarier:

      ÄNDRA TABELL [AdventureWorksDW2012].[dbo].[FactInternetSales] BYT PARTITION 37 TILL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] MED (WAIT_AT_LOW_PRIORITET, MAX_DURITET, MAX_DURITET) =FÖRRETT; 

    Vänta 1 minut och avbryt DDL-operationen

      Följande exempel väntar i 1 minut om det finns en blockerande transaktion och kommer att få en "tidsgräns för låsbegäran har överskridits" för SWITCH operation om den maximala varaktigheten uppnås:

      ÄNDRA TABELL [AdventureWorksDW2012].[dbo].[FactInternetSales] BYT PARTITION 37 TILL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] MED (WAIT_AT_LOW_PRIORITET, MAX_DAFURITET) =
       

      Vänta 1 minut och döda blockerarna

        Det här exemplet väntar i 1 minut om det finns en blockerande transaktion och kommer sedan att döda de blockerande transaktionerna (källa eller destination ingår), vilket tillåter SWITCH operation för att slutföra.

        ÄNDRA TABELL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] VÄXLA PARTITION 37 TILL [AdventureWorksDW2012].[dbo].[FactInternetSales] MED (WAIT_AT_LOW_PRIORITET, MAX_D BLOCK-PRIORITET, MAX_D BLOCK-PRIORITET, MAX_D); 

        I mitt exempel på en DELETE inuti en ej engagerad transaktion fanns det inget fel i mitt SQL Server Management Studio-fönster eftersom jag inte hade en aktivt körande sats, men ett försök med en annan sats inom den sessionen returnerade följande felmeddelande (eftersom min session hade dödats):

        Msg 233, Level 20, State 0, Line 3
        Ett transportnivåfel har inträffat när förfrågan skickas till servern. (leverantör:Shared Memory Provider, fel:0 – Ingen process finns i andra änden av röret.)

      Döda blockerarna omedelbart (källa eller destination för SWITCH)

        Följande är ett exempel på att döda blockeraren omedelbart – och i mitt exempel skedde bytet på en sekund och faktiskt den session som var blockeraren dödades:

        ÄNDRA TABELL [AdventureWorksDW2012].[dbo].[FactInternetSales] BYT PARTITION 37 TILL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales]WITH (WAIT_AT_LOW_PRIORITY =MAX_DURITERS, MAX_DURITERS, MAX_DURITERS, MAX_DURATIONS); 

    En sista positiv aspekt som jag ville nämna...

    SQL Server-felloggen tillhandahåller en viss standardgranskning av vänteanvändningen med låg prioritet, inklusive information om ABORT_AFTER_WAIT operation i linje med informationen om offret:

    Datum 2013-09-10 13:37:15
    Logg SQL Server (Aktuell – 2013-09-10 12:03:00 PM)
    Källa spid51
    Meddelande
    Process ID 57 dödades av en ABORT_AFTER_WAIT =BLOCKERS DDL-sats på database_id =5, object_id =309576141.

    Och du kommer också att se separata poster för själva den ursprungliga operationen. Till exempel:

    En ALTER TABLE SWITCH-sats exekverades på databasen 'AdventureWorksDW2012', tabellen 'staging_FactInternetSales' av värdnamnet 'WIN-4T7S36VMSD9', värdprocess-ID 1360 med måltabellen 'AdventureWorksDW2012.dbo.FactInternetWorksDW2012.dbo.FactInternetWorksDW2012.dbo.FactInternetWorksales_1. BLOCKERS. Blockerande användarsessioner kommer att avbrytas efter den maximala väntetiden.

    Den här typen av loggning är mycket användbar för felsökning och revision, och jag är glad att se den.


  1. Uppgradera MySQL till MariaDB 10 (Del 1 – Installera MariaDB 5.5)

  2. Förstör en Postgres DB på Heroku

  3. Oracle Regular Expressions. Dangerous Range

  4. Ansluter SAP Lumira till Microsoft Access