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

Hovedkonceptet for SQL Server-låsning

I dette indlæg vil vi diskutere SQL Server-låsemekanismen, og hvordan man overvåger SQL Server-låsning med SQL Server-standard dynamiske administrationsvisninger. Før vi begynder at forklare SQL Server-låsearkitektur, lad os tage et øjeblik på at beskrive, hvad ACID-databasen (Atomicitet, Konsistens, Isolation og Durability) er. ACID-databasen kan forklares som databaseteori. Hvis en database kaldes relationel database, skal den opfylde kravene til atomicitet, konsistens, isolation og holdbarhed. Nu vil vi kort forklare disse krav.

Atomicitet :Det afspejler princippet om udelelighed, som vi beskriver som hovedtræk ved transaktionsprocessen. En transaktionsblokering kan ikke efterlades uden opsyn. Halvdelen af ​​den resterende transaktionsblok forårsager datainkonsistens. Enten udføres hele transaktionen, eller også vender transaktionen tilbage til begyndelsen. Det vil sige, at alle ændringer foretaget af transaktionen fortrydes og returneres til deres tidligere tilstand.

Konsistens :Der er en regel, der sætter understrukturen af ​​ikke-delelighedsreglen. Transaktionsdata skal give konsistens. Det vil sige, at hvis opdateringsoperationen udføres i en transaktion, skal enten alle resterende transaktioner udføres, eller opdateringsoperationen skal annulleres. Disse data er meget vigtige med hensyn til konsistens.

Isolation :Dette er en anmodningspakke for hver transaktionsdatabase. Ændringer foretaget af en anmodningspakke skal være synlige for en anden transaktion, før den er fuldført. Hver transaktion skal behandles separat. Alle transaktioner skal være synlige for en anden transaktion, efter de har fundet sted.

Holdbarhed: Transaktioner kan udføre komplekse operationer med data. For at sikre alle disse transaktioner skal de være modstandsdygtige over for en transaktionsfejl. Systemproblemer, der kan opstå i SQL Server, skal være forberedt og modstandsdygtige over for strømsvigt, operativsystem eller andre software-inducerede fejl.

Transaktion: Transaktion er den mindste stak i processen, som ikke kan opdeles i mindre stykker. En eller anden gruppe af transaktionsprocesser kan også udføres sekventielt, men som vi forklarede i Atomicity-princippet, hvis selv en af ​​transaktionerne mislykkes, vil alle transaktionsblokke mislykkes.

Lås: Lås er en mekanisme til at sikre datakonsistens. SQL Server låser objekter, når transaktionen starter. Når transaktionen er gennemført, frigiver SQL Server det låste objekt. Denne låsetilstand kan ændres i henhold til SQL Server-procestypen og isolationsniveauet. Disse låsetilstande er:

Lås hierarki: SQL Server har et låsehierarki, som henter låseobjekter i dette hierarki. En database er placeret øverst i hierarkiet, og rækken er placeret nederst. Billedet nedenfor illustrerer låsehierarkiet i SQL Server.

Delte (S) låse: Denne låsetype opstår, når objektet skal læses. Denne låsetype forårsager ikke mange problemer.

Eksklusive (X) låse: Når denne låsetype opstår, sker den for at forhindre andre transaktioner i at ændre eller få adgang til et låst objekt.

Opdater (U) låse: Denne låsetype ligner den eksklusive lås, men den har nogle forskelle. Vi kan opdele opdateringsoperationen i forskellige faser:læsefase og skrivefase. Under læsefasen ønsker SQL Server ikke, at andre transaktioner skal have adgang til dette objekt, der skal ændres. Af denne grund bruger SQL Server opdateringslåsen.

Intent Locks: Hensigtslåsen opstår, når SQL Server ønsker at erhverve den delte (S) lås eller eksklusive (X) lås på nogle af ressourcerne lavere i låsehierarkiet. I praksis, når SQL Server anskaffer en lås på en side eller række, er hensigtslåsen påkrævet i tabellen.

Efter alle disse korte forklaringer vil vi forsøge at finde et svar på, hvordan man identificerer låse. SQL Server tilbyder en masse dynamiske administrationsvisninger for at få adgang til metrics. For at identificere SQL Server-låse kan vi bruge sys.dm_tran_locks udsigt. I denne visning kan vi finde en masse information om aktuelt aktive låseadministratorressourcer.

I det første eksempel vil vi oprette en demo-tabel, som ikke indeholder nogen indekser, og forsøge at opdatere denne demo-tabel.

CREATE TABLE TestBlock
(Id INT ,
Nm VARCHAR(100))

INSERT INTO TestBlock
values(1,'CodingSight')
In this step, we will create an open transaction and analyze the locked resources.
BEGIN TRAN
UPDATE TestBlock SET   Nm='NewValue_CodingSight' where Id=1
select @@SPID

Nu vil vi kontrollere sys.dm_tran_lock-visningen.

select * from sys.dm_tran_locks  WHERE request_session_id=74

