sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server Latches – Andra Latches att veta om

För att avsluta min korta serie artiklar om spärrar, den här gången ska jag diskutera några andra spärrar i SQL Server som du kanske ser ibland men som inte förtjänar en komplett artikel för sig. Som vanligt rekommenderar jag starkt att du läser det första inlägget i serien före detta, så att du har all allmän bakgrundskunskap om spärrar.

LOG_MANAGER-spärren

LOG_MANAGER-låset används för synkronisering under vissa operationer som involverar transaktionsloggen, och det finns en LOG_MANAGER-lås per databas (eftersom varje databas har sin egen logghanterare). Den kan endast förvärvas i exklusivt läge och kan vara en flaskhals under tillväxt av transaktionsloggfiler. Scenariot där det kommer att bli uppenbart som ett problem är:

  • Loggfilen har en liten autotillväxtuppsättning
  • Det finns många samtidiga anslutningar som genererar transaktionsloggposter
  • Loggfilen måste hela tiden växa

När loggfilen tar slut på utrymme måste den växa. Den första tråden för att realisera mer loggutrymme krävs förvärvar LOG_MANAGER-låset i EX-läge och fortsätter att växa loggfilen. Många andra trådar fortsätter att försöka generera loggposter och hamna i kön för LOG_MANAGER-låset, så att de kan utöka loggfilen. När den första tråden släpper spärren, får nästa den och inser att stocken redan har vuxit, så tappar den och fortsätter. Och så vidare och så vidare. Detta flaskhalsmönster kallas för övrigt en låskonvoj .

Du kan ungefär tänka på det som exakt samma flaskhals som med FGCB_ADD_REMOVE-spärren som jag diskuterade tidigare i serien, men med loggfiltillväxt istället för datafiltillväxt. Men med FGCB_ADD_REMOVE-låset har instansen vanligtvis omedelbar filinitiering aktiverad, så filtillväxten är mycket snabb, men med LOG_MANAGER-låset *måste* loggen nollinitieras och tiden som slösas bort i låskön är längre .

Lösningen för denna flaskhals har tre delar:

  1. Ställ in loggfilens autotillväxt korrekt, så att loggen inte växer ofta
  2. Storleken på loggen är korrekt för arbetsbelastningen, så att loggen inte ska växa alls
  3. Se till att loggen rensas korrekt, så att loggen inte behöver växa

Om alla dessa är på plats bör du inte se LOG_MANAGER-spärren vara en vanlig flaskhals, och jag berättar mer om detta i mitt inlägg här.

ACCESS_METHODS_DATASET_PARENT-spärren

När antingen en heap eller ett index nås, finns det internt ett objekt som kallas HeapDataSetSession eller IndexDataSetSession, respektive. När en parallell skanning utförs, har trådarna som gör själva arbetet med skanningen var och en en "underordnad" datauppsättning (en annan instans av de två objekt som jag just beskrev), och huvuddatauppsättningen, som verkligen styr genomsökningen, kallas "föräldern".

När en av skanningsarbetartrådarna har uttömt uppsättningen rader som den ska skanna, måste den få ett nytt intervall genom att komma åt den överordnade datamängden, vilket innebär att man skaffar ACCESS_METHODS_DATASET_PARENT-låset i exklusivt läge. Även om detta kan verka som en flaskhals, är det inte riktigt, och det finns inget du kan göra för att stoppa trådarna som utför en parallell skanning från att ibland visa en LATCH_EX väntan på denna spärr.

Frågan du bör ställa dig själv är:ska den här frågan utföra en parallell skanning i första hand? Det är fullt möjligt att något hände som tvingade frågeplanen att inkludera en parallell skanning när det kanske inte är det mest effektiva sättet för frågan att köras. Exempel på saker som kan få en plan att ändras till en parallell skanning är:

  • Inaktuell statistik
  • Ett saknat eller borttaget icke-klustrat index
  • Ny kod som tvingar fram en genomsökning på grund av en implicit omvandling – en datatypsfel överensstämmer mellan en kolumn och en variabel/parameter, vilket utesluter användningen av ett icke-klustrat index
  • Ny kod som tvingar fram en skanning eftersom aritmetik utförs på en tabellkolumn istället för en variabel/parameter, vilket återigen utesluter användningen av ett icke-klustrat index
  • Datatillväxt sker och en genomsökning är verkligen den mest effektiva planen

Eller så kan den här frågan kräver en genomsökning, i vilket fall LATCH_EX väntar på att ACCESS_METHODS_DATASET_PARENT bara är en del av din miljö.

ACCESS_METHODS_HOBT_VIRTUAL_ROOT-spärren

Varje instans av denna spärr skyddar en post i Storage Engine-metadata för ett b-träd, särskilt sid-ID:t för b-trädets rotsida (sidan högst upp i triangeln som vi vanligtvis ser som ett index) . Jag säger specifikt b-tree och inte index , eftersom ett index kan ha flera partitioner, som var och en har ett b-träd (i huvudsak en del av det totala indexet, men med nyckelbegränsningar för lågt värde och högt värde).

Varje gång en tråd behöver korsa ett b-träd måste den börja på rotsidan och arbeta sig ner till bladnivån. För att läsa metadata som innehåller sid-ID:t för rotsidan måste tråden skaffa ACCESS_METHODS_HOBT_VIRTUAL_ROOT-spärren i SH-läge, för att se till att sid-ID:t inte håller på att ändras. När en tråd behöver ändra sid-ID för rotsidan måste den skaffa spärren i EX-läge.

Varför skulle rotsidan för ett b-träd någonsin ändras? När antalet indexposter på rotsidan växer kommer den så småningom att fyllas och en siddelning kommer att ske. När det händer blir den aktuella rotsidan och sidan den delas upp i en ny nivå i b-trädet, och en helt ny rotsida skapas, med två indexposter i, som pekar på den gamla rotsidan och sidan den delas upp i. Det nya rotsidans ID måste matas in i metadata, så spärren hämtas i EX-läge. Detta kommer att hända några gånger snabbt när ett index på en tom tabell börjar fyllas i med inlägg men är inte något du kommer att se som ett pågående problem med prestandaflaskhalsar.

Sammanfattning

Som jag är säker på att du har lärt dig från den här serien, innebär att förstå låsningar och flaskhalsar med låsningar att veta lite mer om vad som händer inuti Storage Engine än för allmän analys av väntestatistik.

Jag brukar råda folk *inte* att börja felsöka prestanda genom att titta på spärrstatistik (via sys.dm_os_latch_stats ) men istället för att alltid börja med väntestatistik (se mitt inlägg här) och bara fördjupa sig i låsningar om LATCH_EX eller LATCH_SH är en av de översta handfulla väntetiderna på SQL Server-instansen.

Om du har några frågor om spärrar får du gärna höra av dig.


  1. Hur ditt småföretag kan dra nytta av cloud computing

  2. Hur hanterar jag att öppna/stänga Db-anslutning i en Go-app?

  3. Lista över alla index- och indexkolumner i SQL Server DB

  4. När du använder GETDATE() på många ställen, är det bättre att använda en variabel?