Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Concept principal du verrouillage SQL Server

Dans cet article, nous discuterons du mécanisme de verrouillage de SQL Server et de la manière de surveiller le verrouillage de SQL Server avec les vues de gestion dynamique standard de SQL Server. Avant de commencer à expliquer l'architecture de verrouillage de SQL Server, prenons un moment pour décrire ce qu'est la base de données ACID (atomicité, cohérence, isolation et durabilité). La base de données ACID peut être expliquée comme la théorie des bases de données. Si une base de données est appelée base de données relationnelle, elle doit répondre aux exigences d'atomicité, de cohérence, d'isolement et de durabilité. Nous allons maintenant expliquer brièvement ces exigences.

Anomicité :Il reflète le principe d'indivisibilité que nous décrivons comme la principale caractéristique du processus transactionnel. Un bloc de transaction ne peut pas être laissé sans surveillance. La moitié du bloc de transaction restant provoque une incohérence des données. Soit toute la transaction est exécutée, soit la transaction revient au début. Autrement dit, toutes les modifications apportées par la transaction sont annulées et renvoyées à leur état précédent.

Cohérence :Il existe une règle qui définit la sous-structure de la règle de non-divisibilité. Les données de transaction doivent assurer la cohérence. Autrement dit, si l'opération de mise à jour est effectuée dans une transaction, soit toutes les transactions restantes doivent être effectuées, soit l'opération de mise à jour doit être annulée. Ces données sont très importantes en termes de cohérence.

Isolement :Il s'agit d'un paquet de requête pour chaque base de données de transactions. Les modifications apportées par un paquet de requête doivent être visibles pour une autre transaction avant qu'elle ne soit terminée. Chaque transaction doit être traitée séparément. Toutes les transactions doivent être visibles par une autre transaction après leur exécution.

Durabilité : Les transactions peuvent effectuer des opérations complexes avec des données. Afin de sécuriser toutes ces transactions, elles doivent être résistantes à une erreur de transaction. Les problèmes système pouvant survenir dans SQL Server doivent être préparés et résistants aux pannes de courant, au système d'exploitation ou à d'autres erreurs induites par le logiciel.

Transaction : La transaction est la plus petite pile du processus qui ne peut pas être divisée en plus petits morceaux. En outre, certains groupes de processus de transaction peuvent être exécutés de manière séquentielle, mais comme nous l'avons expliqué dans le principe d'atomicité, si même l'une des transactions échoue, tous les blocs de transaction échoueront.

Verrouiller : Le verrouillage est un mécanisme permettant d'assurer la cohérence des données. SQL Server verrouille les objets au démarrage de la transaction. Lorsque la transaction est terminée, SQL Server libère l'objet verrouillé. Ce mode de verrouillage peut être modifié en fonction du type de processus SQL Server et du niveau d'isolement. Ces modes de verrouillage sont :

Verrouiller la hiérarchie : SQL Server possède une hiérarchie de verrouillage qui acquiert des objets de verrouillage dans cette hiérarchie. Une base de données est située en haut de la hiérarchie et la ligne est située en bas. L'image ci-dessous illustre la hiérarchie des verrous de SQL Server.

Verrous partagés (S) : Ce type de verrouillage se produit lorsque l'objet doit être lu. Ce type de verrou ne pose pas beaucoup de problèmes.

Verrous exclusifs (X) : Lorsque ce type de verrouillage se produit, il se produit pour empêcher d'autres transactions de modifier ou d'accéder à un objet verrouillé.

Mettre à jour les verrous (U) : Ce type de verrou est similaire au verrou exclusif mais il présente quelques différences. On peut diviser l'opération de mise à jour en différentes phases :phase de lecture et phase d'écriture. Lors de la phase de lecture, SQL Server ne souhaite pas que d'autres transactions aient accès à cet objet à modifier. Pour cette raison, SQL Server utilise le verrou de mise à jour.

