<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Le Blog SQL Server d&#039;ElSüket &#187; blocked process threshold</title>
	<atom:link href="https://blog.developpez.com/elsuket/ptag/blocked-process-threshold/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/elsuket</link>
	<description>Nicolas Souquet - Expert SQL Server</description>
	<lastBuildDate>Mon, 05 Apr 2021 07:32:41 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Auditer les processus bloqués : l&#8217;événement blocked process report</title>
		<link>https://blog.developpez.com/elsuket/p12049/snippets/auditer-les-processus-bloques-levenement-blocked-process-report</link>
		<comments>https://blog.developpez.com/elsuket/p12049/snippets/auditer-les-processus-bloques-levenement-blocked-process-report#comments</comments>
		<pubDate>Sat, 15 Jun 2013 10:46:31 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Non documenté]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[%%lockres%%]]></category>
		<category><![CDATA[blocage]]></category>
		<category><![CDATA[blocked process report]]></category>
		<category><![CDATA[blocked process threshold]]></category>
		<category><![CDATA[blocking]]></category>
		<category><![CDATA[deadlock]]></category>
		<category><![CDATA[événements étendus]]></category>
		<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[lock monitor]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[sp_configure]]></category>
		<category><![CDATA[timeout]]></category>
		<category><![CDATA[verrou]]></category>
		<category><![CDATA[waitresource]]></category>
		<category><![CDATA[XE]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=604</guid>
		<description><![CDATA[SQL Server 2005 a introduit un évènement capturable par SQL Profiler et par les Notifications d’évènements, qui permet de retrouver les processus qui ont été bloqués. Avec la sortie de SQL Server 2008 et l&#8217;introduction des Évènements Étendus, il nous &#8230; <a href="https://blog.developpez.com/elsuket/p12049/snippets/auditer-les-processus-bloques-levenement-blocked-process-report">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2005 a introduit un évènement capturable par <em><a href="http://elsuket.developpez.com/tutoriels/sqlserveur/fichier-trace-cote-serveur/">SQL Profiler</a></em> et par les <em>Notifications d’évènements</em>, qui permet de retrouver les processus qui ont été bloqués. Avec la sortie de SQL Server 2008 et l&rsquo;introduction des <em><a href="http://elsuket.developpez.com/tutoriels/sqlserveur/EvenementsEtendusSQLServer2008/">Évènements Étendus</a></em>, il nous est également possible de capturer cet évènement.</p>
<p>Dans cet article, je vous propose de voir comment paramétrer SQL Server pour capturer cet évènement, puis de vous aider à interpréter le document XML qui décrit la situation de blocage.<br />
<span id="more-604"></span><br />
Toute exécution de requête résulte en l&rsquo;acquisition de verrous, dont la granularité (ligne, page, clé, partition, table, base de données, ou encore et plus rarement compilation) et le mode (partagé, exclusif, de mise à jour, ou d&rsquo;intention) varient. Le verrouillage de ressources est une opération de base pour le moteur de stockage de tout moteur de bases de données SQL, qui garantit l&rsquo;intégrité de la base de données à travers toutes les opérations de manipulation de données que celle-ci supporte. Cependant, il arrive que lorsqu&rsquo;un processus a posé un verrou sur une ressource, d&rsquo;autres processus doivent simultanément accéder à cette même ressource : ces processus sont alors bloqués. Comme il est possible que le processus bloquant ne libère ledit verrou qu&rsquo;après une durée relativement longue, les effets possibles d&rsquo;une telle situation sur nos applications peuvent aller de requêtes dont la durée d&rsquo;exécution est élevée jusqu&rsquo;à l&rsquo;expiration du délai d&rsquo;attente d&rsquo;une réponse pour l&rsquo;exécution d&rsquo;un requête : le fameux <em>timeout</em>.</p>
<p>Il est néanmoins possible, à l&rsquo;aide d&rsquo;une trace SQL Profiler ou des Évènements Étendus, de capturer ces situations, qui sont décrites par un document XML.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Configurer l&rsquo;instance SQL Server</strong></p>
<p>Le seuil de durée de blocage à partir de laquelle on souhaite capturer un tel évènement est configurable à l&rsquo;aide de l&rsquo;option d&rsquo;instance <em>blocked process threshold</em>. On accède à ce paramètre :</p>
<p>&#8211; soit à l&rsquo;aide de <em>SQL Server Management Studio</em> (SSMS), après un clic-droit sur l&rsquo;instance dans l&rsquo;Explorateur d&rsquo;Objets (F8), et avoir choisi l&rsquo;option <em>Propriétés</em> :</p>
<p><img src="http://img855.imageshack.us/img855/6901/gq2.png" alt="" /></p>
<p>&#8211; soit à l&rsquo;aide de la procédure stockée système <em>sp_configure</em> :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">configurations</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'%block%'</span></div></td></tr></tbody></table></div>
<p><img src="http://img836.imageshack.us/img836/9273/zx81.png" alt="" /></p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Activation de la modification d'options d'instance avancées</span><br />
<span style="color: #0000FF;">EXEC</span> sys.<span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'show advanced options'</span>, <span style="color: #000;">1</span> <br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO<br />
<br />
<span style="color: #008080;">-- Configuration du seuil de durée de blocage à 5 secondes</span><br />
<span style="color: #0000FF;">EXEC</span> sys.<span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'blocked process threshold'</span>, <span style="color: #000;">5</span><br />
GO <br />
<span style="color: #0000FF;">RECONFIGURE</span>; <br />
GO<br />
<br />
<span style="color: #008080;">-- Désactivation de la modification d'options d'instance avancées</span><br />
<span style="color: #0000FF;">EXEC</span> sys.<span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'show advanced options'</span>, <span style="color: #000;">0</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO</div></td></tr></tbody></table></div>
<p>La console de SSMS affiche, à l&rsquo;exécution de ce lot de requêtes :</p>
<p><img src="http://img28.imageshack.us/img28/4259/1ug.png" alt="" /></p>
<p>Veillez à ne pas mettre un seuil trop bas : sans cela, on aurait le processus d&rsquo;arrière plan LOCK MONITOR qui s&rsquo;exécuterait constamment. Or ce dernier, qui est aussi en charge de détecter les deadlocks, est gourmand en ressources CPU. En s&rsquo;exécutant fréquemment, il pourrait donc impacter négativement les performances générales de l&rsquo;instance SQL Server. D&rsquo;un autre côté, 5 secondes est une durée très longue sur une base de données qui supporte une charge de travail OLTP conséquente. On trouve ce processus avec la requête suivante :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; session_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , status<br />
&nbsp; &nbsp; &nbsp; &nbsp; , command<br />
&nbsp; &nbsp; &nbsp; &nbsp; , wait_type<br />
&nbsp; &nbsp; &nbsp; &nbsp; , wait_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; , last_wait_type<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_exec_requests</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; command <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOCK MONITOR'</span></div></td></tr></tbody></table></div>
<p>Si l&rsquo;on exécute maintenant cette requête de façon répétée, on voit que la valeur de la colonne <em>wait_time</em> croit jusqu&rsquo;à atteindre 5000, mais ne dépasse jamais cette valeur : cette colonne affiche sa valeur en millisecondes, et montre bien que le processus cherche les processus bloqués toutes les 5 secondes.</p>
<p>Il faut aussi noter qu&rsquo;avec cette configuration, si un processus reste bloqué 15 secondes, l’évènement sera généré 3 fois pour la même situation de blocage.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Capture avec SQL Profiler</strong></p>
<p>Une fois cela fait, nous démarrons SQL Profiler, et dans l&rsquo;onglet de sélection des évènements, dans la catégorie <em>Errors and Warnings</em> (et non pas dans la catégorie <em>Locks</em>), nous trouvons l’évènement <em>Blocked process report</em> :</p>
<p><img src="http://img546.imageshack.us/img546/5205/hptk.png" alt="" /></p>
<p>Nous configurons l’évènement comme suit, où le champ <em>TextData</em> contiendra le document XML décrivant la situation de blocage :</p>
<p><img src="http://img19.imageshack.us/img19/2305/n66.png" alt="" /></p>
<p><strong>N.B.</strong> : N&rsquo;oubliez pas le champ <em>Mode</em>, qui procure le type de verrou acquis.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Capture avec les Évènements Étendus (XE)</strong></p>
<p>Pour les lecteurs qui n&rsquo;ont pas encore eu le temps de se familiariser avec cette fonctionnalité, qui est vouée au remplacement futur de SQL Profiler, et dont la puissance en fait mon outil de diagnostic favori, vous pouvez vous aider de l&rsquo;<a href="http://elsuket.developpez.com/tutoriels/sqlserveur/EvenementsEtendusSQLServer2008/">article</a> que j&rsquo;ai publié sur le sujet.</p>
<p>Si l&rsquo;on souhaite capturer en permanence toute situation de blocage, l&rsquo;avantage revient à XE, puisqu&rsquo;on peut stocker ces évènements dans une cible dite anneau de mémoire (ring buffer). Cette structure consomme très peu de mémoire et fonctionne à l&rsquo;image d&rsquo;un FIFO : lorsqu&rsquo;il est plein, la capture d&rsquo;un nouvel évènement donne lieu à l&rsquo;éviction du plus vieil évènement pour le stockage de celui-ci. Avec SQL Profiler, il est nécessaire de mettre en place une trace côté serveur et de gérer le fichier de trace et l&rsquo;espace disque. En revanche, une fois que l&rsquo;on a démarré la session XE, on peut &laquo;&nbsp;l&rsquo;oublier&nbsp;&raquo;.</p>
<p>Pour les lecteurs familiers de XE et de Profiler, sachez que le document XML produit par ces deux fonctionnalités pour un même évènement de blocage est identique, ce qui n&rsquo;est pas le cas avec les deadlocks (XE produit un document XML mal formé, qui rend impossible son enregistrement en document de type .xdl en vue de son interprétation graphique dans SSMS).</p>
<p>La définition d&rsquo;une telle session est simple :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Définition de la session</span><br />
<span style="color: #0000FF;">CREATE</span> EVENT <span style="color: #0000FF;">SESSION</span> blocked_process_report_RB <span style="color: #0000FF;">ON</span> SERVER<br />
<span style="color: #0000FF;">ADD</span> EVENT sqlserver.<span style="color: #202020;">blocked_process_report</span><br />
<span style="color: #0000FF;">ADD</span> TARGET package0.<span style="color: #202020;">ring_buffer</span> <span style="color: #808080;">&#40;</span><span style="color: #0000FF;">SET</span> MAX_MEM<span style="color: #808080;">OR</span>Y <span style="color: #808080;">=</span> <span style="color: #000;">4096</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">WITH</span> <span style="color: #808080;">&#40;</span>MAX_DISPATCH_LATENCY <span style="color: #808080;">=</span> <span style="color: #000;">5</span> SECONDS<span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #008080;">-- Démarrage de la session</span><br />
<span style="color: #0000FF;">ALTER</span> EVENT <span style="color: #0000FF;">SESSION</span> blocked_process_report_RB <span style="color: #0000FF;">ON</span> SERVER<br />
<span style="color: #0000FF;">STATE</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">START</span><br />
<br />
<span style="color: #008080;">-- Vérification</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , create_time<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_sessions</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">=</span> <span style="color: #FF0000;">'blocked_process_report_RB'</span></div></td></tr></tbody></table></div>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Le test</strong></p>
<p>Pour l&rsquo;exemple, nous avons la trace SQL Profiler et la session XE ci-dessus actifs.<br />
Nous créons la table suivante :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> blocked_process_report_test<br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cle <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">16</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CONSTRAINT</span> UQ_blocked_process_report_test <span style="color: #0000FF;">UNIQUE</span> <span style="color: #0000FF;">CLUSTERED</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , valeur <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p>Puis, dans une première fenêtre de requête (A) sous SSMS, nous ajoutons la ligne suivante, sans valider la transaction :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">BEGIN</span> <span style="color: #0000FF;">TRANSACTION</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> dbo.<span style="color: #202020;">blocked_process_report_test</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cle<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , valeur<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">VALUES</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">'TEST'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #000;">12</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p>Dans une seconde fenêtre de requête (B), nous exécutons :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">UPDATE</span>&nbsp; dbo.<span style="color: #202020;">blocked_process_report_test</span><br />
<span style="color: #0000FF;">SET</span> &nbsp; &nbsp; valeur <span style="color: #808080;">=</span> <span style="color: #000;">15</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; cle <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TEST'</span></div></td></tr></tbody></table></div>
<p>Ceci fait que la requête B doit attendre que la requête A soit terminée pour réaliser l&rsquo;UPDATE, ce qui ne peut se faire que si l&rsquo;on valide (COMMIT) ou annule (ROLLBACK) la transaction : nous ne le faisons pas ici, pour l&rsquo;exemple. Nous laissons aussi la requête B s&rsquo;exécuter 10 secondes, de façon à bien voir que l’évènement est capturé deux fois pour la même situation de blocage.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Ce que capture SQL Profiler</strong></p>
<p>L&rsquo;interface affiche bien deux captures de l’évènement :</p>
<p><img src="http://img705.imageshack.us/img705/8171/5kt.png" alt="" /></p>
<p>Notez que les valeurs pour la colonne <em>Duration</em> sont données ici en microsecondes : on voit donc qu&rsquo;il y a un léger décalage entre la détection du blocage et sa capture. Toutes les informations dont nous avons besoin sont donc sous nos yeux: la ressource à la source de la situation de blocage, ainsi que les requêtes impliquées dans celle-ci.</p>
<p>Il est possible de charger le fichier de trace dans une table à l&rsquo;aide de la fonction <a href="http://msdn.microsoft.com/fr-fr/library/ms188425.aspx">sys.fn_trace_gettable()</a>. Cela permet l&rsquo;écriture d&rsquo;une requête utilisant les méthodes SQLXML, qui extrait directement les informations intéressantes de chaque document XML. La requête est similaire à celle que je donne dans la section suivante.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Ce que capture la session XE</strong></p>
<p>Ici il nous est nécessaire d&rsquo;écrire une requête faisant appel aux fonctions SQLXML pour dépouiller le document XML sans se fatiguer :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #FF00FF;">DATEADD</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">hour</span>, <span style="color: #FF00FF;">DATEDIFF</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">hour</span>, <span style="color: #FF00FF;">GETUTCDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>, doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/@timestamp)[1]'</span>, <span style="color: #FF0000;">'datetime'</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> log_date_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;transaction_id&quot;]/value)[1]'</span>, <span style="color: #FF0000;">'bigint'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> transaction_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;database_name&quot;]/value)[1]'</span>, <span style="color: #FF0000;">'nvarchar(128)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;duration&quot;]/value)[1]'</span>, <span style="color: #FF0000;">'int'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> <span style="color: #000;">1000</span> <span style="color: #0000FF;">AS</span> duration_ms<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;resource_owner_type&quot;]/text)[1]'</span>, <span style="color: #FF0000;">'varchar(10)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> resource_owner_type<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;lock_mode&quot;]/text)[1]'</span>, <span style="color: #FF0000;">'varchar(10)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> lock_mode<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocked-process/process/@waitresource)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> wait_resource<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocked-process/process/@isolationlevel)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocked_tran_iso_level<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocking-process/process/@isolationlevel)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocking_tran_iso_level<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocked-process/process/inputbuf)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocked_statement<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocking-process/process/inputbuf)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocking_statement<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">n</span>.<span style="color: #202020;">query</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'.'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> doc<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>target_data <span style="color: #0000FF;">AS</span> xml<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_sessions</span> <span style="color: #0000FF;">AS</span> S &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_session_targets</span> <span style="color: #0000FF;">AS</span> ST<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> S.<span style="color: #202020;">address</span> <span style="color: #808080;">=</span> ST.<span style="color: #202020;">event_session_address</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'blocked_process_report_RB'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ST.<span style="color: #202020;">target_name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ring_buffer'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> sub<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; <span style="color: #0000FF;">data</span>.<span style="color: #202020;">nodes</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'RingBufferTarget/event'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> D<span style="color: #808080;">&#40;</span>n<span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> T</div></td></tr></tbody></table></div>
<p>La capture d&rsquo;écran du résultat a été coupée en deux pour faciliter un peu la lecture :</p>
<p><img src="http://img827.imageshack.us/img827/7796/91d.png" alt="" /></p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Interprétation du résultat</strong></p>
<p>Notre intérêt dans l&rsquo;interprétation de ce document se portera sur la propriété waitresource, que l&rsquo;on peut décrypter à l&rsquo;aide de la <a href="http://support.microsoft.com/kb/224453">documentation</a> (Voir la section <strong><em>Waitresource</em></strong>).</p>
<p>Ici, waitresource est : KEY: 5:72057594039107584 (2158b2b5a6d5), ce qui signifie :</p>
<p>&#8211; Database ID : 5<br />
&#8211; Partition ID : 72057594039107584<br />
&#8211; (2158b2b5a6d5) : le hash de la clé d&rsquo;index</p>
<p>Sur ce dernier point, il faut savoir que SQL Server utilise le hash, stocké sur 6 octets, de la clé de l&rsquo;index qui supporte la requête. Ceci conduit SQL Server à générer des valeurs de hash identiques pour des valeurs de clé différentes, ce qui peut causer d&rsquo;autre problèmes de concurrence d&rsquo;accès. C&rsquo;est une raison de plus pour choisir des clés d&rsquo;index les plus &laquo;&nbsp;étroites&nbsp;&raquo; possible, de façon à éviter ce type de collisions.</p>
<p>Voyons comment retrouver la ressource qui a été verrouillée :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">USE</span> ELSUKET<br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; O.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> table_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , I.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> index_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , P.<span style="color: #202020;">partition_number</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , P.<span style="color: #0000FF;">rows</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">partitions</span> <span style="color: #0000FF;">AS</span> p<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">objects</span> <span style="color: #0000FF;">AS</span> O<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> O.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> P.<span style="color: #FF00FF;">object_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">indexes</span> <span style="color: #0000FF;">AS</span> I<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> P.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> I.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> P.<span style="color: #202020;">index_id</span> <span style="color: #808080;">=</span> I.<span style="color: #202020;">index_id</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.<span style="color: #202020;">partition_id</span> <span style="color: #808080;">=</span> <span style="color: #000;">72057594039107584</span></div></td></tr></tbody></table></div>
<p><img src="http://img818.imageshack.us/img818/5617/zsbe.png" alt="" /></p>
<p>Voyons maintenant comment retrouver la clé qui a été utilisée :</p>
<div class="codecolorer-container tsql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; dbo.<span style="color: #202020;">blocked_process_report_test</span> <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">INDEX</span> <span style="color: #808080;">=</span> UQ_blocked_process_report_test<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; <span style="color: #808080;">%%</span>lockres<span style="color: #808080;">%%</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'(2158b2b5a6d5)'</span></div></td></tr></tbody></table></div>
<p><img src="http://img268.imageshack.us/img268/5628/5xt.png" alt="" /></p>
<p>La fonction %%lockres%% n&rsquo;est pas documentée : il est donc recommandé de l&rsquo;utiliser avec parcimonie. La même méthodologie est utilisable dans le diagnostic des deadlocks.</p>
<p>Bon déblocage à tous !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
