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

SQL Server Lock Escalation

Introduktion

Relationelle databaser følger ACID-egenskaberne i, hvordan de implementerer transaktioner – Atomicitet, Konsistens, Isolation og Holdbarhed. Isolering er nødvendig for at sikre, at flere transaktioner ikke kan forårsage ændringer af data og efterlade de endelige resultater inkonsistente. For at garantere, at operationerne forbliver isolerede, anvender SQL Server låsemekanismer.

Låsetilstande og hierarki

SQL Servers mekanisme til samtidighedskontrol er involveret. For at optimere ydeevnen med hensyn til låseventer, deadlocks og lignende, skal du træffe en beslutning baseret på det specifikke scenarie.

I SQL Server kan låse holdes på forskellige måder og på flere niveauer af granularitet. Låsetilstande er de specifikke måder at gøre det på, og deres niveauer er låshierarki.

Figur 1 viser de tilgængelige låsetilstande i SQL Server for standardtransaktionsisolationsniveauet (READ COMMITTED):

Oversigt over låseeskalering

SQL Server kan låse ressourcer på flere niveauer. Det afhænger af de mest effektive handlinger i henhold til arten af ​​arbejdsbyrden. Tabel 1 viser de ressourcer, der kan låses.

  • Låse på et mere granulært niveau (f.eks. rækkeniveaulåse) tillader højere samtidighed og mindre blokering.
  • Låse på et højere niveau (f.eks. Table Level Lock) reducerer samtidighed. De kan forårsage mere blokering, afhængigt af hvor længe den faktiske erklæring varer.

SQL Server vælger det nødvendige låseniveau i henhold til interne målinger.

En låseskalering sker, når en lås konverteres fra et finere granularitetsniveau til et grovere niveau.

F.eks. konvertere en rækkelås til en tabellås (se tabel 1).

Ressource Beskrivelse
RID Række-id'et, der bruges til at låse en enkelt række i en heap.
NØGLE Rækkelåsen i et indeks, der bruges til at beskytte nøgleområder i serialiserbare transaktioner.
SIDE 8-kilobyte (KB) siden i en database, såsom data eller indekssider.
UDVIDELSE Den sammenhængende gruppe på otte sider, såsom data eller indekssider.
HoBT Dyngen eller B-træet. Låsen beskytter et B-træ (indeks) eller heap-datasiderne i en tabel, der ikke har et klynget indeks.
TABEL Hele tabellen, inklusive alle data og indekser.
FIL Databasefilen.
APPLIKATION Den applikationsspecificerede ressource.
METADATA Metadatalåse.
ALLOCATION_UNIT Tildelingsenheden.
DATABASE Hele databasen.

Begrundelsen for eskalering af låse

Låse i SQL Server kan være ret dyre. For hver lås, som Lock Manager anskaffer, skal SQL Server reservere hukommelse – 64 bytes eller 128 bytes. Beløbet afhænger af, om vi har at gøre med henholdsvis et 32-bit eller 64-bit system.

Efterhånden som antallet af rækkelåse på en tabel stiger, skal SQL Server erhverve mere og mere hukommelse. Derfor sulter andre processer, ude af hukommelse.

Det giver mening at konvertere rækkelåse og sidelåse til en enkelt tabel (objekt) niveaulås. Det sker, når antallet af låse for det pågældende bord overstiger 5000.

Kompromiset sker, når hele bordet ikke længere er tilgængeligt for andre sessioner i transaktionsprocessen.

Demonstrering af låseeskalering

Vi kan demonstrere låseeskalering ved hjælp af koden i liste 1.

Lad os først beskrive bordet lidt. Produktion.ProdukterI er et relativt lille bord med omkring 7777 rækker. Bygningselementerne er det samme sæt af 77 rækker duplikeret 101 gange. Koden i liste 1 består af tre versioner af den samme opdateringserklæring, som hver er indeholdt i en transaktion.

-- Listing 1: Demonstrating Lock Escalation

-- Update very few rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK 

For mere klarhed vil vi nedbryde indholdet af liste 1.

Før det, lad os observere Listing 2 - en forespørgsel til at vise låsene i TSQLV4-databasen.

