Décrypter la clé et la page WaitResource dans les blocages et les verrous

Si vous utilisez un rapport de processus bloqué ou collectez des graphiques d'interblocage fournis par SQL Server de temps en temps, vous rencontrerez ces choses:



waitresource = "PAGE: 6: 3: 70133"



waitresource = "CLÉ: 6: 72057594041991168 (ce52f92a058c)"


Parfois, il y aura plus d'informations dans ce XML géant que vous apprenez (les graphiques bloqués contiennent une liste de ressources qui vous aide à trouver les noms d'objet et d'index), mais pas toujours.



Ce texte vous aidera à les déchiffrer.



Toutes les informations qui sont ici se trouvent sur Internet à divers endroits, elles sont simplement trÚs diffusées! Je veux tout mettre ensemble - de DBCC PAGE à hobt_id et aux fonctions non documentées %% physloc %% et %% lockres %%.



Parlons d'abord de l'attente des verrous PAGE, puis passons aux verrous KEY.



1) waitresource = "PAGE: 6: 3: 70133" = Database_Id: FileId: PageNumber



Si votre requĂȘte attend un verrou PAGE, SQL Server vous donnera l'URL de cette page.



En décomposant "PAGE: 6: 3: 70133", nous obtenons:



  • id_base_de_donnĂ©es = 6
  • data_file_id = 3
  • page_numer = 70133




1.1) DĂ©crypter database_id



Trouvons le nom de la base de donnĂ©es Ă  l'aide de la requĂȘte:

SELECT 
    name 
FROM sys.databases 
WHERE database_id=6;
GO


Il s'agit de la base de données publique WideWorldImporters sur mon serveur SQL.



1.2) Recherche du nom du fichier de données - si cela vous intéresse



Nous allons utiliser data_file_id Ă  l'Ă©tape suivante pour trouver le nom de la table. Vous pouvez simplement passer Ă  l'Ă©tape suivante, mais si le nom du fichier vous intĂ©resse, vous pouvez le trouver en exĂ©cutant une requĂȘte dans le contexte du DB trouvĂ©, en remplaçant data_file_id dans cette requĂȘte:

USE WideWorldImporters;
GO
SELECT 
    name, 
    physical_name
FROM sys.database_files
WHERE file_id = 3;
GO


Dans la base de donnĂ©es WideWorldImporters, il s'agit d'un fichier nommĂ© WWI_UserData et il a Ă©tĂ© restaurĂ© dans mon C: \ MSSQL \ DATA \ WideWorldImporters_UserData.ndf. (Oups, vous m'avez surpris en train de mettre des fichiers sur le disque systĂšme! Non! C'Ă©tait gĂȘnant).



1.3) Obtenez le nom de l'objet Ă  partir de la PAGE DBCC



Nous savons maintenant que la page # 70133 du fichier de données 3 appartient à la base de données WorldWideImporters. Nous pouvons regarder le contenu de cette page en utilisant la PAGE DBCC non documentée et l'indicateur de trace 3604.

Remarque: Je préfÚre utiliser la PAGE DBCC sur une sauvegarde restaurée à partir d'une sauvegarde quelque part sur un serveur différent, car c'est une chose non documentée. Dans certains cas, cela peut conduire à la création d'un dump ( commentaire du traducteur - le lien, malheureusement, ne mÚne nulle part, mais à en juger par l'url, on parle d'index filtrés ).

/* This trace flag makes DBCC PAGE output go to our Messages tab
instead of the SQL Server Error Log file */
DBCC TRACEON (3604);
GO
/* DBCC PAGE (DatabaseName, FileNumber, PageNumber, DumpStyle)*/
DBCC PAGE ('WideWorldImporters',3,70133,2);
GO


En faisant défiler les résultats, vous pouvez trouver object_id et index_id.



Presque prĂȘt! Vous pouvez maintenant trouver les noms de table et d'index Ă  l'aide de la requĂȘte:

USE WideWorldImporters;
GO
SELECT 
    sc.name as schema_name, 
    so.name as object_name, 
    si.name as index_name
FROM sys.objects as so 
JOIN sys.indexes as si on 
    so.object_id=si.object_id
JOIN sys.schemas AS sc on 
    so.schema_id=sc.schema_id
WHERE 
    so.object_id = 94623380
    and si.index_id = 1;
GO


Et maintenant, nous voyons que l'attente sur le verrou Ă©tait sur l'index PK_Sales_OrderLines de la table Sales.OrderLines.



Remarque: dans SQL Server 2014 et versions ultĂ©rieures, le nom de l'objet peut Ă©galement ĂȘtre trouvĂ© Ă  l'aide du DMO non documentĂ© sys.dm_db_database_page_allocations. Mais vous devez interroger chaque page de la base de donnĂ©es, ce qui n'a pas l'air trĂšs cool pour les grandes bases de donnĂ©es, j'ai donc utilisĂ© DBCC PAGE.



1.4) Pouvez-vous voir les données sur la page qui a été bloquée?



Nuuu, oui. Mais ... ĂȘtes-vous sĂ»r que vous en avez vraiment besoin?

