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 hvisMAX_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,0pre>NÅR PRIORITET, 0)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
Meddelelse 233, niveau 20, tilstand 0, linje 3DELETE
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):
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
Dato 9/10/2013 1:37:15 PMABORT_AFTER_WAIT
operation i tråd med offeroplysningerne:
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.