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

SQL Server Latches - Andre Latches at vide om

For at afslutte min korte serie af artikler om låse, vil jeg denne gang diskutere et par andre låse i SQL Server, som du måske ser lejlighedsvis, men som ikke fortjener en komplet artikel alene. Som sædvanlig anbefaler jeg stærkt, at du læser det første indlæg i serien før dette, så du har al den generelle baggrundsviden om låse.

LOG_MANAGER-låsen

LOG_MANAGER-låsen bruges til synkronisering under nogle operationer, der involverer transaktionsloggen, og der er én LOG_MANAGER-lås pr. database (da hver database har sin egen log-manager). Det kan kun erhverves i eksklusiv tilstand og kan være en flaskehals under vækst af transaktionslogfiler. Scenariet, hvor det vil blive tydeligt som et problem, er:

  • Logfilen har et lille autovækstsæt
  • Der er mange samtidige forbindelser, der genererer transaktionslogposter
  • Logfilen bliver ved med at vokse

Når logfilen løber tør for plads, skal den vokse. Den første tråd til at realisere mere logplads er påkrævet, anskaffer LOG_MANAGER-låsen i EX-tilstand og fortsætter med at vokse logfilen. Mange andre tråde fortsætter med at forsøge at generere logposter og komme ind i køen til LOG_MANAGER-låsen, så de kan udvide logfilen. Når den første tråd slipper låsen, får den næste den og indser, at stokken allerede er vokset, så taber den og fortsætter. Og så videre og så videre. I øvrigt kaldes dette flaskehalsmønster en låsekonvoj .

Du kan på en måde tænke på det som nøjagtig den samme flaskehals som med FGCB_ADD_REMOVE-låsen, jeg diskuterede tidligere i serien, men med logfilvækst i stedet for datafilvækst. Men med FGCB_ADD_REMOVE-låsen har instansen normalt øjeblikkelig filinitialisering aktiveret, så filvæksten er meget hurtig, men med LOG_MANAGER-låsen *skal* loggen nulinitialiseres, og den tid, der spildes i låsekøen er længere .

Løsningen på denne flaskehals har tre dele:

  1. Indstil logfilens autovækst korrekt, så loggen ikke vokser ofte
  2. Størrelse af loggen korrekt til arbejdsbyrden, så loggen burde slet ikke vokse
  3. Sørg for, at loggen ryddes korrekt, så loggen ikke behøver at vokse

Hvis disse alle er på plads, bør du ikke se LOG_MANAGER-låsen være en almindelig flaskehals, og jeg fortæller mere om dette i mit indlæg her.

ACCESS_METHODS_DATASET_PARENT-låsen

Når der tilgås enten en heap eller et indeks, er der internt et objekt kaldet henholdsvis en HeapDataSetSession eller IndexDataSetSession. Når en parallel scanning udføres, har trådene, der udfører selve scanningens arbejde, hver et "barn"-datasæt (en anden forekomst af de to objekter, jeg lige har beskrevet), og hoveddatasættet, som egentlig styrer scanningen, kaldes "forælderen".

Når en af ​​scanningsarbejdertrådene har opbrugt det sæt af rækker, den skal scanne, skal den få et nyt område ved at få adgang til det overordnede datasæt, hvilket betyder at anskaffe ACCESS_METHODS_DATASET_PARENT-låsen i eksklusiv tilstand. Selvom dette kan virke som en flaskehals, er det ikke rigtigt, og der er intet, du kan gøre for at forhindre, at trådene, der udfører en parallel scanning, lejlighedsvis viser en LATCH_EX ventetid på denne lås.

Spørgsmålet, du bør stille dig selv, er:skal denne forespørgsel udføre en parallel scanning i første omgang? Det er helt muligt, at der er sket noget, der tvinger forespørgselsplanen til at inkludere en parallel scanning, når det måske ikke er den mest effektive måde for forespørgslen at køre på. Eksempler på ting, der kan få en plan til at ændre sig til en parallel scanning omfatter:

  • Forældede statistikker
  • Et manglende eller udeladt ikke-klynget indeks
  • Ny kode, der tvinger en scanning på grund af en implicit konvertering – en datatype-uoverensstemmelse mellem en kolonne og en variabel/parameter, som udelukker brugen af ​​et ikke-klynget indeks
  • Ny kode, der tvinger en scanning, fordi aritmetik udføres på en tabelkolonne i stedet for en variabel/parameter, hvilket igen udelukker brugen af ​​et ikke-klynget indeks
  • Datavækst, og en scanning er virkelig den mest effektive plan

Eller det kan være denne forespørgsel kræver en scanning, i hvilket tilfælde LATCH_EX venter på, at ACCESS_METHODS_DATASET_PARENT kun er en del af dit miljø.

ACCESS_METHODS_HOBT_VIRTUAL_ROOT-låsen

Hver forekomst af denne lås beskytter en post i Storage Engine-metadataene for et b-træ, specifikt side-id'et for b-træets rodside (siden øverst i trekanten, som vi generelt opfatter som et indeks) . Jeg siger specifikt b-tree og ikke indeks , da et indeks kan have flere partitioner, som hver har et b-træ (i det væsentlige en del af det samlede indeks, men med nøglebegrænsninger for lav værdi og høj værdi).

Hver gang en tråd skal krydse et b-træ, skal den starte ved rodsiden og arbejde sig ned til bladniveauet. For at læse metadataene, der indeholder side-id'et for rodsiden, skal tråden anskaffe ACCESS_METHODS_HOBT_VIRTUAL_ROOT-låsen i SH-tilstand for at sikre, at side-id'et ikke er i gang med at ændre sig. Når en tråd skal ændre side-id'et for rodsiden, skal den hente låsen i EX-tilstand.

Hvorfor ville rodsiden af ​​et b-træ nogensinde ændre sig? Efterhånden som antallet af indeksposter på rodsiden vokser, vil den til sidst blive fyldt op, og der vil ske en sideopdeling. Når det sker, bliver den aktuelle rodside og siden den opdeles til et nyt niveau i b-træet, og der oprettes en helt ny rodside med to indeksposter i, der peger på den gamle rodside og siden den opdelt i. Det nye rodside-id skal indtastes i metadata, så låsen hentes i EX-tilstand. Dette vil ske et par gange hurtigt, da et indeks på en tom tabel begynder at blive udfyldt af indstik, men det er ikke noget, du vil se som et vedvarende problem med ydeevneflaskehals.

Oversigt

Som jeg er sikker på, du har forstået fra denne serie, indebærer forståelse af låse og låseflaskehalse at vide lidt mere om, hvad der foregår inde i Storage Engine end til generel analyse af ventestatistikker.

Jeg plejer at råde folk *ikke* til at starte fejlfinding af ydeevne ved at se på låsestatistikker (via sys.dm_os_latch_stats ), men i stedet for altid at starte med ventestatistikker (se mit indlæg her) og kun dykke ned i låse, hvis LATCH_EX eller LATCH_SH er en af ​​de øverste håndfuld ventetider på SQL Server-instansen.

Hvis du har spørgsmål om låse, er du velkommen til at skrive til mig.


  1. kan ikke modtage ud parameter fra oracle procedure udført af mybatis

  2. SQL Server Error 206:Operand type sammenstød

  3. Hvordan kører man SQLite-forespørgsel asynkront på baggrundstråd?

  4. Sådan pivoterer du dynamisk med dato som kolonne