C'est lent mĂȘme sur de petites tables. Mais c'est plutĂŽt cool, donc puisque vous avez lu jusqu'ici ... parlons de %% physloc %%!



%% physloc %% est un morceau de magie non documenté qui renvoie un identifiant physique pour chaque entrée. Vous pouvez utiliser %% physloc %% avec sys.fn_PhysLocFormatter dans SQL Server 2008 et versions ultérieures .



Maintenant que nous savons que nous voulions bloquer la page dans Sales.OrderLines, nous pouvons afficher toutes les donnĂ©es de cette table, qui sont stockĂ©es dans le fichier de donnĂ©es # 3 Ă  la page # 70133, Ă  l'aide de la requĂȘte suivante:

Use WideWorldImporters;
GO
SELECT 
    sys.fn_PhysLocFormatter (%%physloc%%),
    *
FROM Sales.OrderLines (NOLOCK)
WHERE sys.fn_PhysLocFormatter (%%physloc%%) like '(3:70133%'
GO




Comme je l'ai dit - c'est lent mĂȘme sur de petites tables. J'ai ajoutĂ© NOLOCK Ă  la requĂȘte car nous n'avons toujours aucune garantie que les donnĂ©es que nous voulons regarder sont exactement les mĂȘmes que lorsque le verrou a Ă©tĂ© trouvĂ© - afin que nous puissions faire des lectures incorrectes en toute sĂ©curitĂ©.

Mais, hourra, la requĂȘte me renvoie les mĂȘmes 25 lignes pour lesquelles notre requĂȘte s'est battue.



Assez parlé des verrous PAGE. Et si nous attendons un verrou KEY?



2) waitresource = "KEY: 6: 72057594041991168 (ce52f92a058c)" = Database_Id, HOBT_Id (hash magique qui peut ĂȘtre dĂ©chiffrĂ© avec %% lockres %% si vous le souhaitez vraiment)





Si votre requĂȘte tente de verrouiller une entrĂ©e d'index et se verrouille d'elle-mĂȘme, vous obtenez un type d'adresse complĂštement diffĂ©rent.

En décomposant «6: 72057594041991168 (ce52f92a058c)» en plusieurs parties, nous obtenons:

  • id_base_de_donnĂ©es = 6
  • hobt_id = 72057594041991168
  • hachage magique = (ce52f92a058c)




2.1) DĂ©crypter database_id



Cela fonctionne exactement de la mĂȘme maniĂšre que dans l'exemple ci-dessus! Recherchez le nom de la base de donnĂ©es Ă  l'aide de la requĂȘte:

SELECT 
    name 
FROM sys.databases 
WHERE database_id=6;
GO


Dans mon cas, il s'agit de la mĂȘme base de donnĂ©es WideWorldImporters .



2.2) DĂ©crypter le hobt_id



Dans le contexte de la base de donnĂ©es trouvĂ©e, vous devez exĂ©cuter une requĂȘte sur sys.partitions avec quelques jointures qui vous aideront Ă  dĂ©terminer les noms de table et d'index ...

USE WideWorldImporters;
GO
SELECT 
    sc.name as schema_name, 
    so.name as object_name, 
    si.name as index_name
FROM sys.partitions AS p
JOIN sys.objects as so on 
    p.object_id=so.object_id
JOIN sys.indexes as si on 
    p.index_id=si.index_id and 
    p.object_id=si.object_id
JOIN sys.schemas AS sc on 
    so.schema_id=sc.schema_id
WHERE hobt_id = 72057594041991168;
GO


Il m'indique que la demande Ă©tait en attente sur le verrou Application.Countries Ă  l'aide de l'index PK_Application_Countries.



2.3) Maintenant un peu de magie %% lockres %% - si vous voulez savoir quel enregistrement a été verrouillé



Si je veux vraiment savoir sur quelle ligne le verrou Ă©tait nĂ©cessaire, je peux le comprendre en interrogeant la table elle-mĂȘme. Nous pouvons utiliser la fonction %% lockres %% non documentĂ©e pour trouver l'entrĂ©e qui correspond au hachage magique.

Notez que cette requĂȘte analysera la table entiĂšre, et sur les grandes tables, cela peut ne pas ĂȘtre amusant du tout:

SELECT
    *
FROM Application.Countries (NOLOCK)
WHERE %%lockres%% = '(ce52f92a058c)';
GO


J'ai ajoutĂ© NOLOCK ( sur les conseils de Klaus Aschenbrenner sur Twitter ) car le blocage peut ĂȘtre un problĂšme. Nous voulons simplement voir ce qu'il y a maintenant, et non ce qu'il y avait au dĂ©but de la transaction - je ne pense pas que la cohĂ©rence des donnĂ©es soit importante pour nous.

Voila, le record pour lequel nous nous sommes battus!





Remerciements et lectures complémentaires



Je ne me souviens pas qui a été le premier à décrire beaucoup de ces choses, mais voici deux articles sur les choses les moins documentées que vous pourriez aimer:




All Articles