Vores første handling er at udføre liste 1a. Derefter bruger vi liste 2 til at undersøge, hvordan Lock Manager udfører låsning i scenariet. Vi udfører liste 1a uden at udstede rollback-erklæringen. På denne måde bevarer vi låsene længe nok, så forespørgslen i liste 2 kan fange dem.

-- Listing 1a: Demonstrating Lock Escalation
-- Update very few rows

BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Listing 2: Displaying Locks Held in Database TSQLV4

USE TSQLV4
GO
SELECT 
resource_type
, DB_NAME (resource_database_id) database_name
--, OBJECT_NAME(resource_associated_entity_id) resource_name
, request_mode
, request_type
, request_status
, request_reference_count
, request_session_id
, resource_associated_entity_id
, OBJECT_NAME(resource_associated_entity_id) [object_name] --small obj ids
, getuser.login_name
FROM sys.dm_tran_locks
CROSS APPLY dmv.dbo.getuser(request_session_id) as getuser
WHERE DB_NAME (resource_database_id)='TSQLV4';

Når vi kører forespørgslen i liste 1a og derefter tjekker låsene ved hjælp af forespørgslen i liste 2, returnerer SQL Server resultatet vist i figur 2.

404 rækker i tabellen har unitprice='18,00' . Låseadministratoren låser disse rækker sammen med de andre låse på et hvilket som helst niveau. Det bringer rækkeantallet i figur 2 til 467.

-- Listing 1b: Demonstrating Lock Escalation
-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

Vi observerer lignende adfærd, når vi udfører forespørgslen i liste 1b. Denne gang har vi at gøre med 4406 rækker. Det afspejler antallet af rækker i tabellen Produktion. ProduktI har enhedspris>18,00.

-- Listing 1c: Demonstrating Lock Escalation
-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK

Når vi går videre og udfører koden i liste 1c, ser vi en anden adfærd (se figur 4).

Liste 1c forsøger at opdatere alle 7777 rækker i tabellen Production.ProductI. SQL Server bestemmer, at låsning af så mange rækker ikke længere er effektiv for at garantere isolation. I stedet er hele bordet låst.

Mere om låseeskalering

Tabelllåsen indebærer, at ingen anden session kan ændre sine rækker i transaktionsvarigheden, hvilket kan ske, selv når en blokeringssession ikke manipulerer alle rækker i tabellen.

Det er også værd at nævne, at andre faktorer kan påvirke, hvordan låse anskaffes og eskaleres i SQL Server. Det er de konfigurerede isolationsniveauer, indekserings- og sporingsflag.

Sporingsflag T1211 og T1224 kan anvendes for at deaktivere Lock Escalation helt. Lock Escalation kan også blive deaktiveret og aktiveret for en specifik tabel med følgende kode:

-- Listing 5: Disable and Enable Lock Escalation

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=DISABLE);

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=TABLE);

Man ønsker måske at gøre det for at reducere blokering forbundet med låsning af hele bordet. På grund af indvirkningen på hukommelsen bør det overvejes som en midlertidig foranstaltning.

Konklusion

SQL Server bruger Lock Escalation til at kontrollere virkningen af ​​mere granulær låsning på serverressourcer. For at vise måden for disse låses forekomster – rækkelåse, sidelåse, objektlåse osv. – forespørg den dynamiske administrationsvisning sys.dm_tran_locks. Det giver en masse information om låsning, udover Lock Escalation.

Selvom det er muligt at manipulere låseadministratorens adfærd, er det vigtigt at gøre det med stor omhu. Det er også afgørende at kende den præcise præstationseffekt af enhver indsats rettet mod at foretage sådanne ændringer.

Referencer

  1. Korotkevitch, D., 2016. Pro SQL Server Internals. Florida:Dmitri Korotkevitch
  2. Lås scenarier ved hjælp af Sys.dm_tran_locks
  3. Vejledning til transaktionslåsning og rækkeversionering


  1. Sådan modelleres for nem databasevedligeholdelse

  2. Sådan forhindrer du forbindelsestimeout for store MySQL-importer

  3. Webinar:Banking on Postgres – Finansielle ansøgningsovervejelser [Opfølgning]

  4. Sådan fungerer PI() i MariaDB