sql >> Database teknologi >  >> RDS >> Sqlserver

Udforskning af lavprioritetslås-venteindstillinger i SQL Server 2014 CTP1

SQL Server 2014 CTP1 introducerer lav prioritet låsevente muligheder til brug med online indeksoperationer og partitionsskift.

For dem, der udnytter online indeksstyring eller indekspartitionering og partitionsskiftoperationer i SQL Server 2012 Enterprise Edition, har du måske på et tidspunkt oplevet blokering af din DDL-operation, da disse operationer stadig har nogle låsekrav.

For at illustrere, forestil dig, at jeg udfører følgende online-indeksgenopbygning med enkelt partition i SQL Server 2014 CTP1:

ÆNDRE INDEX [ClusteredIndex_on_ps_ShipDate]ON [dbo].[FactInternetSales]REBUILD PARTITION =(37)WITH (ONLINE=ON);

Og lad os tage et kig på de låse, der er erhvervet og frigivet under denne genopbygningsoperation ved hjælp af Extended Events og den følgende sessionsdefinition (dette er en session uden mål, og jeg så resultaterne via ruden "Se Live Data" i SQL Server Management Studio):

CREATE EVENT SESSION [Online_Index_Rebuild_Locks_Taken] PÅ SERVER TILFØJ BEGIVENHED sqlserver.lock_acquired( WHERE ([object_id]=(309576141))),ADD EVENT sqlserver.lock_released(MAKS_195MO)(MAKS41)7(MAKS4)7(MAKS4)6) 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=OFF, STARTUP_STATE=OFF);GO

Værdien 309576141 repræsenterer objekt-id'et for tabellen FactInternetSales.

Min online indeksgenopbygning af en enkelt partition tog 56 sekunder at fuldføre, og efter færdiggørelsen så jeg følgende låseoptagelses- og frigivelsesaktivitet:


Lås aktivitet til online-genopbygning af en enkelt partition

Som du kan se fra outputtet, involverer det, selvom genopbygningen er en online-operation, anskaffelse af låse i forskellige tilstande i løbet af operationens livscyklus. Ideelt set er låsevarigheden minimal (for eksempel – tidsstemplet er identisk for den første SCH_S lås erhvervet og frigivet). Men selv med en minimal mængde af låsning kan du helt sikkert støde på samtidighedsproblemer afhængigt af de transaktioner, der kører mod indekset, der genopbygges eller skiftes til.

Jeg nævnte i begyndelsen af ​​dette indlæg, at Microsoft introducerede lav prioritet låsevente muligheder for online-operationer og partitionsskiftoperationer i SQL Server 2014 CTP1. Med hensyn til partitionsskift, forestil dig, at jeg udfører følgende handling:

ÆNDRINGSTABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SKIFT PARTITION 37 TIL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales];

For at se låsene erhvervet og frigivet til denne operation, ændrede jeg min tidligere definerede udvidede hændelsessession til at inkludere de relevante objekter (kilde- og måltabel). Jeg så følgende:


Lås aktivitet for en partitionsskiftoperation

Skiftet til en tom partition fandt sted på mindre end et sekund, men vi ser stadig, at SCH_S og SCH_M låse var påkrævet under operationens livscyklus på både kilden og destinationen (309576141 er FactInternetSales og 398624463 er staging_FactInternetSales).

Så igen, mens varigheden af ​​låsningen kan være ekstremt kort, når der ikke er nogen samtidige transaktioner, der får adgang til de pågældende objekter, ved vi, at dette ikke altid er muligt, og så vores online-indeksgenopbygning og partitionsskifte-operationer kan faktisk blive blokeret.

Så med denne virkelighed introducerer SQL Server 2014 WAIT_AT_LOW_PRIORITY argument, der kan justeres med MAX_DURATION og ABORT_AFTER_WAIT muligheder for både ALTER INDEX og ALTER TABLE kommandoer, som vi kan bruge til både online-indeks- og partitionsskiftoperationer.

Hvad giver dette os mulighed for? Først og fremmest, lad os tale om, hvordan adfærden var før SQL Server 2014. Forestil dig som et eksempel, at jeg har følgende transaktion åben og uforpligtet:

BEGIN TRANSAKTION;SLET [dbo].[staging_FactInternetSales];

Hvis jeg forsøgte at udføre en ALTER TABLE SWITCH til tabellen staging_FactInternetSales som destination i en separat session, vil jeg blive blokeret, og anmodningen vil bare vente. Specifikt for dette eksempel ville jeg vente med en LCK_M_SCH_M vent type. Når jeg ruller tilbage eller forpligter min transaktion, kan handlingen gå videre og fuldføres.

Hvis jeg nu bruger SQL Server 2014's WAIT_AT_LOW_PRIORITY med MAX_DURATION og ABORT_AFTER_WAIT , kan jeg udnytte et par forskellige muligheder afhængigt af mine ansøgningskrav.

