<?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; Non documenté</title>
	<atom:link href="https://blog.developpez.com/elsuket/pcategory/moteur-de-base-de-donnees-sql-server/non-documente/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>
		<item>
		<title>Quelles statistiques l&#8217;Optimiseur a-t-il utilisées pour calculer le plan de requête ?</title>
		<link>https://blog.developpez.com/elsuket/p12023/moteur-de-base-de-donnees-sql-server/quelles-statistiques-loptimiseur-a-t-il-utilisees-pour-calculer-le-plan-de-requete</link>
		<comments>https://blog.developpez.com/elsuket/p12023/moteur-de-base-de-donnees-sql-server/quelles-statistiques-loptimiseur-a-t-il-utilisees-pour-calculer-le-plan-de-requete#comments</comments>
		<pubDate>Thu, 06 Jun 2013 16:19:44 +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[SQL Server 2012]]></category>
		<category><![CDATA[8666]]></category>
		<category><![CDATA[drapeau de trace]]></category>
		<category><![CDATA[plan d'exécution]]></category>
		<category><![CDATA[statistiques]]></category>
		<category><![CDATA[trace flag]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=559</guid>
		<description><![CDATA[Si une bonne partie de votre temps de travail est consacrée à l&#8217;optimisation de requête et à la compréhension du fonctionnement de l&#8217;Optimiseur de Requêtes, vous vous êtes probablement demandé sur quelles statistiques celui-ci se base pour calculer le plan &#8230; <a href="https://blog.developpez.com/elsuket/p12023/moteur-de-base-de-donnees-sql-server/quelles-statistiques-loptimiseur-a-t-il-utilisees-pour-calculer-le-plan-de-requete">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Si une bonne partie de votre temps de travail est consacrée à l&rsquo;optimisation de requête et à la compréhension du fonctionnement de l&rsquo;Optimiseur de Requêtes, vous vous êtes probablement demandé sur quelles statistiques celui-ci se base pour calculer le plan d&rsquo;une requête.</p>
<p>Il existe un drapeau de trace <strong>non-documenté</strong>, n° 8666, qui permet d&rsquo;ajouter au document XML qui décrit le plan de requête les statistiques utilisées par l&rsquo;optimiseur pour générer le plan de requêtes.</p>
<p>Voyons comment l&rsquo;utiliser avec une requête sur la base de données <a href="http://blog.developpez.com/elsuket/p11188/moteur-de-base-de-donnees-sql-server/attacher_base_donnees_sans_tran_log">AdventureWorks2012</a> :</p>
<p><span id="more-559"></span></p>
<p>Avant toute chose, notez que ce drapeau de trace n&rsquo;est pas documenté. Comme toute fonctionnalité non-documentée, on ne doit <strong>JAMAIS</strong> utiliser celui-ci sur une base de données ou une instance qui sert une charge de production. <strong>Si tel devait être le cas, je ne peux en aucun cas être tenu pour responsable des conséquences. Vous devez limiter strictement l’usage de cette instruction aux environnements de test.</strong></p>
<p>Utilisons 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 />9<br />10<br />11<br />12<br />13<br />14<br />15<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;">DBCC</span> TRACEON <span style="color: #808080;">&#40;</span><span style="color: #000;">8666</span><span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #0000FF;">USE</span> AdventureWorks2012<br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SOH.<span style="color: #202020;">OrderDate</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOH.<span style="color: #202020;">DueDate</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOH.<span style="color: #202020;">ShipDate</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOH.<span style="color: #202020;">AccountNumber</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOD.<span style="color: #202020;">OrderQty</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOD.<span style="color: #202020;">UnitPrice</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Sales.<span style="color: #202020;">SalesOrderHeader</span> <span style="color: #0000FF;">AS</span> SOH<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; Sales.<span style="color: #202020;">SalesOrderDetail</span> <span style="color: #0000FF;">AS</span> SOD<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SOH.<span style="color: #202020;">SalesOrderID</span> <span style="color: #808080;">=</span> SOD.<span style="color: #202020;">SalesOrderID</span></div></td></tr></tbody></table></div>
<p>Demandons maintenant à SQL Server de générer le plan de requête estimé. Celui-ci s&rsquo;obtient soit en pressant CTRL + L, soit par un clic sur l&rsquo;icône suivante, présente dans la barre d&rsquo;outils : </p>
<p><img src="http://img199.imageshack.us/img199/605/estimatedexecutionplan.png" alt="" /></p>
<p>On obtiendra aussi les informations ajoutées par le drapeau de trace 8666 avec le plan d&rsquo;exécution réel, que l&rsquo;on obtient soit en pressant CTRL + M, soit par un clic sur l&rsquo;icône, suivante présente elle aussi dans la barre d&rsquo;outils : </p>
<p><img src="http://img41.imageshack.us/img41/2989/actualexecutionplan.png" alt="" /></p>
<p>Nous devons maintenant explorer le document XML à l&rsquo;origine du plan d&rsquo;exécution graphique, ce qui se fait par un simple clic droit dans une zone vierge de ce dernier :</p>
<p><img src="http://img546.imageshack.us/img546/1588/tf866601.png" alt="" /></p>
<p>Il nous suffit maintenant de chercher la chaîne de caractères <em>wszStatName</em>, et nous obtenons :</p>
<p><img src="http://img9.imageshack.us/img9/3892/tf866602.png" alt="" /></p>
<p>On voit clairement les détails de ce que SQL Server utilise comme métriques pour calculer le plan, notamment :</p>
<p>&#8211; le nom de la statistique (ici c&rsquo;est la statistiques sous-jacente à l&rsquo;index qui supporte la clé primaire)<br />
&#8211; le nom de la colonne la plus à gauche dans cette statistique (wszColName)<br />
&#8211; le nombre de lignes échantillonnées lors de la génération de la statique (m_ullSnapShotModCtr)<br />
&#8211; le nombre de lignes présentes dans la table (m_ullRowCount)<br />
&#8211; le seuil de recalcul automatique de la statistique (ullThreshold)</p>
<p>Pour cette dernière valeur, on peut d&rsquo;ailleurs faire le calcul suivant :</p>
<blockquote><p>100.0 * 24,763 / 121,317 = 20.41181367821492</p></blockquote>
<p>Soit environ 20%. Prenons la partie décimale de ce pourcentage : </p>
<blockquote><p>(0.41181367821492 / 100.0) * 121,317 = 499.5999999999945</p></blockquote>
<p>Soit environ 500 lignes. Ceci vérifie bien la règle du seuil de recalcul automatique des statistiques pour les tables de plus de 8MB : 500 lignes + 20% du nombre de lignes de la table.</p>
<p>Bons calculs de plans de requêtes et estimations de cardinalités !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Une procédure stockée pour connaître l&#8217;état des fichiers du journal des transactions</title>
		<link>https://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions</link>
		<comments>https://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions#comments</comments>
		<pubDate>Mon, 11 Feb 2013 05:12:22 +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[DBCC]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[transaction]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=199</guid>
		<description><![CDATA[Ha ! le fichier du journal des transactions, l&#8217;option de récupération, son grossissement, &#8230; et bien sûr la fameuse transaction restée ouverte qui a provoqué une explosion de la taille de celui-ci, allant jusqu&#8217;à remplir le volume disque qui l&#8217;héberge &#8230; <a href="https://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Ha ! le fichier du journal des transactions, l&rsquo;option de récupération, son grossissement, &#8230; et bien sûr la fameuse transaction restée ouverte qui a provoqué une explosion de la taille de celui-ci, allant jusqu&rsquo;à remplir le volume disque qui l&rsquo;héberge : tout autant de paramétrages et d&rsquo;investigations fastidieuses.</p>
<p>Alors comme je n&rsquo;aime pas beaucoup répéter plusieurs fois les mêmes opérations sans avoir un script, ou mieux, une procédure stockée sous la main, j&rsquo;ai créé la suivante, dont voici le script de création :</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 />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<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> master<br />
GO<br />
<br />
<span style="color: #008080;">-----------------------------------------------------------------</span><br />
<span style="color: #008080;">-- Nicolas Souquet - 09/02/2013</span><br />
<span style="color: #008080;">-- LA PROCEDURE STOCKEE SUIVANTE EST DONNEE EN TANT QUE TELLE</span><br />
<span style="color: #008080;">-- SON UTILISATION ET SA MODIFICATION EST A VOS RISQUES ET PÉRILS</span><br />
<span style="color: #008080;">-----------------------------------------------------------------</span><br />
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>sp__log_space_get<span style="color: #808080;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @_database_name sysname <span style="color: #808080;">=</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #0000FF;">AS</span><br />
<span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @<span style="color: #0000FF;">sql</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de l'espace disque disponible</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- sur tous les volumes visibles par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @free_disk_space <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; drive_letter <span style="color: #0000FF;">char</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</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; , free_space_MB <span style="color: #0000FF;">int</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @free_disk_space<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; master.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">xp_fixeddrives</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de l'occupation des fichiers des journaux de transaction</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- de toutes les bases de données hébergées par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @dbcc_sqlperf_logspace <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; database_name sysname<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_size <span style="color: #0000FF;">float</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_space_used_pct <span style="color: #0000FF;">decimal</span> <span style="color: #808080;">&#40;</span><span style="color: #000;">5</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , status <span style="color: #0000FF;">tinyint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_sqlperf_logspace<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'DBCC SQLPERF(logspace)'</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de la liste de tous les fichiers virtuels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- du fichier du journal des transactions de toutes les bases de données</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- disponibles, hébergées par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @dbcc_loginfo <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; recovery_unit_id <span style="color: #0000FF;">tinyint</span> <span style="color: #008080;">-- new column in SQL Server 2012</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , fileid <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , file_size <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , start_offset <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , f_seq_no <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , status <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , parity <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , create_LSN <span style="color: #0000FF;">varbinary</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">max</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Cas où l'on souhaite réaliser l'audit du fichier du journal des transactions</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- de toutes les bases de données hébergées par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Dans ce cas le paramètre d'entrée @_database_name est à NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_database_name <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @dbcc_loginfo_all_db <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &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; database_name <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">128</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_file_id <span style="color: #0000FF;">tinyint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , vlf_count <span style="color: #0000FF;">smallint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de liste de toutes les bases de données disponibles</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- (pas une capture iOFFLINE, SINGLE_USER, ou ... SUSPECT ;))</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &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; database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_file_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , vlf_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><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;">name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #FF00FF;">file_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #000;">0</span><br />
&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;">databases</span> <span style="color: #0000FF;">AS</span> D<br />
&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;">master_files</span> <span style="color: #0000FF;">AS</span> MF<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;">ON</span> D.<span style="color: #202020;">database_id</span> <span style="color: #808080;">=</span> MF.<span style="color: #202020;">database_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">source_database_id</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span> <span style="color: #008080;">-- ce n'est pas une capture instantanée de base de données</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">state_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span> <span style="color: #008080;">-- la base de données est disponible</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">user_access_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span> <span style="color: #008080;">-- la base de données est à l'écoute de connexions utilisateur</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MF.<span style="color: #202020;">type_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span> <span style="color: #008080;">-- le type de fichier est &quot;journal des transactions&quot;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Pour chaque base de données, récupération de la liste des fichiers virtuels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- du fichier du journal des transactions pour toutes les bases de données disponibles</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">EXISTS</span><br />
&nbsp; &nbsp; &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; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; vlf_count <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> @_database_name <span style="color: #808080;">=</span> database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; vlf_count <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @<span style="color: #0000FF;">sql</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'DBCC LOGINFO ('</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">')'</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span>@<span style="color: #0000FF;">sql</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;<span style="color: #0000FF;">WITH</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &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; fileid<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; , <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> vlf_count<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; @dbcc_loginfo<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;">GROUP</span> &nbsp; <span style="color: #0000FF;">BY</span> fileid<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">UPDATE</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vlf_count <span style="color: #808080;">=</span> C.<span style="color: #202020;">vlf_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @dbcc_loginfo_all_db <span style="color: #0000FF;">AS</span> DLAD<br />
&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; CTE <span style="color: #0000FF;">AS</span> C<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; <span style="color: #0000FF;">ON</span> DLAD.<span style="color: #202020;">log_file_id</span> <span style="color: #808080;">=</span> C.<span style="color: #202020;">fileid</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DLAD.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> @_database_name<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DELETE</span>&nbsp; <span style="color: #0000FF;">FROM</span> @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Résultat final, avec addition de quelques détails</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LS.<span style="color: #202020;">database_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">recovery_model_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> logical_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #0000FF;">AS</span> transaction_log_file_stored_on<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">free_space_MB</span> <span style="color: #0000FF;">AS</span> volume_free_space_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> transaction_log_file_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , LS.<span style="color: #202020;">log_space_used_pct</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_space_used_pct</span> <span style="color: #808080;">/</span> <span style="color: #000;">100.0</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">*</span> LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> log_used_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CASE</span> MF.<span style="color: #202020;">is_percent_growth</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;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">3</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' %'</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;">ELSE</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #808080;">/</span> <span style="color: #000;">128</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">20</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' MB'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #0000FF;">AS</span> growth &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">log_reuse_wait_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , DLAD.<span style="color: #202020;">vlf_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">physical_name</span><br />
&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;">master_files</span> <span style="color: #0000FF;">AS</span> MF<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @dbcc_sqlperf_logspace <span style="color: #0000FF;">AS</span> LS<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;">ON</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">DB_NAME</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">database_id</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @free_disk_space <span style="color: #0000FF;">AS</span> FDS<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;">ON</span> FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">physical_name</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&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;">databases</span> <span style="color: #0000FF;">AS</span> D<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;">ON</span> D.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @dbcc_loginfo_all_db <span style="color: #0000FF;">AS</span> DLAD<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;">ON</span> DLAD.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> D.<span style="color: #202020;">name</span> <span style="color: #0000FF;">COLLATE</span> database_default<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> DLAD.<span style="color: #202020;">log_file_id</span> <span style="color: #808080;">=</span> MF.<span style="color: #FF00FF;">file_id</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> DLAD.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">DB_NAME</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">database_id</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MF.<span style="color: #202020;">type_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">source_database_id</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">state_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">user_access_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Si la base de données que l'on souhaite auditer n'existe pas ==&amp;gt; exception</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span>@_database_name<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'The database named '</span><span style="color: #FF0000;">'%s'</span><span style="color: #FF0000;">' does not exist'</span>, <span style="color: #000;">16</span>, <span style="color: #000;">1</span>, @_database_name<span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RETURN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- récupération de la liste des fichiers virtuels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- du fichier du journal des transactions de la base de données choisie</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @vlf_count <span style="color: #0000FF;">int</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @<span style="color: #0000FF;">sql</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'DBCC LOGINFO ('</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">')'</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span>@<span style="color: #0000FF;">sql</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Résultat final, avec addition de quelques détails</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;<span style="color: #0000FF;">WITH</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &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; <span style="color: #0000FF;">SELECT</span>&nbsp; fileid<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> vlf_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">GROUP</span> &nbsp; <span style="color: #0000FF;">BY</span> fileid<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LS.<span style="color: #202020;">database_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">recovery_model_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> logical_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #0000FF;">AS</span> transaction_log_file_stored_on<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">free_space_MB</span> <span style="color: #0000FF;">AS</span> volume_free_space_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> transaction_log_file_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , LS.<span style="color: #202020;">log_space_used_pct</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_space_used_pct</span> <span style="color: #808080;">/</span> <span style="color: #000;">100.0</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">*</span> LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> log_used_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CASE</span> MF.<span style="color: #202020;">is_percent_growth</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;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">3</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' %'</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;">ELSE</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #808080;">/</span> <span style="color: #000;">128</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">20</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' MB'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #0000FF;">AS</span> growth<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">log_reuse_wait_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , C.<span style="color: #202020;">vlf_count</span> <span style="color: #0000FF;">AS</span> VLF_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">physical_name</span><br />
&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;">master_files</span> <span style="color: #0000FF;">AS</span> MF<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @dbcc_sqlperf_logspace <span style="color: #0000FF;">AS</span> LS<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;">ON</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">DB_NAME</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">database_id</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @free_disk_space <span style="color: #0000FF;">AS</span> FDS<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;">ON</span> FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">physical_name</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&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;">databases</span> <span style="color: #0000FF;">AS</span> D<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;">ON</span> D.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span> C<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;">ON</span> C.<span style="color: #202020;">fileid</span> <span style="color: #808080;">=</span> MF.<span style="color: #FF00FF;">file_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MF.<span style="color: #202020;">type_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LS.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> @_database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">source_database_id</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">state_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">user_access_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<span style="color: #0000FF;">END</span><br />
GO<br />
<br />
<span style="color: #008080;">-- On marque la procédure stockée comme objet système</span><br />
<span style="color: #008080;">-- Dès lors, on pourra l'exécuter dans n'importe quel contexte de base de données</span><br />
<span style="color: #0000FF;">EXEC</span> sp_ms_marksystemobject <span style="color: #FF0000;">'sp__log_space_get'</span></div></td></tr></tbody></table></div>
<p>Elle donne un résultat comme le suivant :</p>
<p><a href="http://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions/attachment/sp__log_space_get" rel="attachment wp-att-203"><img src="http://blog.developpez.com/elsuket/files/2013/02/sp__log_space_get-300x29.png" alt="sp__log_space_get" width="300" height="29" class="alignnone size-medium wp-image-203" /></a></p>
<p>à savoir :</p>
<p>&#8211; le nom de la base de données<br />
&#8211; l&rsquo;option de récupération de la base de données<br />
&#8211; le nom logique du fichier du journal des transactions (utile pour un DBCC SHRINKFILE après que le journal ait explosé en taille)<br />
&#8211; le volume sur lequel est hébergé le fichier du journal des transactions<br />
&#8211; la quantité d&rsquo;espace disque libre restant sur ce volume<br />
&#8211; la taille actuelle du fichier du journal des transactions<br />
&#8211; le pourcentage d&rsquo;utilisation de ce fichier (taille occupée dans le fichier par rapport à la taille totale du fichier)<br />
&#8211; la taille équivalente à ce pourcentage<br />
&#8211; le paramètre de grossissement de ce fichier<br />
&#8211; ce qui empêche actuellement la troncature de l&rsquo;espace occupé dans ce fichier<br />
&#8211; le chemin complet du fichier</p>
<p>On peut utiliser cette procédure stockée sous SQL Server 2005, 2008 et 2012.<br />
Elle fonctionne également pour les bases de données ayant plusieurs fichiers du journal des transactions</p>
<p>Bonne gestion des fichiers du journal des transactions !</p>
<p>ElSüket <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Marquer une procédure stockée comme objet système : la procédure stockée sp_MS_marksystemobject</title>
		<link>https://blog.developpez.com/elsuket/p9409/utilitaires/marquer_un_procedure_stockee_comme_objet</link>
		<comments>https://blog.developpez.com/elsuket/p9409/utilitaires/marquer_un_procedure_stockee_comme_objet#comments</comments>
		<pubDate>Tue, 19 Oct 2010 04:55:58 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Non documenté]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il peut être intéressant de pouvoir utiliser une procédure stockée dans n&#8217;importe quel contexte de base de données (sur la même instance SQL Server). Voyons comment faire cela à l&#8217;aide de la procédure stockée système non documentée sp_MS_marksystemobject Je cherchai &#8230; <a href="https://blog.developpez.com/elsuket/p9409/utilitaires/marquer_un_procedure_stockee_comme_objet">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Il peut être intéressant de pouvoir utiliser une procédure stockée dans n&rsquo;importe quel contexte de base de données (sur la même instance SQL Server).<br />
Voyons comment faire cela à l&rsquo;aide de la procédure stockée système <strong>non documentée <em>sp_MS_marksystemobject</em></strong><br />
<span id="more-130"></span><br />
Je cherchai à fournir à mes collègues développeurs SQL un moyen de générer des instructions CRUD (INSERT, SELECT, UPDATE, DELETE) de façon propre et générique.<br />
Voici donc l&rsquo;exemple de l&rsquo;INSERT (je publierai les autres dans un billet à venir) :</p>
<div class="codecolorer-container text 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 />24<br />25<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE master <br />
GO <br />
&nbsp;<br />
CREATE PROCEDURE dbo.sp__generate_INSERT <br />
&nbsp; &nbsp; @_table_name sysname, <br />
&nbsp; &nbsp; @_nb_tab tinyint = 0 <br />
AS <br />
BEGIN <br />
&nbsp; &nbsp; SET NOCOUNT ON <br />
&nbsp;<br />
&nbsp; &nbsp; DECLARE @sql varchar(max) <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;@sql = CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN @sql IS NULL THEN REPLICATE(CHAR(9), @_nb_tab) + 'INSERT' + CHAR(9) + @_table_name + &nbsp;CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + '(' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + CHAR(9) + name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE @sql + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + CHAR(9) + ', ' + name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;object_id = OBJECT_ID(@_table_name) <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;is_computed = 0 <br />
&nbsp; &nbsp; ORDER &nbsp; &nbsp;BY column_id <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; SET &nbsp; &nbsp;@sql = @sql + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + ')' <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; PRINT &nbsp; &nbsp;@sql <br />
END</div></td></tr></tbody></table></div>
<p>Vous remarquerez que je me place dans le contexte de la base de données système master, qui est la seule dans laquelle vous pouvez marquer des procédures stockées comme objet système.</p>
<p>Un autre requis pour pouvoir utiliser une procédure stockée marquée comme objet système dans n&rsquo;importe quel contexte de base de données de l&rsquo;instance en cours, est de faire commencer le nom de la procédure stockée par &laquo;&nbsp;sp&nbsp;&raquo;.<br />
Rien ne vous empêche de marquer la procédure stockée comme objet système, mais lorsque vous exécuterez une telle procédure stockée (dont le nom ne commence donc pas par &laquo;&nbsp;sp&nbsp;&raquo;), SQL Server &laquo;&nbsp;feindra&nbsp;&raquo; de ne pas trouver celle-ci.</p>
<p><strong>Le marquage se fait de façon extrêmement simple, mais n&rsquo;est pas documenté</strong> :</p>
<p><code class="codecolorer text default"><span class="text">EXEC sp_MS_marksystemobject 'sp__generate_INSERT'</span></code></p>
<p>Et le tour est joué : vous pouvez générer le script d&rsquo;INSERT en exécutant tout simplement :</p>
<div class="codecolorer-container text 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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE maBD <br />
GO <br />
&nbsp;<br />
EXEC sp__generate_INSERT 'maTable'</div></td></tr></tbody></table></div>
<p>Bonne génération !</p>
<p>ElSüket <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Trouver l&#8217;espace disque occupé par les fichiers, et l&#8217;espace libre dans ceux-ci</title>
		<link>https://blog.developpez.com/elsuket/p8540/moteur-de-base-de-donnees-sql-server/trouver_l_espace_disque_occupe_par_les_f</link>
		<comments>https://blog.developpez.com/elsuket/p8540/moteur-de-base-de-donnees-sql-server/trouver_l_espace_disque_occupe_par_les_f#comments</comments>
		<pubDate>Wed, 12 May 2010 09:08:49 +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[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici quelques requêtes pour vous permettre d&#8217;auditer vos fichiers de base de données : => Par une requête 12345678910111213141516171819202122232425------------------------------- -- Nicolas SOUQUET - 26/01/2010 ------------------------------- ;WITH &#160; &#160; CTE AS &#160; &#160; ( &#160; &#160; &#160; SELECT name AS nomLogique, &#8230; <a href="https://blog.developpez.com/elsuket/p8540/moteur-de-base-de-donnees-sql-server/trouver_l_espace_disque_occupe_par_les_f">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici quelques requêtes pour vous permettre d&rsquo;auditer vos fichiers de base de données :<br />
<span id="more-96"></span><br />
=> <strong>Par une requête</strong></p>
<div class="codecolorer-container text 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 />24<br />25<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- Nicolas SOUQUET - 26/01/2010 <br />
------------------------------- <br />
;WITH &nbsp; <br />
&nbsp; CTE AS &nbsp; <br />
&nbsp; ( &nbsp; <br />
&nbsp; &nbsp; SELECT name AS nomLogique, &nbsp;<br />
&nbsp; &nbsp; &nbsp; physical_name AS nomPhysique, &nbsp;<br />
&nbsp; &nbsp; &nbsp; CASE is_percent_growth <br />
&nbsp; WHEN 0 THEN CAST(growth * 8 / 1024 AS VARCHAR(8)) + ' MB' <br />
&nbsp; ELSE CAST(growth AS VARCHAR(3)) + ' %' <br />
&nbsp; &nbsp; &nbsp; END AS accroissement, &nbsp;<br />
&nbsp; &nbsp; &nbsp; CAST((size * 8) / CAST(1024 AS NUMERIC(14, 2)) AS NUMERIC(14, 2)) AS tailleFichier_MB, &nbsp;<br />
&nbsp; &nbsp; &nbsp; CAST((FILEPROPERTY(name, 'SpaceUsed') * 8) / CAST(1024 AS NUMERIC(14, 2)) AS NUMERIC(14, 2)) AS espaceOccupe &nbsp;<br />
&nbsp; &nbsp; FROM sys.database_files &nbsp;<br />
&nbsp; ) &nbsp;<br />
SELECT nomLogique, &nbsp;<br />
&nbsp; nomPhysique, &nbsp;<br />
&nbsp; tailleFichier_MB, &nbsp;<br />
&nbsp; accroissement, &nbsp;<br />
&nbsp; espaceOccupe AS espaceOccupe_MB, &nbsp;<br />
&nbsp; tailleFichier_MB - espaceOccupe AS espaceLibre_MB, &nbsp;<br />
&nbsp; CAST((CAST(espaceOccupe AS NUMERIC(14, 2)) / tailleFichier_MB) * 100 AS NUMERIC(14, 2)) AS [%occupe], &nbsp;<br />
&nbsp; CAST((CAST(tailleFichier_MB - espaceOccupe AS NUMERIC(14, 2)) / tailleFichier_MB) * 100 AS NUMERIC(14, 2)) AS [%libre] &nbsp;<br />
FROM CTE</div></td></tr></tbody></table></div>
<p>=> <strong>Avec l&rsquo;instruction DBCC SHOWFILESTATS</strong> (<strong>non documentée</strong>):</p>
<p>Elle donne le nombre d&rsquo;étendues (extents) occupées et le nombre total d&rsquo;étendues allouées pour le fichier.<br />
Une étendue étant constituée de 8 pages, et une page faisant 8192 octets, il vous faudra donc multiplier les nombres obtenus par 64Ko.</p>
<p>=> <strong>Avec la procédure stockée système sp_spaceused</strong> :</p>
<p>Elle retourne deux ensemble de résultats :<br />
&#8211; l&rsquo;espace occupé pour toute la base de données, mais attention seulement l&rsquo;espace libre dans le fichier de données.<br />
&#8211; le nombre de Ko réservés (= taille du fichier), utilisés (colonne data), dédiés aux index et inutilisés.</p>
<p>=> <strong>Avec l&rsquo;instruction DBCC SQLPERF(logspace)</strong></p>
<p>Celle-ci ne procure que la taille totale du fichier du journal des transactions, ainsi que son pourcentage d&rsquo;occupation.</p>
<p>Bonne gestion d&rsquo;espace disque <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>ElSuket.</p>
<p>=>=>=> <strong>12/05/2010 : MAJ :  un script pour connaître l&rsquo;espace occupé par et dans les fichiers, pour toutes les bases de données d&rsquo;une instance SQL Server :</strong></p>
<div class="codecolorer-container text 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 />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- 12/05/2010 - Nicolas SOUQUET <br />
------------------------------- <br />
SET NOCOUNT ON <br />
GO <br />
&nbsp;<br />
DECLARE @sql varchar(1024) <br />
SET @sql = 'SELECT name AS file_logical_name,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'physical_name AS file_physical_name,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'CASE is_percent_growth' + CHAR(13) + CHAR(10) + CHAR(9) + CHAR(9) + <br />
&nbsp; 'WHEN 0 THEN CAST(growth * 8 / 1024 AS varchar(8)) + '''' MB''''' + CHAR(13) + CHAR(10) + CHAR(9) + CHAR(9) + <br />
&nbsp; 'ELSE CAST(growth AS varchar(3)) + '''' %''''' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'END AS file_growth,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'CAST((size * 8) / CAST(1024 AS numeric(14, 2)) AS numeric(14, 2)) AS file_size_MB,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'CAST((FILEPROPERTY(name, ''''SpaceUsed'''') * 8) / CAST(1024 AS numeric(14, 2)) AS numeric(14, 2)) AS file_used_space_MB' + CHAR(13) + CHAR(10) + <br />
&nbsp; 'FROM sys.database_files''' + CHAR(13) + CHAR(10) <br />
&nbsp; <br />
DECLARE @exec_sql varchar(1024) <br />
&nbsp;<br />
DECLARE @instance_database_file_space TABLE <br />
( <br />
&nbsp; database_name sysname <br />
&nbsp; , file_logical_name sysname <br />
&nbsp; , file_physical_name nvarchar(260) &nbsp;<br />
&nbsp; , file_growth varchar(8) <br />
&nbsp; , file_size_MB numeric(14,2) <br />
&nbsp; , file_used_space_MB numeric(14,2) <br />
&nbsp; , file_free_space_MB numeric(14,2) <br />
&nbsp; , file_used_space_percent numeric(5,2) <br />
&nbsp; , file_free_space_percent numeric(5,2) <br />
) <br />
&nbsp;<br />
DECLARE @database_file_space TABLE <br />
( <br />
&nbsp; file_logical_name sysname <br />
&nbsp; , file_physical_name nvarchar(260) &nbsp;<br />
&nbsp; , file_growth varchar(8) <br />
&nbsp; , file_size_MB numeric(14,2) <br />
&nbsp; , file_used_space_MB numeric(14,2) <br />
) <br />
&nbsp;<br />
DECLARE db_cur CURSOR LOCAL FAST_FORWARD FOR <br />
&nbsp; SELECT &nbsp;name <br />
&nbsp; FROM &nbsp;sys.databases <br />
&nbsp; WHERE &nbsp;source_database_id IS NULL <br />
FOR READ ONLY <br />
&nbsp;<br />
DECLARE @database_name sysname <br />
&nbsp;<br />
OPEN db_cur <br />
FETCH NEXT FROM db_cur INTO @database_name <br />
WHILE @@fetch_status = 0 <br />
BEGIN <br />
&nbsp; DELETE &nbsp;@database_file_space <br />
&nbsp;<br />
&nbsp; SET @exec_sql = 'EXEC ' + @database_name + '.dbo.sp_executeSQL N''' + @sql + '' <br />
&nbsp;<br />
&nbsp; BEGIN TRY <br />
&nbsp; &nbsp; INSERT &nbsp;@database_file_space <br />
&nbsp; &nbsp; EXEC &nbsp;(@exec_sql) <br />
&nbsp; END TRY <br />
&nbsp; BEGIN CATCH <br />
&nbsp; &nbsp; PRINT @database_name + ' : ' + ERROR_MESSAGE() <br />
&nbsp; END CATCH <br />
&nbsp; <br />
&nbsp; INSERT &nbsp;@instance_database_file_space <br />
&nbsp; SELECT &nbsp;@database_name <br />
&nbsp; &nbsp; , file_logical_name <br />
&nbsp; &nbsp; , file_physical_name <br />
&nbsp; &nbsp; , file_growth <br />
&nbsp; &nbsp; , file_size_MB <br />
&nbsp; &nbsp; , file_used_space_MB <br />
&nbsp; &nbsp; , file_size_MB - file_used_space_MB AS file_free_space_MB <br />
&nbsp; &nbsp; , CAST((CAST(file_used_space_MB AS numeric(14, 2)) / file_size_MB) * 100 AS numeric(14, 2)) AS file_used_space_percent <br />
&nbsp; &nbsp; , CAST((CAST(file_size_MB - file_used_space_MB AS numeric(14, 2)) / file_size_MB) * 100 AS numeric(14, 2)) AS file_free_space_percent <br />
&nbsp; FROM &nbsp;@database_file_space <br />
&nbsp; <br />
&nbsp; FETCH NEXT FROM db_cur INTO @database_name <br />
END <br />
CLOSE db_cur <br />
DEALLOCATE db_cur <br />
&nbsp;<br />
SELECT &nbsp;* <br />
FROM &nbsp;@instance_database_file_space</div></td></tr></tbody></table></div>
<p>Il arrive que la procédure stockée système sp_executeSQL ne soit pas trouvée dans la base de données.<br />
Quand tel est le cas, la liste des bases de données est affichée dans la console de SSMS.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Nomination MVP</title>
		<link>https://blog.developpez.com/elsuket/p8139/moteur-de-base-de-donnees-sql-server/non-documente/nomination_mvp_1</link>
		<comments>https://blog.developpez.com/elsuket/p8139/moteur-de-base-de-donnees-sql-server/non-documente/nomination_mvp_1#comments</comments>
		<pubDate>Thu, 01 Oct 2009 21:52:02 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[Non documenté]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je viens d&#8217;être nominé MVP SQL Server, et je souhaite associer à ce titre, et remercier toutes les personnes qui maintiennent ce site, et qui participent aux forums. Je tiens à remercier plus particulièrement SQLPro qui m&#8217;a parrainé pour l&#8217;obtention &#8230; <a href="https://blog.developpez.com/elsuket/p8139/moteur-de-base-de-donnees-sql-server/non-documente/nomination_mvp_1">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Je viens d&rsquo;être nominé MVP SQL Server, et je souhaite associer à ce titre, et remercier toutes les personnes qui maintiennent ce site, et qui participent aux forums.</p>
<p>Je tiens à remercier plus particulièrement <a href="http://sqlpro.developpez.com/">SQLPro</a> qui m&rsquo;a parrainé pour l&rsquo;obtention de ce titre.</p>
<p>Je continuerai à contribuer à ce forum aussi fidèlement que je le fais depuis deux ans, tout simplement parce que cela me fait plaisir, et en me concentrant plus sur la publication d&rsquo;articles complets.</p>
<p>@++ <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Les dangers de la vérification de l&#8217;intégrité des données : la commande DBCC CHECKDB</title>
		<link>https://blog.developpez.com/elsuket/p8075/snippets/les_dangers_de_la_verification_de_l_inte</link>
		<comments>https://blog.developpez.com/elsuket/p8075/snippets/les_dangers_de_la_verification_de_l_inte#comments</comments>
		<pubDate>Thu, 17 Sep 2009 21:16:20 +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>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[La plupart du temps, lorsqu&#8217;on pose la question à des personnes qui débutent sous SQL Server, la réponse à la question : &#171;&#160;comment faites-vous pour résoudre une erreur de page déchirée ou de somme de contrôle &#171;&#160;, la réponse est &#8230; <a href="https://blog.developpez.com/elsuket/p8075/snippets/les_dangers_de_la_verification_de_l_inte">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>La plupart du temps, lorsqu&rsquo;on pose la question à des personnes qui débutent sous SQL Server, la réponse à la question : &laquo;&nbsp;comment faites-vous pour résoudre une erreur de page déchirée ou de somme de contrôle &laquo;&nbsp;, la réponse est bien souvent : &laquo;&nbsp;j&rsquo;utilise la commande DBCC CHECKDB avec l&rsquo;option REPAIR_ALLOW_DATA_LOSS&nbsp;&raquo; &#8230;</p>
<p>Et là, c&rsquo;est le drame, car il existe avant cette options bien d&rsquo;autres solutions.</p>
<p>Comme vous allez le voir, l&rsquo;option REPAIR_ALLOW_DATA_LOSS est une option à utiliser en dernier recours, tellement les dégâts qu&rsquo;elle peut causer sont dangereux &#8230;<br />
<span id="more-86"></span></p>
<p>Comment, dès lors, utiliser la commande DBCC CHECKDB, dont l&rsquo;utilité n&rsquo;est ici pas remise en cause, bien au contraire !<br />
Si vous avez choisi la bonne stratégie de sauvegarde suivant le métier qui fait vivre la base de données, vous devez en plus effectuer, au pire par abus de conscience, un contrôle d&rsquo;intégrité, à une fréquence adaptée elle aussi au métier de l&rsquo;entreprise.<br />
Pour une base de données utilisée qui doit être hautement disponible, on peut préférer par exemple vérifier l&rsquo;intégrité de celle-ci tous les jours à l&rsquo;aide de l&rsquo;instruction suivante :</p>
<p><code class="codecolorer text default"><span class="text">DBCC CHECKDB ('maBD') WITH NO_INFOMSGS</span></code></p>
<p>L&rsquo;option <code class="codecolorer text default"><span class="text">WITH NO_INFOMSGS</span></code> ne montre pas tous les messages d&rsquo;information qui sont normalement retournées sans cette option (nombre de pages vérifiées par table, &#8230;).<br />
En revanche, on verra toujours les erreurs apparaître.<br />
Il sera donc pratique de faire exécuter cela par un job à une heure de faible activité sur la base de données, et d&rsquo;adjoindre au job un fichier de sortie pour pouvoir consulter <em>a posteriori</em> ce fichier.</p>
<p>Comme cette option peut consommer une quantité de ressources système élevée, on peut tout à fait se rabattre sur :</p>
<p><code class="codecolorer text default"><span class="text">DBCC CHECKDB ('maBD') WITH PHYSICAL_ONLY, NO_INFOMSGS</span></code></p>
<p>Cette instruction permet de ne vérifier les structures sur disque, sans scruter les structures logiques internes aux pages de la base de données.</p>
<p><strong>Revenons à nos moutons : nous avons détecté un problème d&rsquo;intégrité dans la base de données, et maintenant, que fait-on ?</strong></p>
<p>Si, comme nous l&rsquo;avons vu un peu plus haut, nous avons choisi la bonne stratégie de sauvegarde, alors nous sommes sauvés.<br />
Restaurer une base de données corrompue est de loin la meilleure solution à employer pour passer outre une corruption de données, mais il existe encore, avant de prendre cette décision qui peut être lourde de conséquences dans certains contextes, bien d&rsquo;autres possibilités.<br />
Voyons à quoi ressemble une erreur de corruption de page :</p>
<blockquote><p>Msg 8928, Level 16, State 1, Line 1<br />
Object ID 2078435228, index ID 0, partition ID 72342401522583797, alloc unit ID 72385201253561693 (type In-row data): Page (1:62418) could not be processed.  See other errors for details.<br />
Msg 8939, Level 16, State 98, Line 1<br />
Table error: Object ID 2078435228, index ID 0, partition ID 72342401522583797, alloc unit ID 72385201253561693 (type In-row data), page (1:62418). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed.<br />
CHECKDB found 0 allocation errors and 2 consistency errors in table &lsquo;elsuket&rsquo; (object ID 2078435228).<br />
CHECKDB found 0 allocation errors and 2 consistency errors in database &lsquo;elsuket&rsquo;.<br />
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (ELSUKET).</p></blockquote>
<p>Comme on le voit, la page corrompue nous est précisée.<br />
Il serait avantageux de savoir à quel objet appartient cette page, car :</p>
<p>&#8211; si c&rsquo;est un index non-cluster, il suffit de reconstruire celui-ci (ce n&rsquo;est pas le cas avec un index cluster)<br />
&#8211; si c&rsquo;est un autre type d&rsquo;objet, nous pouvons utiliser l&rsquo;option PAGE de l&rsquo;instruction RESTORE DATABASE.</p>
<p>Notons que cette dernière possibilité n&rsquo;est possible que dans le mode de restauration FULL.<br />
Examinons maintenant la page qui est corrompue.<br />
Malheureusement cela nécessite de connaître des drapeaux de trace et instructions qui ne sont pas documentés :</p>
<div class="codecolorer-container text 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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">DBCC TRACEON (3604, -1) <br />
GO <br />
DBCC PAGE('ELSUKET', 1, 62418, 3) <br />
GO</div></td></tr></tbody></table></div>
<p>Le drapeau de trace 3604 est utilisé ici pour remonter les traces d&rsquo;exécution de toute commande DBCC au client de la session de l&rsquo;utilisateur.</p>
<p>La commande DBCC PAGE est ici spécifiée comme suit :</p>
<p>&#8211; &lsquo;ELSUKET&rsquo; est le nom de la base de données,<br />
&#8211; 1 est le numéro de fichier (c&rsquo;est le même numéro que celui qui précède le numéro de page dans le résultat de la commande DBCC CHECKDB )<br />
&#8211; 62418 est le numéro de page<br />
&#8211; 3 est l&rsquo;option de suivi de scrutation des pages : on aura l&rsquo;en-tête de buffer, l&rsquo;en-tête de page, chaque ligne de données que stocke la page, la table des offsets de lignes.</p>
<p>Dans le listing, nous trouverons des repères nommés <em>MetaData</em>, et nous pourrons trouver, par exemple :</p>
<div class="codecolorer-container text 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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">MetaData: AllocUnitId = 72385201253561693 &nbsp;<br />
MetaData: PartitionId = 72342401522583797 <br />
MetaData: ObjectId = 2078435228 <br />
Metadata: IndexId = 1</div></td></tr></tbody></table></div>
<p>C&rsquo;est plus précisément <em>Metadata: IndexId</em> qui nous intéresse ici :</p>
<p>&#8211; S&rsquo;il est plus grand que 1, il s&rsquo;agit d&rsquo;une index non-cluster, donc il suffit de le supprimer et de la reconstruire<br />
&#8211; S&rsquo;il vaut 0 ou 1, nous devons résoudre le défaut d&rsquo;intégrité de façon plus complexe.</p>
<p>=> <strong>Restauration de pages à partir d&rsquo;une sauvegarde de la base de données</strong></p>
<p>On peut tout simplement restaurer la page concernée à partir de notre sauvegarde, en ayant au préalable sauvegardé la queue du fichier du journal des transactions, c&rsquo;est à dire le journal des transactions courant.<br />
Il faut alors restaurer la dernière sauvegarde complète, puis l&rsquo;éventuelle dernière sauvegarde différentielle, puis les journaux de transaction dans l&rsquo;ordre où ils ont été sauvegardés, pour enfin restaurer la queue de celui-ci, mais avec l&rsquo;option <code class="codecolorer text default"><span class="text">NORECOVERY</span></code> de l&rsquo;instruction <code class="codecolorer text default"><span class="text">RESTORE</span></code>.</p>
<p>Si peu de pages sont corrompues, on peut alors décider de les restaurer une à une à partir de la base de données fraîchement restaurée :</p>
<div class="codecolorer-container text 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="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">RESTORE DATABASE ELSUKET PAGE = '1:62418' <br />
FROM DISK = 'C:\ELSUKET.bak' <br />
WITH NORECOVERY</div></td></tr></tbody></table></div>
<p>Rappelons que cela n&rsquo;est possible que dans le mode de restauration FULL.<br />
Si la base de données utilise le mode de restauration SIMPLE, alors on devra restaurer la base de données à partir de la dernière sauvegarde complète et des éventuelles sauvegardes différentielles, mais on perdra les données qui ont été ajoutées ou modifiées entre l&rsquo;heure de terminaison des sauvegardes et maintenant.</p>
<p>=> <strong>La réparation automatique, et ses dangers</strong></p>
<p>Il est important, avant de choisir parmi les options de réparation de corruption, l&rsquo;option qui convient :</p>
<p>&#8211; REPAIR_ALLOW_DATA_LOSS<br />
&#8211; REPAIR_REBUILD</p>
<p>Si nous revenons à la trace produite par l&rsquo;exécution de la commande DBCC CHECKDB, on trouve dans celle-ci le niveau de correction à adopter :</p>
<blockquote><p>repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (ELSUKET)</p></blockquote>
<p>Si l&rsquo;option proposée est REPAIR_REBUILD, vous l&rsquo;avez échappé belle : il n&rsquo;y aucun risque de perte de données : il s&rsquo;agira pour le moteur de base de données de réparer des clés manquantes dans les index non-cluster, ou bien de reconstruire un index.</p>
<p>Si en revanche vous avez, comme ici, l&rsquo;option REPAIR_ALLOW_DATA_LOSS, comme le dit si bien cette options, il est possible que vous perdiez des données (d&rsquo;où l&rsquo;importance des sauvegardes).<br />
En effet, cette commande peut par exemple supprimer la page et la ré-allouer pour faire &laquo;&nbsp;croire&nbsp;&raquo; que celle-ci n&rsquo;a en fait jamais existé&#8230;</p>
<p><strong>En conclusion : bichonnez vos sauvegardes !</strong></p>
<p>Pour aller plus loin, je vous propose cet article de Mikedavem : <a href="La vérification d'intégrité et les problématiques liées aux VLDB">La vérification d&rsquo;intégrité et les problématiques liées aux VLDB</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connaître l&#8217;état d&#8217;un service : xp_servicecontrol</title>
		<link>https://blog.developpez.com/elsuket/p7806/snippets/connaitre_l_etat_d_un_service_xp_service</link>
		<comments>https://blog.developpez.com/elsuket/p7806/snippets/connaitre_l_etat_d_un_service_xp_service#comments</comments>
		<pubDate>Sat, 27 Jun 2009 06:32:18 +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>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Comment connaître simplement l&#8217;état d&#8217;un service ? Est-il possible d&#8217;arrêter et de démarrer un service avec une requête ? La procédure stockée système étendue non documentée xp_servicecontrol permet de connaître l&#8217;état d&#8217;un service : EXEC master.dbo.xp_servicecontrol 'QUERYSTATE', 'MSSQLServer' Retourne bien &#8230; <a href="https://blog.developpez.com/elsuket/p7806/snippets/connaitre_l_etat_d_un_service_xp_service">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Comment connaître simplement l&rsquo;état d&rsquo;un service ?<br />
Est-il possible d&rsquo;arrêter et de démarrer un service avec une requête ?</p>
<p><span id="more-48"></span></p>
<p>La procédure stockée système étendue <strong>non documentée</strong> xp_servicecontrol permet de connaître l&rsquo;état d&rsquo;un service :</p>
<p><code class="codecolorer text default"><span class="text">EXEC master.dbo.xp_servicecontrol 'QUERYSTATE', 'MSSQLServer'</span></code></p>
<p>Retourne bien sûr :</p>
<p><img src="http://blog.developpez.com/media/serviceSQLServer.PNG" width="564" height="139" alt="" /></p>
<p>mais peut retourner les états suivants :</p>
<div class="codecolorer-container text 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="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">- &quot;Stopped.&quot; <br />
- &quot;Running.&quot; <br />
- &quot;Stopping.&quot; <br />
- &quot;Starting.&quot; <br />
- &quot;Unknown.&quot; <br />
- &quot;ErrorRetrieving.&quot;</div></td></tr></tbody></table></div>
<p>On peut aussi démarrer un service :</p>
<p><code class="codecolorer text default"><span class="text">EXEC master.dbo.xp_servicecontrol 'START', 'MSSQLServer'</span></code></p>
<p>ou encore l&rsquo;arrêter : </p>
<p><code class="codecolorer text default"><span class="text">EXEC master.dbo.xp_servicecontrol 'STOP', 'MSSQLServer'</span></code></p>
<p>Il peut être pratique de connaître l&rsquo;état de services par ce biais, lorsque l&rsquo;on administre une instance de SQL Server avec l&rsquo;utilitaire en ligne de commande <a href="http://msdn.microsoft.com/fr-fr/library/ms162773(SQL.90).aspx">SQLCMD</a> (ancien OSQL) et une connexion <a href="http://msdn.microsoft.com/fr-fr/library/ms189595(SQL.90).aspx">DAC</a>, ou encore encapsuler ce résultat dans un rapport SSRS sur l&rsquo;état d&rsquo;un serveur et de ses applications &#8230;</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
