<?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>David Barbarin &#187; SQL Server 2012</title>
	<atom:link href="https://blog.developpez.com/mikedavem/ptag/sql-server-2012/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/mikedavem</link>
	<description>MVP DataPlatform - MCM SQL Server</description>
	<lastBuildDate>Thu, 09 Sep 2021 21:19:50 +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>Columnstore index rebuild cannot start</title>
		<link>https://blog.developpez.com/mikedavem/p13068/sql-server-2012/columnstore-index-rebuild-cannot-start</link>
		<comments>https://blog.developpez.com/mikedavem/p13068/sql-server-2012/columnstore-index-rebuild-cannot-start#comments</comments>
		<pubDate>Sat, 09 Jul 2016 07:31:30 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[columnstore]]></category>
		<category><![CDATA[datawarehouse]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=1220</guid>
		<description><![CDATA[Il y a quelques semaines,j&#8217;étais en charge de migrer une infrastructure Datawarehouse sur une version plus récente de SQL Server (passage de 2005 à 2012). Après discussion avec le client nous avons décidé de profiter des nouvelles fonctionnalités offertes par &#8230; <a href="https://blog.developpez.com/mikedavem/p13068/sql-server-2012/columnstore-index-rebuild-cannot-start">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Il y a quelques semaines,j&rsquo;étais en charge de migrer une infrastructure Datawarehouse sur une version plus récente de SQL Server (passage de 2005 à 2012). Après discussion avec le client nous avons décidé de profiter des nouvelles fonctionnalités offertes par 2012 et en particulier des index columnstore qui pouvaient potentiellement améliorer les performances de Reporting dans le contexte présent &#8230;</p>
<p>&gt; <a href="http://blog.dbi-services.com/columnstore-index-rebuild-cannot-start/" target="_blank">Lire la suite</a> (en anglais)</p>
<p>David Barbarin<br />
MVP &amp; MCM SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server AlwaysOn : Consid&#233;rations sur l&#8217;ajout d&#8217;un fichier de bases de donn&#233;es</title>
		<link>https://blog.developpez.com/mikedavem/p12435/sql-server-2012/sql-server-always-considrations-sur-lajout-dun-fichier-de-bases-de-donnes</link>
		<comments>https://blog.developpez.com/mikedavem/p12435/sql-server-2012/sql-server-always-considrations-sur-lajout-dun-fichier-de-bases-de-donnes#comments</comments>
		<pubDate>Sat, 18 Jan 2014 09:19:52 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[SQL Server 2014]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=856</guid>
		<description><![CDATA[Ce billet fait suite à quelques discussions échangés lors d’un cours sur SQL Server AlwaysOn que j’ai pu donner ces derniers temps. Une des parties du cours ciblaient certaines tâches qu’un administrateur pouvait avoir à effectuer sur une base de &#8230; <a href="https://blog.developpez.com/mikedavem/p12435/sql-server-2012/sql-server-always-considrations-sur-lajout-dun-fichier-de-bases-de-donnes">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Ce billet fait suite à quelques discussions échangés lors d’un cours sur SQL Server AlwaysOn que j’ai pu donner ces derniers temps. Une des parties du cours ciblaient certaines tâches qu’un administrateur pouvait avoir à effectuer sur une base de données concernée par un groupe de disponibilité dans un environnement complètement asymétrique. Je tiens à dire tout de suite que Microsoft conseille d’avoir des environnements similaires entre réplicas pour une administration plus simple. Maintenant que cela est dit, prenons une situation où un administrateur de bases de données doive ajouter un fichier de données supplémentaire à une base de données faisant parti d’un groupe de disponibilité dont l’architecture en place est la suivante :</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb.png" width="728" height="231" /></a> </p>
<p>Une architecture avec 4 réplicas. Je précise de suite que cette architecture est tout à fait fictive et que le placement de fichier pas forcément optimale pour une telle architecture mais le principe est de bien comprendre les problèmes qu’impliquent une telle asymétrie dans notre architecture. La convention de placement de fichier suivante : &lt;LETTER&gt;:\&lt;SQLSERVER&gt;\&lt;INSTANCE&gt;\&lt;TYPEF_FICHIER&gt;. Pour l’instance SQL141\IRONMAN pour les fichiers de données qui seront hébergés sur le disque E: nous aurons le placement suivant E:\SQLSERVER\IRONMAN\DATA. </p>
<p>L’ajout du fichier doit se faire en respectant la convention de placement en place. La question à 1 euros est-ce que je peux ajouter un fichier de données sans perturber l’architecture en place ? </p>
<p>…….</p>
<p>….</p>
<p>.</p>
<p>Pour le savoir rendez-vous dans la suite de ce billet !</p>
<p>La base de données concernée se nomme AGDB avec le schéma de répartition suivant :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image1.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb1.png" width="693" height="170" /></a>&#160; </p>
<p>Côté groupe de disponibilité voici ce que nous avons :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image2.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb2.png" width="562" height="424" /></a> </p>
<p>&#160;</p>
<p>Ajoutons maintenant un fichier supplémentaire …</p>
</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image3.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb3.png" width="711" height="116" /></a> </p>
<p>et voilà le résultat côté groupe de disponibilité :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image4.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb4.png" width="559" height="417" /></a> </p>
<p>… et côté instance :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image5.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb5.png" width="531" height="181" /></a> </p>
<p>&#160;</p>
<p>Comme dirait l’autre, ça c’est fait !!! Bon reprenons nos esprits et regardons un peu ce qui se passe dans le journal des erreurs SQL Server d’une des instances SQL Server concernées :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image6.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb6.png" width="715" height="266" /></a> </p>
<p>On voit rapidement que le problème est la convention de placement des fichiers de données. En effet SQL Server tente de propager la création de fichier depuis le primaire vers les secondaires qui n’ont pas du tout les mêmes chemins de fichiers. Une erreur est levée et tant que le problème n’est pas réglé la réplication est suspendue. </p>
<p>Ok … que doit-on faire ici ? Réinitialiser le tout en supprimant la base de données AGDB du groupe de disponibilité et repartir d’une nouvelle sauvegarde en prenant soin de changer les chemins de fichiers ? Possible mais cela veut dire qu’il faut tout rependre … avec des bases de données de petite taille c’est jouable mais imaginez seulement une base de données de plus d’une centaine de Go, le tout multiplié par 3 car nous avons 3 réplicas secondaires … Une autre solution ?&#160; En fait oui .. on peut récupérer une sauvegarde de journal et la restaurer sur chacun des réplicas. Mais comment faire car il n’est pas possible d’appliquer des sauvegardes sur une base de données d’un groupe de disponibilités sur un réplica secondaire. En fait il faut supprimer la base de données du groupe de disponibilité sur chaque secondaire de la manière suivante :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image7.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb7.png" width="352" height="239" /></a> </p>
<p>Il se peut que des messages d’erreurs apparaissent stipulant un problème de création de fichiers sur un mauvais chemin mais on peut les ignorer. L’important est de pouvoir retrouver nos bases de données sur les réplicas secondaires en mode de restauration :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image8.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb8.png" width="474" height="444" /></a> </p>
<p>On peut maintenant appliquer une restauration du journal effectuée après avoir rencontré notre problème en veillant à restaurer notre fichier (AGDB2) qui pose problème vers le bon chemin :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image9.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb9.png" width="556" height="204" /></a> </p>
<p>et en ajoutant à nouveau la base de données au groupe de disponibilité pour le réplica concerné </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image10.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb10.png" width="590" height="74" /></a> </p>
<p>… ainsi de suite pour les autres réplicas et le tour est joué :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image11.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb11.png" width="627" height="538" /></a> </p>
<p>… avec une répartition qui respecte la convention en vigueur :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2014/01/image12.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2014/01/image_thumb12.png" width="548" height="244" /></a> </p>
<p>Bien qu’il est possible de revenir à une situation pérenne plus ou moins facilement cela reste à mon avis fortement déconseillé car ce genre de configuration ne peut que compliquer l’administration courante d’un administrateur de bases de données. Ici nous avons ajouté un fichier de données mais que se passerait-il si nous devions ajouter en urgence un fichier journal en urgence dans un environnement SQL Server AlwaysOn complètement asymétrique ? …</p>
<p>David BARBARIN (Mikedavem)    <br />MVP et MCM SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cas d&#8217;utilisation d&#8217;un groupe de disponibilit&#233; multi-listeners</title>
		<link>https://blog.developpez.com/mikedavem/p12376/sql-server-2012/cas-dutilisation-dun-groupe-de-disponibilit-multi-listeners</link>
		<comments>https://blog.developpez.com/mikedavem/p12376/sql-server-2012/cas-dutilisation-dun-groupe-de-disponibilit-multi-listeners#comments</comments>
		<pubDate>Fri, 06 Dec 2013 15:02:21 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[haute disponibilité]]></category>
		<category><![CDATA[high availability]]></category>
		<category><![CDATA[SQL Server 14]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=747</guid>
		<description><![CDATA[Pour ceux qui ont déjà installé SQL Server AlwaysOn vous avez pu sans doute remarquer qu’il est possible d’avoir uniquement un seul listener pour un groupe de disponibilité. Sur le principe cela n’est pas gênant dans la plupart des configurations &#8230; <a href="https://blog.developpez.com/mikedavem/p12376/sql-server-2012/cas-dutilisation-dun-groupe-de-disponibilit-multi-listeners">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Pour ceux qui ont déjà installé SQL Server AlwaysOn vous avez pu sans doute remarquer qu’il est possible d’avoir uniquement un seul listener pour un groupe de disponibilité. Sur le principe cela n’est pas gênant dans la plupart des configurations mais comment dans le cas où un client cherche absolument à décomissionner un serveur SQL avec une multitude d’application et qu’il est difficile de changer le nom de serveur dans la chaîne de connexion de ces applications. </p>
<p>Prenons un cas concret que j’ai pu rencontrer chez un client lors d’une migration et qui aurait pu poser problème lors du passage à une architecture haute disponibilité SQL Server AlwaysOn :</p>
<ul>
<li>Plusieurs applications installées sur une centaine de postes clients depuis longtemps et qui ne sont plus supportées par les différents éditeurs La chaîne de connexion des applications est codée en dur (pas de chance …) et l’intervention des différents consultants peut coûter cher d’autant plus que ces derniers proposent de mettre à jour l’application pour résoudre le problème. hors le client n’a pas forcément le budget pour cela car il n’a pas pu anticiper ce problème … bref le changement du nom de serveur pour cette application n’est pas envisageable et pourtant il nous faut migrer les bases de données pour décomissionner au plus vite notre ancien serveur SQL vers une infrastructure AlwaysOn </li>
</ul>
<p>Quelles solutions avons-nous à disposition ?</p>
<p>&#8211;&gt; Nous pouvons créer un listener avec l’ancien nom du serveur SQL et son ancienne adresse IP mais deux problèmes se posent :</p>
<ul>
<li>le but est à l’origine est de pouvoir décomissionner l’ancien nom de serveur qui n’est plus conforme à la nouvelle nomenclature générale de nommage et doit être absolument changé dès que possible. </li>
<li>le planning de migration nous impose de migrer les applications en douceur et nous impose de garder de migrer les applications facilement modifiables au départ et garder les applications statiques pour la fin. Cette option n’est donc pas envisageable. </li>
</ul>
<p>&#8211;&gt; Nous pouvons utiliser un alias CNAME avec l’ancien nom de serveur qui pointe vers le nouveau listener. Cela suppose que notre ancien serveur soit complètement décomissionné pour pouvoir utiliser notre nouveau listener mais notre planning de migration nous impose encore une fois de garder l’ancien serveur pendant la phase de migration jusqu’à la fin.&#160; </p>
<p>Dans ce cas cas comment faire ? He bien une solution (parmi quelques autres) serait de créer un second listener pour notre groupe de disponibilité. Comment ? En fait l’astuce consiste à passer par le gestionnaire de cluster et de créer un nouveau point d’accès client (Client Access Point) pour le rôle associé au groupe de disponibilité concerné avec un nom réseau et une adresse IP :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point.jpg"><img title="aag_new_cllient_access_point" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="aag_new_cllient_access_point" src="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point_thumb.jpg" width="577" height="472" /></a> </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point_2.jpg"><img title="aag_new_cllient_access_point_2" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="aag_new_cllient_access_point_2" src="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point_2_thumb.jpg" width="574" height="462" /></a> </p>
<p>Une fois la ressource associé au nouveau point d’accès client créé il suffit de le mettre en ligne et de configurer les dépendances associées au groupe de disponibilité. L’utilisation d’une logique de dépendance à base de AND est possible mais il est préférable d’utiliser une logique de dépendance à base de OR pour garder le groupe de disponibilité en ligne autant que possible. </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point_3.jpg"><img title="aag_new_cllient_access_point_3" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="aag_new_cllient_access_point_3" src="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point_3_thumb.jpg" width="574" height="481" /></a> </p>
<p>Une fois le tout configuré on peut avoir apparaître un nouveau listener dans SQL Server Management Studio.</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point_4.jpg"><img title="aag_new_cllient_access_point_4" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="aag_new_cllient_access_point_4" src="http://blog.developpez.com/mikedavem/files/2013/12/aag_new_cllient_access_point_4_thumb.jpg" width="405" height="402" /></a> </p>
<p>L’utilisation de la vue système <strong><em>sys.availability_group_listeners</em></strong> nous montre également que le groupe <em>aag</em> possède bien 2 listeners :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/image.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/12/image_thumb.png" width="531" height="310" /></a> </p>
<p>La colonne <em><strong>is_conformant</strong></em> indique que le listener peut être managé depuis SQL Server. On voit également que pour le moment le listener n’est pas encore exploitable car aucun port d’écoute est configuré. Puisque le listener est configurable depuis SQL Server nous pouvons changer facilement son port depuis SQL Server Management Studio.</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/image1.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/12/image_thumb1.png" width="554" height="201" /></a></p>
<p>…</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/image2.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/12/image_thumb2.png" width="553" height="339" /></a></p>
<p>Un test de connexion et le tout fonctionne !!</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/12/image3.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/12/image_thumb3.png" width="546" height="116" /></a>&#160;</p>
<p>&#160;</p>
<p>Merci à <a href="http://blogs.msdn.com/401589/ProfileUrlRedirect.ashx">Qiang Wang</a> pour l’astruce</p>
<p>David BARBARIN (Mikedavem)    <br />MVP et MCM SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Saturdays 2013 &#224; Paris : les slides</title>
		<link>https://blog.developpez.com/mikedavem/p12265/sql-server-2008/sql-saturdays-2013-paris-les-slides</link>
		<comments>https://blog.developpez.com/mikedavem/p12265/sql-server-2008/sql-saturdays-2013-paris-les-slides#comments</comments>
		<pubDate>Mon, 07 Oct 2013 14:43:19 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[Evénements]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2008 R2]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[événements étendues]]></category>
		<category><![CDATA[Extended events]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Saturdays]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[troubleshooting]]></category>
		<category><![CDATA[XE]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=715</guid>
		<description><![CDATA[Comme promis voici les slides de ma session sur les événements étendus. Malheureusement je n’ai pas pu effectuer toutes les démonstrations que je voulais .. eh oui il faut bien commencer par expliquer comment fonctionne les événements étendus et cela &#8230; <a href="https://blog.developpez.com/mikedavem/p12265/sql-server-2008/sql-saturdays-2013-paris-les-slides">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Comme promis voici les <a href="https://skydrive.live.com/?cid=624fd44664395fc5#cid=624FD44664395FC5&amp;id=624FD44664395FC5%214792">slides</a> de ma session sur les événements étendus. Malheureusement je n’ai pas pu effectuer toutes les démonstrations que je voulais .. eh oui il faut bien commencer par expliquer comment fonctionne les événements étendus et cela m’a pris un peu plus de temps que prévu <img src="https://blog.developpez.com/mikedavem/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley" /> . Mais ce n’est que partie remise, je garde cette partie pour une session uniquement orientée démonstration. J’espère pouvoir vous la présenter rapidement.</p>
<p>Merci aux personnes qui ont voulu assister à ma présentation et de assister de manière générale à ce premier SQL Saturdays&#160; Paris. Ce fut un bon moment d’échange et de rencontres !</p>
<p>David BARBARIN (Mikedavem)    <br />MVP SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Analyse des probl&#232;mes de basculement survenus sur une infrastructure SQL Server 2012 AlwaysOn</title>
		<link>https://blog.developpez.com/mikedavem/p12209/sql-server-2012/analyse-des-problmes-de-basculement-survenus-sur-une-infrastructure-sql-server-2012-alwayson</link>
		<comments>https://blog.developpez.com/mikedavem/p12209/sql-server-2012/analyse-des-problmes-de-basculement-survenus-sur-une-infrastructure-sql-server-2012-alwayson#comments</comments>
		<pubDate>Mon, 02 Sep 2013 14:51:51 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[haute disponibilité]]></category>
		<category><![CDATA[high availability]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=702</guid>
		<description><![CDATA[Récemment j&#8217;ai eu à débugger un problème client survenu sur une infrastructure haute disponibilité SQL Server 2012 AlwaysOn. Le problème était le suivant : les connexions sur le réplica primaire ont subitement&#160; cessé vers 12:25 et il n&#8217;était plus possible &#8230; <a href="https://blog.developpez.com/mikedavem/p12209/sql-server-2012/analyse-des-problmes-de-basculement-survenus-sur-une-infrastructure-sql-server-2012-alwayson">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Récemment j&rsquo;ai eu à débugger un problème client survenu sur une infrastructure haute disponibilité SQL Server 2012 AlwaysOn. Le problème était le suivant : les connexions sur le réplica primaire ont subitement&#160; cessé vers 12:25 et il n&rsquo;était plus possible de s&rsquo;y connecter. Le client, dans la précipitation, a visiblement essayer de basculer le groupe de disponibilité sur le réplica secondaire mais visiblement sans succès. Le but de mon intervention était d&rsquo;expliquer à mon client pourquoi il n&rsquo;était plus possible de se connecter aux réplicas et pourquoi le basculement n&rsquo;a pas eu l&rsquo;effet escompté.&#160; </p>
<p>Par où commencer ? Analyser un problème sur une infrastructure AlwaysOn n&rsquo;est pas une mince affaire en réalité. SQL Server 2012 AlwaysOn fonctionne sur une première couche basique de cluster à basculement au niveau du système d&rsquo;exploitation et une couche applicative au niveau SQL Server. Lorsqu&rsquo;un problème survient cela peut donc se produire sur l&rsquo;une des 2 couches voir sur les 2 couches simultanément. </p>
<p>&#160;</p>
<p>Les connexions se sont arrêtées subitement </p>
<p>Commençons dans l&rsquo;ordre des problèmes. Dans le cas présent les connexions s&rsquo;effectuent directement en utilisant le listener du groupe de disponibilité concerné. Cela peut vouloir dire que le problème se situe à ce niveau mais aussi au niveau de l&rsquo;instance SQL Server. Pour cela nous avons à disposition :</p>
<ul>
<li>les logs Windows ou du cluster à basculement Windows </li>
<li>les logs SQL Server </li>
<li>Les fichiers de diagnostics fournis par la procédure stockée sp_server_diagnostics </li>
</ul>
<p>&#160;</p>
<p>D&rsquo;autres outils peuvent nous aider comme les sessions d&rsquo;événements étendus AlwaysOn mais dans notre cas nous n&rsquo;en aurons pas forcément besoin. J&rsquo;essayerai d&rsquo;effectuer un billet sur le sujet. Revenons à notre sujet : les logs Windows nous révèlent ceci :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_1.gif"><img title="billet_alwayson_diag_1" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_1" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_1_thumb.gif" width="982" height="295" /></a></p>
<p>&#160;</p>
<p>On voit ici une série d&rsquo;erreur à partir de 12:20 relatives au cluster Windows à basculement :</p>
<ul>
<li>Event ID 1562 : Cette erreur décrit un problème au niveau du témoin fichier partagé utilisé dans la configuration AlwaysOn qui nous concerné (2 nœuds + 1 FSW). Le partage servant comme élément de vote pour le quorum n&rsquo;est plus accessible pour une raison non connue </li>
<li>Event ID 1069 : Cette erreur indique simplement qu&rsquo;il existe un problème au niveau du groupe de ressource &quot;Cluster Group&quot;. Dans notre cas cette erreur est provoquée par le partage qui n&rsquo;est plus accessible. </li>
<li>Event ID 1564 : Cette erreur nous informe que le partage de fichier ne pourra pas jouer son rôle d&rsquo;arbitrage en cas de défaillance d&rsquo;un des nœuds de la topologie. En effet dans notre configuration le FSW n&rsquo;étant plus disponible la perte d&rsquo;un nœud de cluster supplémentaire serait fatale car la majorité ne pourrait pas être atteinte et le quorum ne pourrait pas être formé. </li>
</ul>
<p>A ce stade on peut simplement conclure que le partage de fichier utilisé en tant que vote pour le quorum n&rsquo;est plus accessible.</p>
<p>&#160;</p>
<p>On retrouve également des erreurs de type NETLOGON qui nous en dit plus sur la nature de notre problème :</p>
<ul>
<li>Event ID 5783 : Cette erreur indique qu&rsquo;un problème de connexion aux serveurs DNS ou aux contrôleurs de domaine est survenu. Un redémarrage des serveurs ? Un problème de connexion de réseau entre le réplica primaire et les serveurs DNS ou DC ? Des serveurs ne pouvant plus répondre à cause d&rsquo;un engorgement des demandes ? Une intervention sur l&rsquo;infrastructure virtuelle sous-jacente ? Difficile à dire à ce stade &#8230; Ce qui est certain est que la résolution de nom ne pouvait pas s&rsquo;effectuer correctement vers le partage de fichier dans ce cas, ce qui peut expliquer que le FSW n&rsquo;était plus disponible à ce moment là </li>
</ul>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_13.gif"><img title="billet_alwayson_diag_13" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_13" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_13_thumb.gif" width="896" height="60" /></a></p>
<p>&#160;</p>
<p>L&rsquo;analyse des logs SQL nous dévoilent ceci :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_2.gif"><img title="billet_alwayson_diag_2" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_2" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_2_thumb.gif" width="916" height="187" /></a></p>
<p>&#160;</p>
<p>Des informations intéressantes ici qui confirment bel et bien qu&rsquo;un problème d&rsquo;infrastructure a bien eu lieu avec une liaison à un contrôleur de domaine défaillante (No authority could be contacted for authentication).</p>
<p>L&rsquo;erreur Windows nous spécifie la même chose : </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_14.gif"><img title="billet_alwayson_diag_14" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_14" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_14_thumb.gif" width="658" height="107" /></a></p>
<p>&#160;</p>
<p>Une autre voix d&rsquo;investigation est possible. Avec SQL Server 2012 AlwaysOn, la ressource DLL SQL Server utilisée par le cluster Windows à basculement exécute une procédure stockée sp_server_diagnostics pour déterminer l&rsquo;état de santé du réplica primaire utilisé dans une topologie AlwaysOn. Des informations détaillées sont envoyés périodiquement au travers de cette ressource et permet au cluster Windows d&rsquo;initier un basculement en fonction de ces informations et des règles de basculement associées. Toutes ces informations de diagnostics produites par la procédure stockée sp_server_diagnostics sont enregistrées par défaut dans des fichiers SQLDIAG exploitables directement par la fonction sys.fn_xe_file_target_read_file() ou directement dans SQL Server Management Studio.</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;height:450px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/@name)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Name'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/@package)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Package'</span><span style="color: #66cc66;">,</span><br />
&nbsp; xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'node_name'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Node_Name'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'instance_name'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Instance_Name'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/@timestamp)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'datetime'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Time'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'state'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'int'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'State'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'state_desc'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'State Description'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'failure_condition_level'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'int'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Failure Conditions'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'creation_time'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'datetime'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Creation Time'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'component'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Component'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'data'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Data'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'info'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'varchar(max)'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'Info'</span><span style="color: #66cc66;">,</span><br />
&nbsp;xml_data<br />
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span> <br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <br />
&nbsp;object_name <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'event'</span> &nbsp;<span style="color: #66cc66;">,</span><br />
&nbsp;<span style="color: #993333; font-weight: bold;">CONVERT</span><span style="color: #66cc66;">&#40;</span>xml<span style="color: #66cc66;">,</span>event_data<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">'xml_data'</span> &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">FROM</span> sys<span style="color: #66cc66;">.</span>fn_xe_file_target_read_file<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'C:<span style="color: #000099; font-weight: bold;">\c</span>ustomer_alwayson_issue<span style="color: #000099; font-weight: bold;">\p</span>rimary_replica<span style="color: #000099; font-weight: bold;">\*</span>.xel'</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span> <br />
<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> XEventData<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;xml_data<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">VALUE</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'(event/data[@name='</span><span style="color: #ff0000;">'creation_time'</span><span style="color: #ff0000;">']/value)[1]'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'datetime'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff0000;">'20130723 12:15:00'</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #993333; font-weight: bold;">TIME</span>;</div></div>
</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_3.gif"><img title="billet_alwayson_diag_3" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_3" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_3_thumb.gif" width="985" height="157" /></a></p>
<p>&#160;</p>
<p>On remarque ici 2 choses. La procédure stockée sp_server_diagnostics stipule que le groupe de disponibilité qui nous concerne n&rsquo;a visiblement pas de problème (premières flèches en rouge) . Les informations fournies ensuite par cette procédure stockée sont classés en catégorie (composants système, ressources, sous système disque, exécution des requêtes et autre évènements utiles notamment extraites des différents ring buffers SQL Server).</p>
<p>Concernant le composant de groupe de disponibilité :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_4.gif"><img title="billet_alwayson_diag_4" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_4" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_4_thumb.gif" width="635" height="402" /></a></p>
<p>&#160;</p>
<p>Concernant le composant Events :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_5.gif"><img title="billet_alwayson_diag_5" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_5" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_5_thumb.gif" width="928" height="526" /></a></p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_6.gif"><img title="billet_alwayson_diag_6" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_6" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_6_thumb.gif" width="908" height="280" /></a></p>
<p>&#160;</p>
<p>On retrouve ici des informations du ring buffer &quot;security error&quot; dans lequel sont enregistrés les erreurs d&rsquo;authentification. Celui-ci qui nous indique une erreur survenue lors de l&rsquo;authentification via les api utilisés par SQL Server et d&rsquo;autres informations que l&rsquo;on retrouve dans les journaux d&rsquo;erreurs Windows. Dans mon cas on retrouve une multitude d&rsquo;enregistrements de ce genre dans ce ring buffer.</p>
<p>Pour résumer, nous avons donc ici l&rsquo;origine du problème de connexion : un contrôleur de domaine ou un serveur DNS non joignable qui empêche les authentifications sur le réplica primaire. Passons maintenant à notre problème de basculement qui n&rsquo;a visiblement pas fonctionné. Après investigation, c&rsquo;est le processus de basculement manuel qui n&rsquo;a pas fonctionné via l&rsquo;interface GUI. En effet l&rsquo;interface demande une authentification vers le réplica cible avant d&rsquo;effectuer la bascule et comme le processus d&rsquo;authentification ne fonctionnait pas avec des comptes de domaine il était alors impossible à ce moment là de basculer. Le serveur SQL a donc été redémarré. On peut le confirmer ici en regardant les informations contenues dans les journaux SQL Server que le service a été arrêté suite à une demande du gestionnaire de service. </p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_7.gif"><img title="billet_alwayson_diag_7" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_7" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_7_thumb.gif" width="1062" height="429" /></a></p>
<p>&#160;</p>
<p>&#8230; Le gestionnaire de réplica démarre, attend que le service de cluster démarre correctement et démarre le réplica local. On voit que l&rsquo;état du réplica passe de NOT_AVAILABLE à RESOLVING_NORMAL</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_12.gif"><img title="billet_alwayson_diag_12" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_12" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_12_thumb.gif" width="991" height="252" /></a></p>
<p>&#160;</p>
<p>&#8230;On voit ici que le réplica local pour le groupe de disponibilité qui nous concerne se prépare à redevenir réplica primaire. L&rsquo;état du réplica passe donc de RESOLVING_NORMAL à PRIMARY_PENDING</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_8.gif"><img title="billet_alwayson_diag_8" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_8" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_8_thumb.gif" width="1069" height="183" /></a></p>
<p>&#8230; L&rsquo;écoute démarre sur le listener associé au groupe de disponibilité&#160; et le réplica passe à son état final PRIMARY_NORMAL. </p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_9.gif"><img title="billet_alwayson_diag_9" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_9" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_9_thumb.gif" width="1091" height="150" /></a></p>
<p>&#8230; Le réplica a bien redémarré mais on voit qu&rsquo;il existe toujours des problèmes de connexion sur le réplica primaire à cause d&rsquo;un problème de connexion à une autorité d&rsquo;authentification (le fameux contrôleur de domaine). </p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_10.gif"><img title="billet_alwayson_diag_10" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_10" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_10_thumb.gif" width="1093" height="173" /></a></p>
<p>&#160;</p>
<p>Pourquoi le groupe de disponibilité n&rsquo;a-t-il pas pu basculer vers notre réplica secondaire ? Les règles de basculement étaient pourtant bien paramétré avec un niveau de condition par défaut (3). Les logs du cluster Windows sur le réplica secondaire nous donne la réponse :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_11.gif"><img title="billet_alwayson_diag_11" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="billet_alwayson_diag_11" src="http://blog.developpez.com/mikedavem/files/2013/09/billet_alwayson_diag_11_thumb.gif" width="1100" height="179" /></a></p>
<p>&#160;</p>
<p>L&rsquo;event id 1254 correspond à un nombre de basculement qui a dépassé le seuil autorisé pour un groupe de ressource. Dans notre cas le groupe de ressource correspond bien à notre groupe de disponibilité. Le basculement de ce dernier était donc impossible ici. C&rsquo;est la raison pour laquelle le groupe de disponibilité a redémarré sur le réplica 1 après son redémarrage manuel.&#160; La boucle est donc bouclée !!</p>
<p>&#160;</p>
<p>Bonne investigation !</p>
<p>&#160;</p>
<p>David BARBARIN (Mikedavem)    <br />MVP SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#233;tecter un basculement automatique avec SQL Server 2012 AlwaysOn</title>
		<link>https://blog.developpez.com/mikedavem/p12169/sql-server-2012/dtecter-un-basculement-automatique-avec-sql-server-2012-alwayson</link>
		<comments>https://blog.developpez.com/mikedavem/p12169/sql-server-2012/dtecter-un-basculement-automatique-avec-sql-server-2012-alwayson#comments</comments>
		<pubDate>Thu, 08 Aug 2013 13:26:30 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[basculement]]></category>
		<category><![CDATA[failover]]></category>
		<category><![CDATA[haute disponibilité]]></category>
		<category><![CDATA[high availability]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=652</guid>
		<description><![CDATA[Après avoir installé une infrastructure SQL Server 2012 AlwaysOn, il peut être intéressant d&#8217;être alerté lorsqu&#8217;un groupe de disponibilité basculement automatiquement d&#8217;un réplica à un autre pour une raison quelconque. Alors que pour les architectures en mirrroring nous avons built-in &#8230; <a href="https://blog.developpez.com/mikedavem/p12169/sql-server-2012/dtecter-un-basculement-automatique-avec-sql-server-2012-alwayson">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Après avoir installé une infrastructure SQL Server 2012 AlwaysOn, il peut être intéressant d&rsquo;être alerté lorsqu&rsquo;un groupe de disponibilité basculement automatiquement d&rsquo;un réplica à un autre pour une raison quelconque. Alors que pour les architectures en mirrroring nous avons built-in tout ce qu&rsquo;il faut avec <a href="http://technet.microsoft.com/en-us/library/cc966392.aspx">DATABASE_MIRRORING_STATE_CHANGE</a> et des états en sortie qui nous permettent de savoir si un basculement manuel ou automatique a été effectué, c&rsquo;est une autre paire de manche avec les infrastructures AlwaysOn. La documentation en ligne nous propose <a href="http://msdn.microsoft.com/library/ff877954(v=sql.110).aspx">différentes outils</a> comme&#160; System Center, SQL Server Management Studio, les compteurs de performances ou encore Transact-SQL. Je rajouterai également PowerShell qui peut nous aider ici ou encore les outils tiers qui viendront compléter cette liste.</p>
<p>Voici une solution parmi d&rsquo;autres. Pour ma part j&rsquo;ai opté pour :</p>
<ul>
<li>Une routine continue en T-SQL qui va chercher les changements d&rsquo;états survenus sur les groupes de disponibilités présents sur un serveur sql. Si un changement est détecté un email est envoyé via databasemail aux personnes concernées </li>
<li>Un job SQL qui démarre et s&rsquo;exécute lorsque le service de l&rsquo;agent SQL Server démarre ou redémarre. Ce service est déjà monitoré par des outils tiers et si un problème survient au niveau de l&rsquo;agent SQL l&rsquo;information sera de toute façon remontée </li>
</ul>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/08/icon_arrow5.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/08/icon_arrow_thumb5.gif" width="15" height="15" /></a>&#160;<strong>Le code de la routine à intégrer</strong></p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;height:450px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- WORK TABLES</span><br />
<span style="color: #993333; font-weight: bold;">DECLARE</span> @t_aag <span style="color: #993333; font-weight: bold;">TABLE</span><br />
<span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp;group_name SYSNAME <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp;primary_replica <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">128</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp;primary_recovery_health NVARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">80</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NULL</span><br />
<span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">DECLARE</span> @t_aag_result <span style="color: #993333; font-weight: bold;">TABLE</span><br />
<span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #66cc66;">&#91;</span>action<span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp;group_name SYSNAME <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp;primary_replica_old <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">128</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp;primary_replica_new <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">128</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp;primary_recovery_health NVARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">80</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NULL</span><br />
<span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> @t_aag <span style="color: #66cc66;">&#40;</span>group_name<span style="color: #66cc66;">,</span> primary_replica<span style="color: #66cc66;">,</span> primary_recovery_health<span style="color: #66cc66;">&#41;</span> <br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#91;</span>group_name<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>primary_replica_new<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">&#91;</span>primary_recovery_health<span style="color: #66cc66;">&#93;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#91;</span>dbo<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>dbi_alwayson_failover_logs<span style="color: #66cc66;">&#93;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">WITH</span> aag<br />
<span style="color: #993333; font-weight: bold;">AS</span><br />
<span style="color: #66cc66;">&#40;</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <br />
&nbsp; &nbsp; g<span style="color: #66cc66;">.</span>name <span style="color: #993333; font-weight: bold;">AS</span> group_name<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; primary_replica<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; primary_recovery_health_desc<br />
&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> sys<span style="color: #66cc66;">.</span>dm_hadr_availability_group_states <span style="color: #993333; font-weight: bold;">AS</span> ags<br />
&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_groups <span style="color: #993333; font-weight: bold;">AS</span> g<br />
&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> ags<span style="color: #66cc66;">.</span>group_id <span style="color: #66cc66;">=</span> g<span style="color: #66cc66;">.</span>group_id<br />
<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">MERGE</span> dbo<span style="color: #66cc66;">.</span>dbi_alwayson_failover_logs <span style="color: #993333; font-weight: bold;">AS</span> t_aag<br />
<span style="color: #993333; font-weight: bold;">USING</span> aag<br />
<span style="color: #993333; font-weight: bold;">ON</span> aag<span style="color: #66cc66;">.</span>group_name <span style="color: #66cc66;">=</span> t_aag<span style="color: #66cc66;">.</span>group_name <span style="color: #993333; font-weight: bold;">COLLATE</span> Latin1_General_CS_AS_KS<br />
<span style="color: #993333; font-weight: bold;">WHEN</span> matched <span style="color: #993333; font-weight: bold;">AND</span> aag<span style="color: #66cc66;">.</span>primary_replica !<span style="color: #66cc66;">=</span> t_aag<span style="color: #66cc66;">.</span>primary_replica_new <span style="color: #993333; font-weight: bold;">COLLATE</span> Latin1_General_CS_AS_KS<br />
<span style="color: #993333; font-weight: bold;">THEN</span> <span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #993333; font-weight: bold;">SET</span> event_time <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; primary_replica_new <span style="color: #66cc66;">=</span> aag<span style="color: #66cc66;">.</span>primary_replica<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; primary_replica_old <span style="color: #66cc66;">=</span> primary_replica_new<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; primary_recovery_health <span style="color: #66cc66;">=</span> aag<span style="color: #66cc66;">.</span>primary_recovery_health_desc<br />
<span style="color: #993333; font-weight: bold;">WHEN</span> <span style="color: #993333; font-weight: bold;">NOT</span> MATCHED <span style="color: #993333; font-weight: bold;">BY</span> TARGET <br />
<span style="color: #993333; font-weight: bold;">THEN</span> <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><span style="color: #66cc66;">,</span> aag<span style="color: #66cc66;">.</span>group_name<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> aag<span style="color: #66cc66;">.</span>primary_replica<span style="color: #66cc66;">,</span> aag<span style="color: #66cc66;">.</span>primary_recovery_health_desc<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">WHEN</span> <span style="color: #993333; font-weight: bold;">NOT</span> MATCHED <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #993333; font-weight: bold;">SOURCE</span> <br />
<span style="color: #993333; font-weight: bold;">THEN</span> <span style="color: #993333; font-weight: bold;">DELETE</span><br />
OUTPUT $action<span style="color: #66cc66;">,</span> inserted<span style="color: #66cc66;">.</span>group_name<span style="color: #66cc66;">,</span> deleted<span style="color: #66cc66;">.</span>primary_replica_new<span style="color: #66cc66;">,</span> inserted<span style="color: #66cc66;">.</span>primary_replica_new<span style="color: #66cc66;">,</span> inserted<span style="color: #66cc66;">.</span>primary_recovery_health<br />
<span style="color: #993333; font-weight: bold;">INTO</span> @t_aag_result;<br />
<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <br />
&nbsp; &nbsp; group_name<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; primary_replica_new<br />
<span style="color: #993333; font-weight: bold;">FROM</span> @t_aag_result <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#91;</span>action<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'UPDATE'</span><br />
<br />
<br />
<span style="color: #808080; font-style: italic;">-- Reset work table</span><br />
<span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> @t_aag;<br />
<span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> @t_aag_result;<br />
<span style="color: #993333; font-weight: bold;">GO</span></div></div>
</p>
<p>&#160;</p>
<p>Le script fonctionne de manière suivante :</p>
<ul>
<li>2 tables de travail @t_aag et @t_aag_result qui vont respectivement contenir la configuration des groupes de disponibilités présents sur le serveur SQL et le delta éventuel dans une configuration existante (action = update) qui impliquerait un basculement dans notre cas </li>
<li>Une boucle continue de détection de basculement avec une temporisation de 10 secondes </li>
<li>1 table [dbo].[dba_alwayson_failover_logs] qui contiendra une ligne de données pour chaque&#160; basculement de groupes de disponibilité détecté. Une procédure stockée dbo.dba.alwayson_mail se servira ensuite de cette table d&rsquo;historique pour l&rsquo;envoi des emails. </li>
<li>Une instruction MERGE utilisée ici pour mettre à jour en continue la configuration des groupes de disponibilités sur le serveur SQL concerné (les ajouts, les mises à jour et les suppressions de groupes de disponibilités) avec insertion d&rsquo;une ligne de données en cas de mise à jour du réplica primaire pour un groupe de disponibilité (when matched and aag.primary_replica &lt;&gt; t_aag.primary_replica) </li>
</ul>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/08/icon_arrow6.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/08/icon_arrow_thumb6.gif" width="15" height="15" /></a>&#160;<strong>Le code de la table d&rsquo;historique</strong></p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #66cc66;">&#91;</span>dbo<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>dbi_alwayson_failover_logs<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>event_time<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#91;</span>datetime<span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #66cc66;">&#40;</span>getdate<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>group_name<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#91;</span>sysname<span style="color: #66cc66;">&#93;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>primary_replica_old<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">128</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>primary_replica_new<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">128</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>primary_recovery_health<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#91;</span>nvarchar<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">80</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NULL</span><br />
<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#91;</span><span style="color: #993333; font-weight: bold;">PRIMARY</span><span style="color: #66cc66;">&#93;</span></div></div>
</p>
<p>&#160;</p>
<p>Je ne mets pas ici volontairement le code la procédure d&rsquo;envoi d&rsquo;email car elle est plutôt spécifique à notre environnement de script. La logique est assez simple et consiste simplement à :</p>
<ul>
<li>1- parcourir la table d&rsquo;historique [dbo].[dba_alwayson_failover_logs] et vérifier les lignes de données non traitées par la routine d&rsquo;envoi d&rsquo;email. </li>
<li>2- Mettre à jour la valeur de colonne sent_by_email à 1 une fois l&rsquo;email envoyé. </li>
</ul>
<p>&#160;</p>
<p>Et vous comment faites-vous ?</p>
<p>Bonne détection de basculement !</p>
<p>&#160;</p>
<p>David BARBARIN (Mikedavem)    <br />MVP SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Consid&#233;ration sur les listeners associ&#233;es aux groupes de disponibilit&#233;s avec SQL Server 2012 AlwaysOn</title>
		<link>https://blog.developpez.com/mikedavem/p12098/sql-server-2012/considration-sur-les-listeners-associes-aux-groupes-de-disponibilits-avec-sql-server-2012-alwayson</link>
		<comments>https://blog.developpez.com/mikedavem/p12098/sql-server-2012/considration-sur-les-listeners-associes-aux-groupes-de-disponibilits-avec-sql-server-2012-alwayson#comments</comments>
		<pubDate>Tue, 02 Jul 2013 21:42:08 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[AlwaysOn]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=591</guid>
		<description><![CDATA[Lorsqu&#8217;on crée un groupe de disponibilité avec SQL Server et AlwaysOn on l&#8217;associe par la suite à un listener. Lorsque ce dernier est créé plusieurs objets lui sont associées : Un objet d&#8217;ordinateur dans l&#8217;annuaire active directory Une entrée DNS &#8230; <a href="https://blog.developpez.com/mikedavem/p12098/sql-server-2012/considration-sur-les-listeners-associes-aux-groupes-de-disponibilits-avec-sql-server-2012-alwayson">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Lorsqu&rsquo;on crée un groupe de disponibilité avec SQL Server et AlwaysOn on l&rsquo;associe par la suite à un listener. Lorsque ce dernier est créé plusieurs objets lui sont associées :</p>
<ul>
<li>Un objet d&rsquo;ordinateur dans l&rsquo;annuaire active directory </li>
<li>Une entrée DNS de type A </li>
<li>Une ressource cluster associée à au groupe de ressource créé et qui représente le groupe de disponibilité </li>
</ul>
<p>&#160;</p>
<p>Dans l&rsquo;exemple suivante un groupe de disponibilité nommé AdventureWorks2 a été créé. Le listener associé s&rsquo;appelle LST_ADVW2</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_aag_lst.gif"><img title="alwayson_aag_lst" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="alwayson_aag_lst" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_aag_lst_thumb.gif" width="497" height="203" /></a></p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow1.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow_thumb1.gif" width="15" height="15" /></a> <strong>Les différents objets associés</strong> </p>
<p>&#160;</p>
<p>L&rsquo;objet d&rsquo;ordinateur dans l&rsquo;annuaire :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_ad_object.gif"><img title="alwayson_ad_object" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="alwayson_ad_object" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_ad_object_thumb.gif" width="515" height="129" /></a></p>
<p>&#160;</p>
<p>&#8230; l&rsquo;enregistrement DNS :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_dns_record.gif"><img title="alwayson_dns_record" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="alwayson_dns_record" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_dns_record_thumb.gif" width="681" height="105" /></a></p>
<p>&#160;</p>
<p>&#8230; Le groupe de ressource lié au groupe de disponibilité :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_cluster_resource.gif"><img title="alwayson_cluster_resource" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="alwayson_cluster_resource" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_cluster_resource_thumb.gif" width="586" height="127" /></a></p>
<p>&#160;</p>
<p>&#8230; et les ressources qui le composent :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_cluster_resource2.gif"><img title="alwayson_cluster_resource2" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="alwayson_cluster_resource2" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_cluster_resource2_thumb.gif" width="464" height="253" /></a></p>
<p>&#160;</p>
<p>Jetons un coup d&rsquo;œil aux dépendances existantes entre les ressources du groupe de ressource AdventureWorksGrp2 :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_cluster_dependencies.gif"><img title="alwayson_cluster_dependencies" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="alwayson_cluster_dependencies" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_cluster_dependencies_thumb.gif" width="802" height="391" /></a></p>
<p>&#160;</p>
<p>Ici on vient bien les dépendances existantes : le groupe de disponibilité AdventureWorksGrp2 dépend de la ressource &quot;nom réseau&quot; qui représente notre listener (LST_ADVW2) qui elle même dépend de la ressource &quot;Adresse IP&quot; qui vous l&rsquo;aurez devinez, correspond à l&rsquo;adresse IP de notre listener. </p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow2.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow_thumb2.gif" width="15" height="15" /></a> <strong><u>Port d&rsquo;écoute du listener</u></strong> </p>
<p>Est-ce qu&rsquo;un listener doit écouter sur le même port que les réplicas du groupe disponibilité ?&#160; Est-ce possible ? C&rsquo;est une question qui s&rsquo;est posé rapidement dans mon cas lorsqu&rsquo;il a fallu installer des réplicas n&rsquo;écoutant pas sur le port qui n&rsquo;écoutaient pas sur le port par défaut (1433). On peut même aller à l&rsquo;extrême et prendre le cas où chaque réplica écoute sur un port différent. Dans ce cas quel port dois-je paramétrer pour mon listener ? Un listener peut tout à fait écouter sur un port différent que les réplicas. Le choix du numéro de port dépend évidement de vos besoins, contraintes de sécurité etc &#8230;&#160; Prenons un exemple avec 2 réplicas qui écoutent sur 2 ports différents (1499 et 1500) et un listener qui écoute sur le port 1433.</p>
<p>&#160;</p>
<p>[AlwaysOn Instance]</p>
<p>Cette configuration fonctionne parfaitement. Par curiosité on peut voir ce que cela donne sur une trace réseau via NetMon par exemple.</p>
<p><font color="#ff0000"><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_netmon0.jpg"><img title="alwayson_netmon0" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="alwayson_netmon0" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_netmon0_thumb.jpg" width="827" height="296" /></a></font></p>
<p><font color="#ff0000"></font></p>
<p><font color="#333333"></font></p>
<p><font color="#333333">On peut voir ici une connexion depuis SQL Server Management Studio vers le listener <em>lst_advw.insentia.lab</em> (IP virtuelle : 192.168.0.61)</font></p>
<p>&#160;</p>
<p>Dans notre cas le listener écoute sur le port 1433 et la connexion est automatiquement redirigée vers le réplica concerné en toute transparence. Au niveau de la chaine de connexion l&rsquo;impact est minime : le nom du listener remplace tout simple le nom de l&rsquo;instance SQL Server. Cependant que se passe-t-il maintenant si nous changeons le port d&rsquo;écoute du listener vers un port non standard ? En réalité les choses se compliquent un peu et il existe plusieurs cas :</p>
<ul>
<li>On spécifie le numéro de port directement dans la chaine de connexion </li>
<li>On a la possibilité d&rsquo;utiliser le format suivant : [nom listener]\[nom instance] sous certaines conditions :
<ul>
<li>On utilise des instances nommées qui portent le même nom pour l&rsquo;ensemble des réplicas </li>
<li>Le service SQL Browser est démarré et opérationnel sur l&rsquo;ensemble des réplicas pour effectuer la résolution de nom de l&rsquo;instance vers le numéro de port adéquat. </li>
</ul>
</li>
</ul>
<p><font color="#ff0000"></font></p>
<p><font color="#ff0000"></font></p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow3.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow_thumb3.gif" width="15" height="15" /></a> <strong>Cas de la</strong> r<strong>edirection vers un réplica secondaire en lecture seule</strong></p>
<p>AlwaysOn nous fournit la possibilité d&rsquo;être redirigé vers un réplica secondaire en lecture seule en se connectant via le listener à condition que les règles de redirection&#160; aient été définies (routes et priorités). Dans ce cas une trace NetMon nous révèle la chose suivante :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_netmon11.jpg"><img title="alwayson_netmon1" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="alwayson_netmon1" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_netmon1_thumb.jpg" width="843" height="243" /></a></p>
<p>&#160;</p>
<p>On peut constater ici qu&rsquo;après la phase d&rsquo;authentification la connexion de SQL Server Management Studio initialement effectuée vers le listener <em>lst_advw.insentia.lab</em> (port 1433) est redirigé vers le réplica secondaire en lecture seule <em>REPLICA2</em> (port 1498)</p>
<p>&#160;</p>
<p><font color="#ff0000"></font></p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow4.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow_thumb4.gif" width="15" height="15" /></a>&#160;<strong><u>Kerberos,</u></strong> <strong><u>SPN et redirection vers un réplica secondaire en lecture seule</u></strong></p>
<p>La documentation en ligne Microsoft stipule que pour utiliser Kerberos dans une architecture AlwaysOn il faut ajouter les SPN correspondants à nos listeners. Cependant je n&rsquo;ai pas trouvé dans la documentation le cas où le listener effectuait une redirection d&rsquo;une connexion en lecture seule vers un réplica secondaire en lecture seule. Dans ce cas ajouter les SPN pour les listeners ne suffit pas et l&rsquo;on doit également ajouter les réplicas secondaires en lecture seule.</p>
<p>Voici une trace netmon d&rsquo;une tentative de connexion en erreur à un réplica secondaire avec Kerberos :</p>
<p><font color="#ff0000"><a href="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_spn_netmon.jpg"><img title="alwayson_spn_netmon" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="alwayson_spn_netmon" src="http://blog.developpez.com/mikedavem/files/2013/07/alwayson_spn_netmon_thumb.jpg" width="816" height="254" /></a></font></p>
<p>&#160;</p>
<p>On peut voir ici 2 requêtes TGS depuis ma station cliente (192.168.0.100) vers mon contrôleur de domaine (192.168.0.1) :</p>
<ul>
<li>TGS request vers le service MSSQLSvc/lst_advw.insentia.lab (port 1433) : listener </li>
<li>TGS request vers le service MSSQLSvc/replica2.insentia.lab (port 1498) : réplica secondaire en lecture seule </li>
</ul>
<p>Le contrôleur de domaine répond avec une erreur pour la deuxième demande car il n&rsquo;y a pas de SPN paramétré pour <em>REPLICA2</em> dans mon cas (KDC_ERR_S_PRINCIPAL_UNKNOW)</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow5.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/07/icon_arrow_thumb5.gif" width="15" height="15" /></a>&#160;<strong><u>Listeners vs alias (DNS / SQL) ?</u></strong> </p>
<p>Une question intéressante surtout lorsqu&rsquo;on a l&rsquo;habitude de lier le point de connexion des applications via un alias DNS ou SQL par exemple. Ainsi lorsqu&rsquo;on change de serveur de bases de données avec un nouveau nom, il suffit d&rsquo;utiliser de modifier l&rsquo;alias en conséquence. Le changement est donc relativement transparent pour les applications. Avec SQL Server AlwaysOn, lorsqu&rsquo;un un listener est créé nous avons vu qu&rsquo;une entrée DNS est également effectuée. De plus on a la possibilité d&rsquo;associer plusieurs listeners à un seul groupe de disponibilité ce qui peut tout à fait remplacer les alias. Bien entendu chaque méthode présente des avantages mais aussi des inconvénients. Goden Yao (Program Manager , SQL Server Engine High Availability)&#160; a écrit un <a href="http://blogs.msdn.com/b/sqlalwayson/archive/2012/02/03/how-to-create-multiple-listeners-for-same-availability-group-goden-yao.aspx">billet</a> intéressant à ce sujet. </p>
<p>&#160;</p>
<p>Bon paramétrage de listeners !!</p>
<p>&#160;</p>
<p><strong><u></u></strong></p>
<p>David BARBARIN (Mikedavem)    <br />MVP SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server 2012 AlwaysOn et plans de maintenance par d&#233;faut</title>
		<link>https://blog.developpez.com/mikedavem/p12043/sql-server-2012/sql-server-2012-alwayson-et-plans-de-maintenance-par-dfaut</link>
		<comments>https://blog.developpez.com/mikedavem/p12043/sql-server-2012/sql-server-2012-alwayson-et-plans-de-maintenance-par-dfaut#comments</comments>
		<pubDate>Thu, 13 Jun 2013 14:26:38 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[maintenance]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=550</guid>
		<description><![CDATA[Lors de ma session GUSS du 23 avril 2013 à propos de AlwaysOn on m&#8217;a demandé si les plans de maintenance SQL Server pouvaient être utilisés dans ce contexte. J&#8217;ai répondu négativement à cette réponse sans pour autant être vraiment &#8230; <a href="https://blog.developpez.com/mikedavem/p12043/sql-server-2012/sql-server-2012-alwayson-et-plans-de-maintenance-par-dfaut">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Lors de ma session <a href="http://guss.fr/2013/06/01/webcast-guss-avril-2013-les-bases-alwayson/">GUSS</a> du 23 avril 2013 à propos de AlwaysOn on m&rsquo;a demandé si les plans de maintenance SQL Server pouvaient être utilisés dans ce contexte. J&rsquo;ai répondu négativement à cette réponse sans pour autant être vraiment explicite. Pourtant lorsqu&rsquo;on créé un plan de maintenance avec SQL Server 2012 et qu&rsquo;on utilise une tâche de sauvegarde des bases on peut s&rsquo;apercevoir que si une base de données est concernée par un groupe de disponibilité une option apparait automatiquement <em>&quot;For availability databases, ignore Replica Priority for Backup and Backup on Primary&#160; Settings</em>&quot;. L&rsquo;apparition de cette option implique que par défaut les plans de maintenance SQL Server ou du mois les tâches de sauvegarde sont en théorie capables de s&rsquo;aligner sur la politique de sauvegarde dictée par le groupe de disponibilité en question mais malgré ce je persiste à dire que les plans de maintenance par défaut ne sont pas adaptés (du moins encore) aux environnements AlwaysOn et c&rsquo;est ce que je vais tenter d&rsquo;expliquer dans ce billet.</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow2.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow_thumb2.gif" width="15" height="15" /></a>&#160;<strong><u>Des tâches de sauvegardes qui gèrent et prennent en compte les préférences de sauvegarde d&rsquo;un groupe de disponibilité</u></strong></p>
<p>Commençons par le début. Effectivement les tâches de sauvegardes des plans de maintenance par défaut détectent l&rsquo;appartenance ou non d&rsquo;une base de données à un groupe de disponibilité. </p>
<p>J&rsquo;ai créé une base de données DUMMY faisait parti du groupe de disponibilité </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image4.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb4.png" width="244" height="250" /></a></p>
<p>&#160;</p>
<p>J&rsquo;ai paramétré mes préférences de sauvegarde de la manière suivante :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image5.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb5.png" width="443" height="288" /></a></p>
<p>&#160;</p>
<p>Dans un plan de maintenance par défaut je glisse une tâche de sauvegarde de type FULL en choisissant la base de données DUMMY &#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image6.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb6.png" width="426" height="359" /></a></p>
<p>&#160;</p>
<p>&#8230; et on s&rsquo;aperçoit qu&rsquo;une option supplémentaire apparait </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image7.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb7.png" width="515" height="230" /></a></p>
<p>&#160;</p>
<p>Cette option permet de ne pas tenir compte des préférences de sauvegarde configurés dans les groupes de disponibilités pour un réplica. Par défaut cette option n&rsquo;est pas activée et la tâche de sauvegarde prendra en compte les préférences de sauvegardes des groupes de disponibilités (de préférence sur les secondaires, uniquement sur les secondaires, uniquement sur le primaire, sur n&rsquo;importe quel réplica). </p>
<p>On peut voir que la commande T-SQL générée utilise la fonction sys.fn_hadr_backup_is_preferred_replica() pour la base de données DUMMY</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image8.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb8.png" width="451" height="351" /></a></p>
<p>&#160;</p>
<p>Notez également que j&rsquo;ai activé l&rsquo;option COPY_ONLY pour les sauvegardes. En effet comme ma politique de sauvegarde stipule que les réplicas secondaires seront utilisés en priorité, seules les sauvegardes avec l&rsquo;option COPY_ONLY fonctionneront si le réplica concerné sera secondaire au moment de la sauvegarde. Mon plan de maintenance fonctionne parfaitement même après test de failover d&rsquo;un réplica vers un autre. Cependant comme vous le savez certainement un plan de maintenance n&rsquo;est jamais aussi simple. </p>
<p>Restons sur notre tâche de sauvegarde et ajoutons-y quelques bases de données utilisateurs en mode de récupération FULL et qui ne font pas parti d&rsquo;un groupe de disponibilité et c&rsquo;est la que le premier problème arrive. Ma politique de sauvegarde de type full se fait toujours avec l&rsquo;option COPY_ONLY dans mon cas puisque mes sauvegardes se feront en priorité sur le secondaire et que ceux-ci ne supportent que les sauvegardes avec l&rsquo;option COPY_ONLY. Le problème est qu&rsquo;ici la création d&rsquo;une base de données utilisateur en mode de récupération FULL fera planté la tâche de sauvegarde des journaux de transactions. Pourquoi ? Tout simplement parce qu&rsquo;une sauvegarde FULL avec l&rsquo;option COPY_ONLY ne va pas initialiser la séquence des LSN utiles pour nos sauvegardes des journaux de transactions. Alors bien entendu je peux créer 2 plans de maintenance par exemple :</p>
<ul>
<li>Un plan de maintenance qui concernera uniquement les bases de données en mode de récupération FULL associées à un groupe de disponibilité </li>
<li>Un plan de maintenance qui concernera les autres bases de données </li>
</ul>
<p>Il faudra dans ce cas répartir manuellement les bases de données dans les différents plans de maintenance. On perd ici toute notion de gestion dynamique des plans de maintenance selon moi. Si j&rsquo;ajoute une base de données par exemple, je n&rsquo;ai pas forcément envie de modifier ensuite mon plan de maintenance &#8230; Bien entendu ce raisonnement ici ne tient que pour les cas où les sauvegardes sont déportés sur le secondaire. Si les sauvegardes sont effectuées uniquement sur le primaire, l&rsquo;utilisation de l&rsquo;option COPY_ONLY n&rsquo;a plus lieu d&rsquo;être. </p>
<p>Une autre chose à noter ici est le manque de support de l&rsquo;option CHECKSUM qui permet pour rappel d&rsquo;une part de vérifier le checksum de chaque page de données sauvegardée d&rsquo;une base de données (si l&rsquo;option est bien entendu activée au niveau de celle-ci) et de générer un checksum global pour le média de sauvegarde. </p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow3.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow_thumb3.gif" width="15" height="15" /></a>&#160;<strong><u>La tâche de vérification d&rsquo;intégrité</u></strong> </p>
<p>Vérifier l&rsquo;intégrité de ses bases de données avant de les sauvegarder est plutôt une opération recommandée. Mais dans une architecture AlwaysOn on peut se poser la question de savoir où est-ce que je dois lancer cette tâche. Si dans d&rsquo;autres environnements le choix est plutôt évident car les sauvegardes ne peuvent se faire que sur le serveur &quot;principal&quot; , le raisonnement n&rsquo;est pas tout à fait le même quand on parle de déplacement des sauvegardes sur un réplica secondaire. En effet, vu que ma politique de sauvegarde gère des préférences et des priorités de réplicas pour les sauvegardes ces dernières peuvent être lancés de n&rsquo;importe où en fonction de la situation présente et des paramètres de configuration. En plus mes bases de données sont accessibles en lecture écriture depuis un réplica primaire et peuvent être inaccessible depuis mes les réplicas secondaires. Il faut également que je vérifie l&rsquo;intégrité de ma base à ce niveau. Cela fait potentiellement 2 points de vérification d&rsquo;intégrité des bases sur n réplicas (n pouvant aller jusqu&rsquo;à 5 pour le moment mais avec SQL14 on pourra monter jusqu&rsquo;à 8 !). </p>
<p>Si on regarde de plus près la tâche de vérification d&rsquo;intégrité des plans de maintenance par défaut de SQL Server on s&rsquo;aperçoit qu&rsquo;il n&rsquo;y a aucun paramètre de gestion des groupes de disponibilités : </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image9.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb9.png" width="393" height="488" /></a></p>
<p>&#160;</p>
<p>Dans ce cas comment puis-je faire pour lancer ma tâche ? On peut prendre le cas extrême qui dit qu&rsquo;il faut lancer cette tâche de vérification des bases sur tous les réplicas .. et pourquoi pas après tout ? </p>
<p>Je vois déjà 2 problèmes à cela :</p>
<ul>
<li>Même si la vérification d&rsquo;intégrité initiée par la commande DBCC CHECKDB ne génère pas de verrou par défaut (utilisation des snapshots de bases de données) celle-ci peut avoir un impact négatif sur les performances IO et sur l&rsquo;augmentation de la REDO queue sur les réplicas secondaires. Une augmentation de cette file d&rsquo;attente sur les secondaires peuvent avoir un impact sur le RPO et RTO en fonction du type de réplication choisi. </li>
<li>On peut tout à fait utiliser un réplica secondaire pour faire des sauvegardes et second réplica secondaire en standby uniquement pour effectuer du failover ou dans une procédure de disaster recovery. Dans ce cas la tâche de vérification d&rsquo;intégrité des bases des plans de maintenance par défaut SQL Server étant incapable de savoir si la base de données concernée fait parti ou non d&rsquo;un groupe de disponibilité et si la base de données en question est accessible en lecture seule ou non provoquera une erreur dans le plan de maintenance en fonction de la situation </li>
</ul>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow4.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow_thumb4.gif" width="15" height="15" /></a>&#160;<strong><u>Les tâches de mise à jour des statistiques et des indexes</u></strong></p>
<p>On a exactement le même problème ici. En regardant les tâches du plan de maintenance associées aux statistiques et aux indexes il n&rsquo;y a aucun paramètre de configuration lié aux groupes de disponibilité. Dans une architecture AlwaysOn on ne peut mettre à jour les indexes et les statistiques&#160; d&rsquo;une base que sur le réplica primaire. Je peux également avoir des bases de données qui ne sont pas concernées par un groupe de disponibilité. Dans ce cas il est tout à fait possible qu&rsquo;un réplica secondaire d&rsquo;un groupe de disponibilité soit l&rsquo;instance principale d&rsquo;une autre base de données. Je peux effectivement créer un plan de maintenance spécifique pour cela et activer / désactiver les jobs SQL Server associées en fonction du cas mais encore une fois cela m&rsquo;oblige à gérer manuellement les bases de données à répartir dans les plans de maintenance &#8230;</p>
<p>De plus dans ce genre d&rsquo;architecture l&rsquo;utilisation des tâches par défaut de maintenance des indexes ne sont pas forcément conseillés car elles peuvent être excréments couteuse en écriture journalisée et de bande passante pour la réplication de ces écritures vers les autres réplicas. En effet, et beaucoup d&rsquo;articles l&rsquo;expliquent déjà, il n&rsquo;y a pas la possibilité de définir des seuils de réorganisation ou de reconstruction d&rsquo;indexes. La politique du tout ou rien ici n&rsquo;est pas forcément très approprié.</p>
<p>&#160;</p>
<p>Pas besoin d&rsquo;aller plus loin je pense pour vous dire que les plans de maintenance SQL Server ne sont pas adaptés pour SQL Server 2012 AlwaysOn. Que fais-t-on dans ce cas là ? Pour le moment pour ma part j&rsquo;ai créé un jeu de script de maintenance des bases de données pour des architectures AlwaysOn installées chez nos clients. Je n&rsquo;ai pour le moment pas trouvé d&rsquo;outil tiers permettant de gérer la maintenance des bases de données de A à Z pour ce type d&rsquo;environnement mais je reste à l&rsquo;écoute si jamais vous avez plus d&rsquo;information là dessus <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none;border-left-style: none;border-bottom-style: none;border-right-style: none" alt="Sourire" src="http://blog.developpez.com/mikedavem/files/2013/06/wlEmoticon-smile.png" /></p>
<p>&#160;</p>
<p>Bonne maintenance de vos architectures AlwaysOn !</p>
<p>&#160;</p>
<p>David BARBARIN (Mikedavem)    <br />MVP SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Webcast sur SQL Server 2012 AlwaysOn pour les fermes Sharepoint 2013 : les slides et la vid&#233;o sont disponibles</title>
		<link>https://blog.developpez.com/mikedavem/p12041/evenements/webcast-sur-sql-server-2012-alwayson-pour-les-fermes-sharepoint-2013-les-slides-et-la-vido-sont-disponibles</link>
		<comments>https://blog.developpez.com/mikedavem/p12041/evenements/webcast-sur-sql-server-2012-alwayson-pour-les-fermes-sharepoint-2013-les-slides-et-la-vido-sont-disponibles#comments</comments>
		<pubDate>Wed, 12 Jun 2013 18:02:56 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[Evénements]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[GUSS]]></category>
		<category><![CDATA[Sharepoint]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=529</guid>
		<description><![CDATA[Un billet en retard pour dire que les slides et la vidéo de la session GUSS que j&#8217;ai eu l&#8217;occasion d&#8217;animer sur SQL Server 2012 AlwaysOn et SharePoint 2013 sont disponibles sur le site du GUSS &#62;&#62; http://guss.fr/2013/06/01/webcast-guss-avril-2013-les-bases-alwayson/ &#160; David &#8230; <a href="https://blog.developpez.com/mikedavem/p12041/evenements/webcast-sur-sql-server-2012-alwayson-pour-les-fermes-sharepoint-2013-les-slides-et-la-vido-sont-disponibles">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un billet en retard pour dire que les slides et la vidéo de la session GUSS que j&rsquo;ai eu l&rsquo;occasion d&rsquo;animer sur SQL Server 2012 AlwaysOn et SharePoint 2013 sont disponibles sur le site du <a href="http://guss.fr/">GUSS</a> </p>
<p>&gt;&gt; <a title="http://guss.fr/2013/06/01/webcast-guss-avril-2013-les-bases-alwayson/" href="http://guss.fr/2013/06/01/webcast-guss-avril-2013-les-bases-alwayson/">http://guss.fr/2013/06/01/webcast-guss-avril-2013-les-bases-alwayson/</a></p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/guss.jpg"><img title="guss" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="guss" src="http://blog.developpez.com/mikedavem/files/2013/06/guss_thumb.jpg" width="210" height="88" /></a></p>
<p>David BARBARIN (Mikedavem)    <br />MVP SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cr&#233;er un serveur li&#233; avec une connexion en lecture seule vers un r&#233;plica secondaire SQL Server 2012 AlwaysOn</title>
		<link>https://blog.developpez.com/mikedavem/p12017/sql-server-2012/crer-un-serveur-li-avec-une-connexion-en-lecture-seule-vers-un-rplica-secondaire-sql-server-2012-alwayson</link>
		<comments>https://blog.developpez.com/mikedavem/p12017/sql-server-2012/crer-un-serveur-li-avec-une-connexion-en-lecture-seule-vers-un-rplica-secondaire-sql-server-2012-alwayson#comments</comments>
		<pubDate>Tue, 04 Jun 2013 20:32:39 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[Linked server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=521</guid>
		<description><![CDATA[Petite question que je me posais aujourd&#8217;hui vu qu&#8217;en ce moment je travaille souvent sur des environnements haute disponibilité avec SQL Server 2012 et AlwaysOn. Est-il possible de créer un serveur lié qui se connecte sur un réplica secondaire en &#8230; <a href="https://blog.developpez.com/mikedavem/p12017/sql-server-2012/crer-un-serveur-li-avec-une-connexion-en-lecture-seule-vers-un-rplica-secondaire-sql-server-2012-alwayson">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Petite question que je me posais aujourd&rsquo;hui vu qu&rsquo;en ce moment je travaille souvent sur des environnements haute disponibilité avec SQL Server 2012 et AlwaysOn. Est-il possible de créer un serveur lié qui se connecte sur un réplica secondaire en lecture et profiter du coup d&rsquo;une redirection transparente en cas de changement de rôle de réplica lors d&rsquo;un basculement automatique par exemple ? </p>
<p>Le meilleur moyen de le savoir est de faire un test. </p>
<p>Créons tout d&rsquo;abord un serveur lié en utilisant le provider SQL Server Native Client 11.0 pour pouvoir utiliser le paramètre de connexion applicationintent=readonly. Le script de création du serveur lié est le suivant :</p>
<p>&#160;</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">EXEC</span> master<span style="color: #66cc66;">.</span>dbo<span style="color: #66cc66;">.</span>sp_addlinkedserver &nbsp; &nbsp;<br />
&nbsp;@server <span style="color: #66cc66;">=</span> N<span style="color: #ff0000;">'LST_APPLIX'</span><span style="color: #66cc66;">,</span><br />
&nbsp;@srvproduct<span style="color: #66cc66;">=</span>N<span style="color: #ff0000;">''</span><span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;@provider<span style="color: #66cc66;">=</span>N<span style="color: #ff0000;">'SQLNCLI'</span><span style="color: #66cc66;">,</span> <span style="color: #808080; font-style: italic;">-- Provider SQL Native Client &nbsp; &nbsp;</span><br />
&nbsp;@datasrc<span style="color: #66cc66;">=</span>N<span style="color: #ff0000;">'LST_APPLIX'</span><span style="color: #66cc66;">,</span> <span style="color: #808080; font-style: italic;">-- Availability group listener &nbsp; &nbsp;</span><br />
&nbsp;@provstr<span style="color: #66cc66;">=</span>N<span style="color: #ff0000;">'applicationintent=readonly'</span><span style="color: #66cc66;">,</span>  <span style="color: #808080; font-style: italic;">-- Readonly intent parameter &nbsp; &nbsp; </span><br />
&nbsp;@catalog<span style="color: #66cc66;">=</span>N<span style="color: #ff0000;">'ApplixEnterprise'</span> <span style="color: #808080; font-style: italic;">--Target database to connect</span></div></div>
</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow.gif"><img title="icon_arrow" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow_thumb.gif" width="15" height="15" /></a> Mon groupe de disponibilité est composé de 3 réplicas avec :</p>
<ul>
<li>REPLICA1 (réplica primaire)</li>
<li>REPLICA2 (réplica secondaire en lecture seule utilisé en priorité)</li>
<li>REPLICA3 (réplica secondaire en lecture seule utilisé si REPLICA2 n&rsquo;est plus joignable)</li>
</ul>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow1.gif"><img title="icon_arrow" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/06/icon_arrow_thumb1.gif" width="15" height="15" /></a> Mon serveur lié est quant à lui configuré sur un serveur standalone à part.</p>
<p>&#160;</p>
<p>La requête suivante illustre l&rsquo;état de note scénario :</p>
<p>&#160;</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; <br />
&nbsp;g<span style="color: #66cc66;">.</span>name <span style="color: #993333; font-weight: bold;">AS</span> group_name<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;r<span style="color: #66cc66;">.</span>replica_server_name<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;rs<span style="color: #66cc66;">.</span>role_desc<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;rs<span style="color: #66cc66;">.</span>operational_state_desc<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;ro<span style="color: #66cc66;">.</span>replica_server_name <span style="color: #993333; font-weight: bold;">AS</span> replica_ro_server_name<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;rol<span style="color: #66cc66;">.</span>routing_priority<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;r<span style="color: #66cc66;">.</span>secondary_role_allow_connections_desc &nbsp; &nbsp;<br />
<span style="color: #993333; font-weight: bold;">FROM</span> sys<span style="color: #66cc66;">.</span>dm_hadr_availability_replica_states <span style="color: #993333; font-weight: bold;">AS</span> rs &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_groups <span style="color: #993333; font-weight: bold;">AS</span> g &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> rs<span style="color: #66cc66;">.</span>group_id <span style="color: #66cc66;">=</span> g<span style="color: #66cc66;">.</span>group_id &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_replicas <span style="color: #993333; font-weight: bold;">AS</span> r &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> r<span style="color: #66cc66;">.</span>replica_id <span style="color: #66cc66;">=</span> rs<span style="color: #66cc66;">.</span>replica_id &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> r<span style="color: #66cc66;">.</span>group_id <span style="color: #66cc66;">=</span> rs<span style="color: #66cc66;">.</span>group_id &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_read_only_routing_lists rol &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> rol<span style="color: #66cc66;">.</span>replica_id <span style="color: #66cc66;">=</span> r<span style="color: #66cc66;">.</span>replica_id &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_replicas <span style="color: #993333; font-weight: bold;">AS</span> ro &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> ro<span style="color: #66cc66;">.</span>replica_id <span style="color: #66cc66;">=</span> rol<span style="color: #66cc66;">.</span>read_only_replica_id &nbsp; &nbsp;<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> g<span style="color: #66cc66;">.</span>name <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'ApplixGrp'</span> &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">AND</span> r<span style="color: #66cc66;">.</span>replica_server_name <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'REPLICA1'</span></div></div>
</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb.png" width="832" height="80" /></a></p>
<p>&#160;</p>
<p>Tentons de retrouver le serveur sur lequel le serveur lié pointe :</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> &nbsp; &nbsp;<br />
<span style="color: #993333; font-weight: bold;">FROM</span> OPENQUERY<span style="color: #66cc66;">&#40;</span>LST_APPLIX<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'SELECT @@SERVERNAME AS SERVER_NAME'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
</p>
<p>qui donne </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image1.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb1.png" width="145" height="56" /></a></p>
<p>&#160;</p>
<p>Ok visiblement cela fonctionne. En utilisant le listener la requête est automatiquement redirigée vers le REPLICA2 comme le stipule notre configuration. </p>
<p>&#160;</p>
<p>On lance maintenant un basculement manuel de groupe de disponibilité ApplixGrp de REPLICA1 vers REPLICA2. REPLICA2 devient donc le nouveau primaire.REPLICA1 et REPLICA3 deviennent les réplicas secondaires. On exécute à nouveau nos requêtes :</p>
<p>&#160;</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; <br />
&nbsp;g<span style="color: #66cc66;">.</span>name <span style="color: #993333; font-weight: bold;">AS</span> group_name<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;r<span style="color: #66cc66;">.</span>replica_server_name<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;rs<span style="color: #66cc66;">.</span>role_desc<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;rs<span style="color: #66cc66;">.</span>operational_state_desc<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;ro<span style="color: #66cc66;">.</span>replica_server_name <span style="color: #993333; font-weight: bold;">AS</span> replica_ro_server_name<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;rol<span style="color: #66cc66;">.</span>routing_priority<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;r<span style="color: #66cc66;">.</span>secondary_role_allow_connections_desc &nbsp; &nbsp;<br />
<span style="color: #993333; font-weight: bold;">FROM</span> sys<span style="color: #66cc66;">.</span>dm_hadr_availability_replica_states <span style="color: #993333; font-weight: bold;">AS</span> rs &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_groups <span style="color: #993333; font-weight: bold;">AS</span> g &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> rs<span style="color: #66cc66;">.</span>group_id <span style="color: #66cc66;">=</span> g<span style="color: #66cc66;">.</span>group_id &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_replicas <span style="color: #993333; font-weight: bold;">AS</span> r &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> r<span style="color: #66cc66;">.</span>replica_id <span style="color: #66cc66;">=</span> rs<span style="color: #66cc66;">.</span>replica_id &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> r<span style="color: #66cc66;">.</span>group_id <span style="color: #66cc66;">=</span> rs<span style="color: #66cc66;">.</span>group_id &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_read_only_routing_lists rol &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> rol<span style="color: #66cc66;">.</span>replica_id <span style="color: #66cc66;">=</span> r<span style="color: #66cc66;">.</span>replica_id &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> sys<span style="color: #66cc66;">.</span>availability_replicas <span style="color: #993333; font-weight: bold;">AS</span> ro &nbsp; &nbsp;<br />
&nbsp; <span style="color: #993333; font-weight: bold;">ON</span> ro<span style="color: #66cc66;">.</span>replica_id <span style="color: #66cc66;">=</span> rol<span style="color: #66cc66;">.</span>read_only_replica_id &nbsp; &nbsp;<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> g<span style="color: #66cc66;">.</span>name <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'ApplixGrp'</span> &nbsp; &nbsp;<br />
&nbsp;<span style="color: #993333; font-weight: bold;">AND</span> r<span style="color: #66cc66;">.</span>replica_server_name <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'REPLICA2'</span></div></div>
</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image2.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb2.png" width="844" height="70" /></a></p>
<p>&#160;</p>
<p>et </p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> &nbsp; &nbsp;<br />
<span style="color: #993333; font-weight: bold;">FROM</span> OPENQUERY<span style="color: #66cc66;">&#40;</span>LST_APPLIX<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'SELECT @@SERVERNAME AS SERVER_NAME'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
</p>
<p>qui donne </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/06/image3.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/06/image_thumb3.png" width="149" height="53" /></a></p>
<p>&#160;</p>
<p>Comme on peut le voir l&rsquo;utilisation d&rsquo;un serveur lié vers une architecture SQL Server 2012 AlwaysOn avec une redirection des connexions en lecture seule vers les réplicas secondaires fonctionne très bien !</p>
<p>&#160;</p>
<p>Bon paramétrage de serveurs liés</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
