I det här inlägget kommer vi att diskutera SQL Server-låsmekanismen och hur man övervakar SQL Server-låsning med SQL Server-standard dynamiska hanteringsvyer. Innan vi börjar förklara SQL Server-låsarkitektur, låt oss ta en stund för att beskriva vad databasen ACID (Atomicity, Consistency, Isolation och Durability) är. ACID-databasen kan förklaras som databasteori. Om en databas kallas relationsdatabas måste den uppfylla kraven på atomicitet, konsistens, isolering och hållbarhet. Nu kommer vi att förklara dessa krav kort.
Atomicitet :Det återspeglar principen om odelbarhet som vi beskriver som huvuddraget i transaktionsprocessen. Ett transaktionsblock kan inte lämnas obevakat. Hälften av det återstående transaktionsblocket orsakar datainkonsekvens. Antingen utförs hela transaktionen eller så återgår transaktionen till början. Det vill säga alla ändringar som görs av transaktionen ångras och återställs till sitt tidigare tillstånd.
Konsistens :Det finns en regel som anger understrukturen för icke-delbarhetsregeln. Transaktionsdata måste ge konsekvens. Det vill säga, om uppdateringsoperationen utförs i en transaktion måste antingen alla återstående transaktioner utföras eller så måste uppdateringsoperationen avbrytas. Dessa data är mycket viktiga när det gäller konsekvens.
Isolering :Detta är ett förfrågningspaket för varje transaktionsdatabas. Ändringar som görs av ett förfrågningspaket måste vara synliga för en annan transaktion innan den är klar. Varje transaktion måste behandlas separat. Alla transaktioner måste vara synliga för en annan transaktion efter att de inträffat.
Hållbarhet: Transaktioner kan utföra komplexa operationer med data. För att säkra alla dessa transaktioner måste de vara resistenta mot ett transaktionsfel. Systemproblem som kan uppstå i SQL Server bör vara förberedda och motståndskraftiga mot strömavbrott, operativsystem eller andra programvaruinducerade fel.
Transaktion: Transaktion är den minsta stapeln i processen som inte kan delas upp i mindre bitar. En viss grupp av transaktionsprocesser kan också utföras sekventiellt, men som vi förklarade i Atomicity-principen om ens en av transaktionerna misslyckas, kommer alla transaktionsblock att misslyckas.
Lås: Lås är en mekanism för att säkerställa datakonsistens. SQL Server låser objekt när transaktionen startar. När transaktionen är klar släpper SQL Server det låsta objektet. Detta låsläge kan ändras beroende på SQL Server-processtyp och isoleringsnivå. Dessa låslägen är:
Låshierarki: SQL Server har en låshierarki som hämtar låsobjekt i denna hierarki. En databas finns längst upp i hierarkin och raden finns längst ner. Bilden nedan illustrerar låshierarkin för SQL Server.
Delade (S) lås: Denna låstyp uppstår när objektet behöver läsas. Denna låstyp orsakar inte mycket problem.
Exklusiva (X) lås: När den här låstypen inträffar inträffar den för att förhindra andra transaktioner för att ändra eller komma åt ett låst objekt.
Uppdatera (U) lås: Denna låstyp liknar det exklusiva låset men det har vissa skillnader. Vi kan dela upp uppdateringsoperationen i olika faser:läsfas och skrivfas. Under läsfasen vill SQL Server inte att andra transaktioner ska ha tillgång till detta objekt som ska ändras. Av denna anledning använder SQL Server uppdateringslåset.
Avsiktslås: Avsiktslåset inträffar när SQL Server vill skaffa det delade (S)-låset eller det exklusiva (X)-låset på några av resurserna lägre i låshierarkin. I praktiken, när SQL Server skaffar ett lås på en sida eller rad, krävs avsiktslåset i tabellen.
Efter alla dessa korta förklaringar kommer vi att försöka hitta ett svar på hur man identifierar lås. SQL Server erbjuder många dynamiska hanteringsvyer för att komma åt mätvärden. För att identifiera SQL Server-lås kan vi använda sys.dm_tran_locks se. I den här vyn kan vi hitta mycket information om för närvarande aktiva låshanterares resurser.
I det första exemplet kommer vi att skapa en demotabell som inte innehåller några index och försöka uppdatera denna demotabell.
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 kommer vi att kontrollera vyn sys.dm_tran_lock.
select * from sys.dm_tran_locks WHERE request_session_id=74
Den här vyn returnerar mycket information om aktiva låsresurser. Men det är inte möjligt att förstå en del av uppgifterna i denna vy. Av denna anledning måste vi gå med i sys.dm_tran_locks se till andra vyer.
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 bilden ovan kan du se de låsta resurserna. SQL Server skaffar det exklusiva låset i den raden. (RID :En radidentifierare som används för att låsa en enskild rad i en hög) Samtidigt skaffar SQL Server det exklusiva avsiktslåset på sidan och TestBlock tabell. Det betyder att någon annan process inte kan läsa den här resursen förrän SQL Server släpper låsen. Detta är den grundläggande låsmekanismen i SQL Server.
Nu kommer vi att fylla i några syntetiska data i vår testtabell.
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 ovanstående fråga får SQL Server det exklusiva låset på varje enskild rad. Nu kör vi en annan fråga.
BEGIN TRAN UPDATE TestBlock set Nm ='New_Value' where Id<7000
I ovanstående fråga skapar SQL Server det exklusiva låset på bordet, eftersom SQL Server försöker få många RID-lås för dessa rader som kommer att uppdateras. Detta fall orsakar mycket resursförbrukning i databasmotorn. Därför flyttar SQL Server automatiskt detta exklusiva lås till ett objekt på högre nivå som finns i låshierarkin. Vi definierar denna mekanism som Lock Escalation. Lock Eskalering kan ändras på tabellnivå.
ALTER TABLE XX_TableName SET ( LOCK_ESCALATION = AUTO -- or TABLE or DISABLE ) GO
Jag skulle vilja lägga till några anteckningar om låseskalering. Om du har en partitionerad tabell kan vi ställa in eskaleringen till partitionsnivån.
I det här steget kommer vi att köra en fråga som skapar ett lås i tabellen AdventureWorks HumanResources. Den här tabellen har klustrade och icke-klustrade index.
BEGIN TRAN UPDATE [HumanResources].[Department] SET Name='NewName' where DepartmentID=1
Som du kan se i resultatrutan nedan, förvärvar vår transaktion exklusiva lås i klusterindexnyckeln PK_Department_DepartmentID och förvärvar även exklusiva lås i den icke-klustrade indexnyckeln AK_Department_Name. Nu kan vi ställa den här frågan "Varför låser SQL Server ett icke-klustrat index?"
Namnet kolumnen indexeras i det icke-klustrade indexet AK_Department_Name och vi försöker ändra namnet kolumn. I det här fallet måste SQL Server ändra alla icke-klustrade index i den kolumnen. Den icke-klustrade indexbladsnivån inkluderar varje KEY-värde som sorterats bort.
Slutsatser
I den här artikeln nämnde vi huvudlinjerna i SQL Server-låsmekanismen och övervägde användningen av sys.dm_tran_locks. Vyn sys.dm_tran_locks returnerar mycket information om för närvarande aktiva låsresurser. Om du googlar kan du hitta många exempel på frågor om denna vy.
Referenser
SQL Server Transaction Locking och Row Versioning Guide
SQL Server, låser objekt