Denne visning returnerer en masse information om aktive låseressourcer. Men det er ikke muligt at forstå nogle af dataene i denne visning. Af denne grund er vi nødt til at tilslutte os sys.dm_tran_locks udsigt til andre synspunkter.

SELECT dm_tran_locks.request_session_id,
       dm_tran_locks.resource_database_id,
       DB_NAME(dm_tran_locks.resource_database_id) AS dbname,
       CASE
           WHEN resource_type = 'OBJECT'
               THEN OBJECT_NAME(dm_tran_locks.resource_associated_entity_id)
           ELSE OBJECT_NAME(partitions.OBJECT_ID)
       END AS ObjectName,
       partitions.index_id,
       indexes.name AS index_name,
       dm_tran_locks.resource_type,
       dm_tran_locks.resource_description,
       dm_tran_locks.resource_associated_entity_id,
       dm_tran_locks.request_mode,
       dm_tran_locks.request_status
FROM sys.dm_tran_locks
LEFT JOIN sys.partitions ON partitions.hobt_id = dm_tran_locks.resource_associated_entity_id
LEFT JOIN sys.indexes ON indexes.OBJECT_ID = partitions.OBJECT_ID AND indexes.index_id = partitions.index_id
WHERE resource_associated_entity_id > 0
  AND resource_database_id = DB_ID()
 and request_session_id=74
ORDER BY request_session_id, resource_associated_entity_id

I ovenstående billede kan du se de låste ressourcer. SQL Server erhverver den eksklusive lås i den række. (RID :En række-id, der bruges til at låse en enkelt række i en heap) Samtidig anskaffer SQL Server den hensigtsmæssige eksklusive lås på siden og TestBlock bord. Det betyder, at enhver anden proces ikke kan læse denne ressource, før SQL Serveren frigiver låsene. Dette er den grundlæggende låsemekanisme i SQL Server.

Nu vil vi udfylde nogle syntetiske data på vores testtabel.

TRUNCATE TABLE 	  TestBlock
DECLARE @K AS INT=0
WHILE @K <8000
BEGIN
INSERT TestBlock VALUES(@K, CAST(@K AS varchar(10)) + ' Value' )
SET @[email protected]+1
 END
After completing this step, we will run two queries and check the sys.dm_tran_locks view.
BEGIN TRAN
 UPDATE TestBlock  set Nm ='New_Value' where Id<5000

I ovenstående forespørgsel erhverver SQL Server den eksklusive lås på hver enkelt række. Nu kører vi endnu en forespørgsel.

BEGIN TRAN
 UPDATE TestBlock  set Nm ='New_Value' where Id<7000

I ovenstående forespørgsel opretter SQL Server den eksklusive lås på bordet, fordi SQL Server forsøger at erhverve en masse RID-låse til disse rækker, som vil blive opdateret. Denne sag forårsager meget ressourceforbrug i databasemotoren. Derfor flytter SQL Server automatisk denne eksklusive lås til et op-niveau objekt, som er i låsehierarkiet. Vi definerer denne mekanisme som Lock Escalation. Låseskalering kan ændres på tabelniveau.

ALTER TABLE XX_TableName
SET
(
	LOCK_ESCALATION = AUTO -- or TABLE or DISABLE
)
GO

Jeg vil gerne tilføje nogle bemærkninger om låseeskalering. Hvis du har en partitioneret tabel, så kan vi indstille eskaleringen til partitionsniveauet.

I dette trin vil vi udføre en forespørgsel, som skaber en lås i AdventureWorks HumanResources-tabellen. Denne tabel har klyngede og ikke-klyngede indekser.

BEGIN TRAN	
UPDATE 	  [HumanResources].[Department] SET Name='NewName' where DepartmentID=1

Som du kan se i nedenstående resultatrude, erhverver vores transaktion eksklusive låse i PK_Department_DepartmentID klyngeindeksnøglen og erhverver også eksklusive låse i den ikke-klyngede indeksnøgle AK_Department_Name. Nu kan vi stille dette spørgsmål "Hvorfor låser SQL Server et ikke-klynget indeks?"

navnet kolonne er indekseret i det ikke-klyngede AK_Department_Name-indeks, og vi forsøger at ændre navnet kolonne. I dette tilfælde skal SQL Server ændre alle ikke-klyngede indekser på den kolonne. Det ikke-klyngede indeksbladsniveau inkluderer hver KEY-værdi, der er sorteret fra.

Konklusioner

I denne artikel nævnte vi hovedlinjerne i SQL Server-låsemekanismen og overvejede brugen af ​​sys.dm_tran_locks. Visningen sys.dm_tran_locks returnerer en masse information om aktuelt aktive låseressourcer. Hvis du googler, kan du finde en masse eksempelforespørgsler om denne visning.

Referencer

SQL Server-transaktionslåsning og rækkeversionsvejledning

SQL Server, låser objekt


  1. Oracle PL/SQL:Eksporter data fra en tabel til CSV

  2. DBCC_OBJECT_METADATA-låsen

  3. Tvinge en forespørgselstimeout i SQL Server

  4. 4 tabelformede outputtilstande i SQLite