MAX_DURATION giver mig mulighed for at specificere det antal minutter, online-indeksgenopbygningen eller partitionsskiftoperationen vil vente. Hvis MAX_DURATION værdien er nået, kan vi indstille, hvad der derefter skal ske baseret på indstillingen af ​​ABORT_AFTER_WAIT , som kan være værdien NONE , SELF eller BLOCKERS :

  • NONE betyder, at indekshandlingen vil fortsætte med at forsøge handlingen.
  • SELF betyder, at hvis MAX_DURATION er nået, annulleres handlingen (genopbygning af onlineindeks eller partitionsskift).
  • Hvis BLOCKERS bruges, vil det dræbe alle transaktioner, der blokerer online-indeksgenopbygningen eller partitionsskiftoperationen (ikke en mulighed, efter min mening, der skal bruges let). BLOCKERS kræver også ALTER ANY CONNECTION tilladelse til anmodningen, der udsteder online-indeksgenopbygningen eller partitionsskiftoperationen.

Følgende kodeeksempler viser forskellige konfigurationsvariationer.

    Standardadfærd før 2014 (vent på ubestemt tid)

      Hvis du udfører følgende, vil det resultere i den adfærd, vi er vant til at se før SQL Server 2014 – og det kan stadig være, hvad du vil have eller forvente i visse scenarier:

      ÆNDR TABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SKIFT PARTITION 37 TIL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] MED (WAIT_AT_LOW_PRIORITET,NÅR PRIORITET, 
       

      Vent 1 minut og annuller DDL-handlingen

        Følgende eksempel venter i 1 minut, hvis der er en blokerende transaktion og vil få en "timeout-periode for låseanmodning overskredet" for SWITCH operation, hvis den maksimale varighed er nået:

        ÆNDRINGSTABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SKIFT PARTITION 37 TIL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] MED (WAIT_AT_LOW_PRIORITET, MAX_DAFURIT =MAX_DAFURIT) (MAX_DAFURIT) (MAX_DAFURIT). 

      Vent 1 minut og dræb blokererne

        Dette eksempel venter i 1 minut, hvis der er en blokerende transaktion, og vil derefter dræbe de blokerende transaktioner (kilde eller destination inkluderet), hvilket tillader SWITCH handling for at fuldføre.

        ÆNDR TABEL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales] SKIFT PARTITION 37 TIL [AdventureWorksDW2012].[dbo].[FactInternetSales] MED (WAIT_AT_LOW_PRIORITET, MAX_D MINUTTER =1_DVÆRDIG PRIORITET, MAX_DURET) (MAKS_BLOCKET); 

        I mit eksempel på en DELETE inde i en ikke-forpligtet transaktion, var der ingen fejl i mit SQL Server Management Studio-vindue, da jeg ikke havde en aktivt kørende sætning, men forsøg på en anden sætning inden for den session returnerede følgende fejlmeddelelse (da min session var blevet dræbt):

        Meddelelse 233, niveau 20, tilstand 0, linje 3
        Der er opstået en fejl på transportniveau ved afsendelse af anmodningen til serveren. (udbyder:Shared Memory Provider, fejl:0 – Ingen proces er i den anden ende af røret.)

      Dræb blokeringen(e) med det samme (kilde eller destination for SWITCH)

        Følgende er et eksempel på at dræbe blokeren med det samme – og i mit eksempel skete skiftet i sekundet, og den session, der var blokeren, blev faktisk dræbt:

        ÆNDRINGSTABEL [AdventureWorksDW2012].[dbo].[FactInternetSales] SKIFT PARTITION 37 TIL [AdventureWorksDW2012].[dbo].[staging_FactInternetSales]WITH (WAIT_AT_LOW_PRIORITY =WAIT_AT_LOW_PRIORITET, MAX_DURATIONS, MAX_DURATIONS, MAX_DURATIONS) (MAX_DURATIONS); 

    Et sidste positivt aspekt, jeg ville fremhæve...

    SQL Server-fejlloggen giver en vis standardrevision af brugen af ​​lav prioritet låsevent, inklusive information om ABORT_AFTER_WAIT operation i tråd med offeroplysningerne:

    Dato 9/10/2013 1:37:15 PM
    Log SQL Server (Aktuel – 9/10/2013 12:03:00 PM)
    Kilde spid51
    Besked
    Proces ID 57 blev dræbt af en ABORT_AFTER_WAIT =BLOCKERS DDL-sætning på database_id =5, object_id =309576141.

    Og du vil også se separate poster for selve den oprindelige handling. For eksempel:

    En ALTER TABLE SWITCH-sætning blev udført på databasen 'AdventureWorksDW2012', tabel 'staging_FactInternetSales' af værtsnavnet 'WIN-4T7S36VMSD9', værtsproces-ID 1360 med måltabellen 'AdventureWorksDW2012.dbo.Fact_InternetWorksDW2012.dbo.Fact_InternetWorksDW2012.dbo.Fact_InternetWorks_Sales_1. BLOKERERE. Blokering af brugersessioner vil blive dræbt efter den maksimale varighed af ventetid.

    Denne form for logning er meget nyttig til fejlfinding og revisionsformål, og jeg er glad for at se den.


  1. Hvad er SQL Server? (Definition, versioner, udgaver)

  2. SQL Vælg mellem to tabeller med indre sammenføjning og grænse

  3. Sådan finder du datoformatet, der bruges i den aktuelle session i SQL Server (T-SQL)

  4. Hvordan forsinker jeg kolonner i MySQL?