Verrouillages d'intention : Le verrou d'intention se produit lorsque SQL Server souhaite acquérir le verrou partagé (S) ou le verrou exclusif (X) sur certaines des ressources inférieures dans la hiérarchie des verrous. En pratique, lorsque SQL Server acquiert un verrou sur une page ou une ligne, le verrou d'intention est requis dans la table.

Après toutes ces brèves explications, nous allons essayer de trouver une réponse à comment identifier les serrures. SQL Server propose de nombreuses vues de gestion dynamiques pour accéder aux métriques. Pour identifier les verrous SQL Server, nous pouvons utiliser les sys.dm_tran_locks voir. Dans cette vue, nous pouvons trouver de nombreuses informations sur les ressources du gestionnaire de verrouillage actuellement actives.

Dans le premier exemple, nous allons créer une table de démonstration qui n'inclut aucun index et essayer de mettre à jour cette table de démonstration.

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

Maintenant, nous allons vérifier la vue sys.dm_tran_lock.

select * from sys.dm_tran_locks  WHERE request_session_id=74

Cette vue renvoie de nombreuses informations sur les ressources de verrouillage actives. Mais il n'est pas possible de comprendre certaines des données dans cette vue. Pour cette raison, nous devons rejoindre les sys.dm_tran_locks vue vers d'autres vues.

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

Dans l'image ci-dessus, vous pouvez voir les ressources verrouillées. SQL Server acquiert le verrou exclusif dans cette ligne. (RID :un identifiant de ligne utilisé pour verrouiller une seule ligne dans un tas) En même temps, SQL Server acquiert le verrou exclusif d'intention dans la page et le TestBlock table. Cela signifie qu'aucun autre processus ne peut lire cette ressource tant que SQL Server n'a pas relâché les verrous. Il s'agit du mécanisme de verrouillage de base dans SQL Server.

Maintenant, nous allons remplir des données synthétiques sur notre table de test.

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

Dans la requête ci-dessus, SQL Server acquiert le verrou exclusif sur chaque ligne. Maintenant, nous allons exécuter une autre requête.

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

Dans la requête ci-dessus, SQL Server crée le verrou exclusif sur la table, car SQL Server essaie d'acquérir un grand nombre de verrous RID pour ces lignes qui seront mises à jour. Ce cas entraîne une consommation importante de ressources dans le moteur de base de données. Par conséquent, SQL Server déplace automatiquement ce verrou exclusif vers un objet de niveau supérieur qui se trouve dans la hiérarchie des verrous. Nous définissons ce mécanisme comme Lock Escalation. L'escalade de verrouillage peut être modifiée au niveau de la table.

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

Je voudrais ajouter quelques notes sur l'escalade de verrouillage. Si vous avez une table partitionnée, nous pouvons définir l'escalade au niveau de la partition.

Dans cette étape, nous allons exécuter une requête qui crée un verrou dans la table AdventureWorks HumanResources. Cette table contient des index clusterisés et non clusterisés.

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

Comme vous pouvez le voir dans le volet de résultats ci-dessous, notre transaction acquiert des verrous exclusifs dans la clé d'index de cluster PK_Department_DepartmentID et acquiert également des verrous exclusifs dans la clé d'index non cluster AK_Department_Name. Maintenant, nous pouvons poser cette question "Pourquoi SQL Server verrouille un index non cluster ?"

Le Nom la colonne est indexée dans l'index non clusterisé AK_Department_Name et nous essayons de changer le Name colonne. Dans ce cas, SQL Server doit modifier tous les index non clusterisés sur cette colonne. Le niveau feuille de l'index non clusterisé inclut toutes les valeurs KEY triées.

Conclusion

Dans cet article, nous avons mentionné les grandes lignes du mécanisme de verrouillage de SQL Server et envisagé l'utilisation de sys.dm_tran_locks. La vue sys.dm_tran_locks renvoie de nombreuses informations sur les ressources de verrouillage actuellement actives. Si vous effectuez une recherche sur Google, vous trouverez de nombreux exemples de requêtes concernant cette vue.

Références

Guide de verrouillage des transactions SQL Server et de gestion des versions de ligne

SQL Server, Verrouille l'objet