<?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>cx.cx</title>
	<atom:link href="http://cx.cx/feed/" rel="self" type="application/rss+xml" />
	<link>http://cx.cx</link>
	<description>Cyber eXchange about new technologies</description>
	<lastBuildDate>Wed, 07 Sep 2011 09:23:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Répartiteur de charge LVS</title>
		<link>http://cx.cx/2011/03/23/repartiteur-de-charge-lvs/</link>
		<comments>http://cx.cx/2011/03/23/repartiteur-de-charge-lvs/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 09:53:00 +0000</pubDate>
		<dc:creator>celine</dc:creator>
				<category><![CDATA[Générale]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[direct routing]]></category>
		<category><![CDATA[director]]></category>
		<category><![CDATA[ipv]]></category>
		<category><![CDATA[ipvsadm]]></category>
		<category><![CDATA[keepalived]]></category>
		<category><![CDATA[linux virtual server]]></category>
		<category><![CDATA[load balancing]]></category>
		<category><![CDATA[lvs]]></category>
		<category><![CDATA[nat]]></category>
		<category><![CDATA[répartition de charge]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=367</guid>
		<description><![CDATA[LVS aka Linux Virtual Servers est la solution par défaut offerte par les distributions Linux en matière de Load Balancing. Cette solution permet de répartir la charge utilisateur sur une ferme de serveurs, assurant ainsi une granularité possible dans la montée en puissance et en charge de vos services internet mis à la disposition d&#8217;une population [...]]]></description>
			<content:encoded><![CDATA[<p>LVS aka <em><a href="http://www.linuxvirtualserver.org/" target="_blank">Linux Virtual Servers</a></em> est la solution par défaut offerte par les distributions Linux en matière de Load Balancing. Cette solution permet de répartir la charge utilisateur sur une ferme de serveurs, assurant ainsi une granularité possible dans la montée en puissance et en charge de vos services internet mis à la disposition d&#8217;une population de plus en plus grande.</p>
<p><span id="more-367"></span><strong><span style="text-decoration: underline;">1) Préconisations</span></strong></p>
<p><span style="text-decoration: underline;">1.1) Système</span></p>
<p>Les noyaux linux postérieurs à la version <em>2.2.14</em> intègrent les fonctionnalités LVS, si vous n&#8217;êtes pas à ce niveau, vous devrez patcher le kernel avec le module &#8220;IPVS&#8221; prévu pour votre distribition.</p>
<p>Généralement, les serveurs LVS sont doublés, en mode FailOver, et supervisés par un module chargé de faire la bascule du primaire vers le secondaire en cas de défaillance du primaire, en effet, rien ne sert par exemple d&#8217;avoir une ferme de serveurs Web si votre LVS ne fonctionne plus et que personne ne peut plus y accéder&#8230; Pour cela, il existe plusieurs solutions classiques telles que HeartBeat ou KeepAlived. Dans notre exemple, nous utiliserons <strong>KeepAlived</strong>.</p>
<p>Dans nos tests, nous avons utilisé une openSuSE 11.4 64bits (kernel 2.6.37) et qui intègre donc la fonctionnalité IPVS. Les serveurs LVS possèdent chacun trois cartes ethernet dont un couple est configuré pour le réseau de production en bonding et la troisième carte sert pour la gestion du FailOver du serveur LVS (protocole VRRP) avec l&#8217;utilitaire KeepAlived.</p>
<p><em>Téléchargements :</em></p>
<p style="padding-left: 30px;">- OpenSuSE : <a href="http://software.opensuse.org/114/fr">http://software.opensuse.org/114/fr</a></p>
<p style="padding-left: 30px;">- Doc LVS : <a href="http://www.linuxvirtualserver.org/Documents.html">http://www.linuxvirtualserver.org/Documents.html</a></p>
<p style="padding-left: 30px;">- IPVS (si kernel &lt; 2.2.14) : <a href="http://rpm.pbone.net/index.php3?simple=1&amp;stat=3&amp;search=ipvs">http://rpm.pbone.net/index.php3?simple=1&amp;stat=3&amp;search=ipvs</a></p>
<p style="padding-left: 30px;">- KeepAlived (optionnel) : <a href="http://www.keepalived.org/software/keepalived-1.2.2.tar.gz" target="_blank">http://www.keepalived.org/software/keepalived-1.2.2.tar.gz</a></p>
<p><span style="text-decoration: underline;">1.2) Matériel</span></p>
<p>Evidement plus votre machine est puissante mieux cela sera, cependant, il ne faut pas perdre à l&#8217;esprit que votre solution LVS se comportera à priori comme un switch (niveau 4 du modèle ISO), même si certains &#8220;patchs&#8221; peuvent l’amener à interagir au niveau 7.  A ce titre les interfaces réseaux doivent être le premier niveau de qualité, la CPU (nombre de processeurs / coeurs) le deuxième niveau.</p>
<p>Le premier travail d&#8217;un serveur LVS va consister en un routage, d&#8217;une adresse IP (adresse virtuelle, ou &#8220;IPV&#8221;) et un port connu du grand public et la redirection d&#8217;un flux réseau qui sera transmis, en fonction de la &#8220;charge&#8221; estimée sur les serveurs de la ferme et de sa disponibilité, vers le serveur le plus &#8220;disponible&#8221; (le moins chargé). L&#8217;analyse de la charge d&#8217;un serveur dépend d&#8217;un algorithme et demande donc de la CPU, mais la notion primaire demeure celle de la charge réseau, il vous appartient de l&#8217;estimer correctement.</p>
<p>Nous verrons qu&#8217;il existe plusieurs façons de déterminer la charge d&#8217;un serveur, de plus ou moins pertinentes, sachant que plus l’algorithme de détermination de charge est complexe plus vos serveurs LVS nécessiteront de la CPU, ne l&#8217;oubliez pas.</p>
<p>Dans le meilleur des mondes, des cartes Gb sur vos serveurs LVS ainsi que des machines avec un maximum de coeurs selon l&#8217;avis et le budget de votre DSI <img src='http://cx.cx/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong><span style="text-decoration: underline;">2) Configuration de LVS</span></strong></p>
<p><span style="text-decoration: underline;">2.1) LVS : un &#8220;switch&#8221; intelligent</span></p>
<p>Les fonctionalités de base de LVS sont de répondre à un client IP qui cherche à joindre un serveur sur une IP &#8220;&lt;ip&gt;&#8221; en dispatchant cette demande sur divers serveurs identiques et pouvant répondre à la demande. Les protocoles possibles sont tous ceux que TCP/IP ou UDP/IP peuvent proposer. La persistance de session est ainsi assurée par IPVS en fonction de l&#8217;adresse IP de l’émetteur de la demande (niveau 4), en d&#8217;autre termes, un internaute qui est dirigé vers le serveur n°X d&#8217;une ferme web à son premier accès sera de nouveau redirigé vers le même serveur lors des accès suivants grâce à LVS.</p>
<p>Nous allons donc indiquer à LVS, pour chaque IPV à gérer, quels sont les serveurs rééls et composant la ferme en face de cette adresse. Nous indiquerons de plus à LVS la méthode que celui-ci devra utiliser pour &#8220;estimer&#8221; la charge d&#8217;un serveur.</p>
<p>Le serveur LVS &#8220;primaire&#8221; de notre cluster de LVS en FailOver se nomme un <strong>DIRECTOR</strong>.</p>
<p><span style="text-decoration: underline;">2.2) Indiquer l&#8217;IPV de votre ferme à votre serveur LVS</span></p>
<p><em>Prenons le cas d&#8217;une ferme Web Classique basée sur 2 LVS en FailOver et 3 serveurs réels.</em></p>
<p>Il existe donc dans notre exemple 3 serveurs rééls, chacun avec une adresse IP réelle @1, @2 et @3. Cependant, hors de question de donner cette information aux internautes, pour eux, un seul serveur existe d&#8217;un point de vue extérieur avec une seule adresse IP @v, c&#8217;est l&#8217;adresse IP Virtuelle de votre ferme Web , ou IPV.</p>
<p>Cette IPV est (au moins) fixée au sein du serveur LVS grâce à l&#8217;utilitaire ipvsadm et les paquets arriveront donc en premier sur cette adresse avant d&#8217;être dispatchée sur l&#8217;un ou l&#8217;autre des serveurs réels.</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/schema_global.jpg"><img class="aligncenter size-full wp-image-388" title="schema_global" src="http://cx.cx/wp-content/uploads/2011/03/schema_global.jpg" alt="" width="279" height="382" /></a></p>
<p>Si l&#8217;adresse IP &#8220;virtuelle&#8221; pour joindre votre ferme web est 192.168.1.10, il faudra utiliser sur votre serveur LVS la commande suivante:</p>
<pre>shell&gt; ifconfig eth0:v0 192.168.1.10 netmask 255.255.255.0 broadcast 192.168.1.255 up</pre>
<p>Il faudra ensuite autoriser Linux à faire transiter les paquets d&#8217;une interface à d&#8217;autres interfaces (routage de l&#8217;IPV vers les IPR &#8211; ip réelles), il faut pour cela activer l&#8217;ip forwarding. Il faut également calibrer vos serveurs LVS pour qu&#8217;ils se comportent d&#8217;une certaine façon face au protocole ARP. La raison technique est décrite <a href="http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.arp_problem.html" target="_blank">dans cet article</a>, cela consiste grossièrement à éviter que vos serveurs LVS n&#8217;interceptent des paquets qui sont en fait destinés initialement aux serveurs réels.</p>
<p>Voici le contenu de /etc/sysctl.conf (à minima, à adapter selon votre configuration) :</p>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;">
<pre><strong>net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.all.promote_secondaries = 1
net.ipv4.conf.lo.forwarding=0
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2</strong></pre>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;"><span style="text-decoration: underline;">2.2) ipvsadm</span></p>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;">C&#8217;est le nom de l&#8217;utilitaire qui va (généralement) nous servir à configurer dynamiquement notre serveur LVS dynamiquement, il est apporté par les distributions aux kernels &gt; 2.2.14, et sera apporté par les rpm ipvs que vous aurez pris soin d&#8217;installer dans la négative. Sans cet utilitaire, vous ne pouvez pas configurer votre serveur LVS. Les utilitaires de configuration automatique tels que KeepAlived se basent eux aussi sur ipvsadm.</p>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;"><em>2.2.1) Indiquer la présence d&#8217;une IPV à votre serveur LVS:</em></p>
<pre><strong>shell&gt; ipvsadm --add-service --tcp-service <span style="color: #ff0000;">192.168.1.10:80</span> --scheduler <span style="color: #ff0000;">rr</span></strong></pre>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;">Ceci signifie que votre serveur LVS va accepter les paquets à destination de 192.168.1.10 sur le port 80 pour les transmettre aux serveurs réels que nous allons décrire ci-dessous.</p>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;">L&#8217;algorithme de répartition de charge ici est &#8220;&#8211;scheduler rr&#8221;, c&#8217;est à dire du Round Robin (Un pour Un). Nous verrons en 2.4 les différents algorithmes disponibles.</p>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;"><em>2.2.2) Indiquer la présence des 3 serveurs réels à LVS :</em></p>
<pre><strong>shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 -<span style="color: #ff0000;">-real-server 192.168.1.1:80</span> --masquerading --weight 10
shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 <span style="color: #ff0000;">--real-server 192.168.1.2:80</span> --masquerading --weight 10
shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 <span style="color: #ff0000;">--real-server 192.168.1.3:80</span> --masquerading --weight 10</strong></pre>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;"><span style="text-decoration: underline;">Explications: </span></p>
<ul>
<li><span style="line-height: 18px;"><strong>&#8211;tcp-service:</strong> les paquets transmis au serveur réel seront ceux qui arrivent sur l&#8217;IPV 192.168.1.10 et le port 80 du serveur LVS</span></li>
<li><span style="line-height: 18px;"><strong>&#8211;real-server</strong>: nos serveurs réels ont les @ip 192.168.1.1, 192.168.1.2 et 192.168.1.3, ils écoutent sur le port 80</span></li>
<li><span style="line-height: 18px;"><strong>&#8211;masquerading</strong>: le Director va utiliser le protocole NAT pour faire transiter les flux TCP avec les serveurs réels (voir 2.3.1)</span></li>
<li><span style="line-height: 18px;"><strong>&#8211;weight:</strong> notion de poids (de priorité pour le LoadBalancing)</span></li>
</ul>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;">Comme vous le découvrirez en 2.2.1) et en 2.2.2) , la route par défaut peut varier selon les configiurations, il se peut quand (comme dans 2.2.1) vous soyez obligé d&#8217;utiliser l&#8217;adresse du serveur LVS alors que dans d&#8217;autres cas (voir 2.2.2) vous deviez indiquer l&#8217;adresse IP de votre routeur / firewall.</p>
<p style="margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; line-height: 18px;">2.2.3) Vérifier la prise en compte des ordres tables ipvs</p>
<pre><strong>shell&gt; <span style="color: #ff0000;">ipvsadm --list</span></strong>

<strong>  IP Virtual Server version 1.2.1 (size=4096)</strong>

<strong>  Prot LocalAddress:Port Scheduler Flags</strong>

<strong>    -&gt; RemoteAddress:Port           Forward Weight ActiveConn InActConn</strong>

<strong>  <span style="color: #ff0000;">TCP  192.168.1.10:http rr persistent 360</span></strong>

<strong>   </strong><span style="color: #ff9900;"><strong> -&gt; 192.168.1.1:http              Route   1      </strong><span style="text-decoration: underline;"><span style="color: #ff0000;">2</span></span><strong>          0</strong></span>

<strong><span style="color: #ff9900;">    -&gt; 192.168.1.2:http              Route   1      0          0</span></strong>

<strong><span style="color: #ff9900;">    -&gt; 192.168.1.3:http              Route   1      0          0</span></strong>

<strong>  <span style="color: #ff0000;">TCP  192.168.1.10:https rr persistent 360</span></strong>

<strong>   <span style="color: #ff9900;"> -&gt; 192.168.1.1:https              Route   1      0          0</span></strong>

<strong><span style="color: #ff9900;">    -&gt; 192.168.1.2:https              Route   1      0          0</span></strong>

<strong><span style="color: #ff9900;">    -&gt; 192.168.1.3:https              Route   1      0          0</span></strong></pre>
<p>Nous voyons dans cet exemple que les paquets qui arriveront sur l&#8217;adresse ip virtuelle 192.168.1.10 sur le port 80 (http) seront redirigés selon la règle du Round Robin (rr) sur les serveurs de la ferme, l&#8217;un après l&#8217;autre.</p>
<p><span style="text-decoration: underline;">Remarque:</span> Nous avons refait les mêmes définition avec le port 443 (https) pour ls connexions sécurisées de notre fermer de serveurs Web.</p>
<p><span style="text-decoration: underline;">Remarque:</span> A l&#8217;instant où nous passons la commande &#8220;ipvsadm -l&#8221; sur notre Director, nous constatons que 2 sessions sont établies vers le serveur physique 192.168.1.1.</p>
<p><span style="text-decoration: underline;">2.3) Routage direct (DR) ou Translations d&#8217;adresses (NAT)</span></p>
<p>Il existe principalement deux méthodes pour établir un dialogue entre un serveur LVS et un serveur d&#8217;une ferme dont il est chargé d&#8217;assurer la balance de charge.</p>
<p>Une troisième méthode moins usitée est celle de l&#8217;établissement de tunnel entre les serveurs LVS et les serveurs réels (TUN), cette méthode n&#8217;est pas décrite dans cet article car très peu usitée, cf <a href="http://www.austintek.com/LVS/LVS-HOWTO/mini-HOWTO/LVS-mini-HOWTO-fr.html" target="_blank">DOC</a> en cas de besoin.</p>
<p>2.3.1) NAT (Network Address Translation)</p>
<p>Le mode NAT, le plus classique et le plus simple à mettre en oeuvre consiste à translater l&#8217;adresse IP cible (ipv) d&#8217;un paquet reçu par l&#8217;adresse réelle du serveur choisi par l&#8217;algorithme d&#8217;analyse de charge.</p>
<p>C&#8217;est le même principe que l&#8217;en rencontre dans tous les routeurs d&#8217;entreprise pur que les employés puissent sortir sur l&#8217;internet, le même principe que pour votre InternetBox personelle :</p>
<p style="text-align: center;"><a href="http://cx.cx/wp-content/uploads/2011/03/flux_nat1.jpg"><img class="aligncenter size-full wp-image-383" title="flux_nat" src="http://cx.cx/wp-content/uploads/2011/03/flux_nat1.jpg" alt="" width="568" height="346" /></a></p>
<p>Il est à noter que, en plus de demander au serveur LVS de gérer la balance de charge, nous allons lui demander en permanence de retoucher les trames TCP/IP afin d’effectuer la translation de la VIP vers toutes les adresses réelles, ce qui peut s&#8217;avérer gourmand en CPU, à surveiller de près.</p>
<p><span style="text-decoration: underline;">Remarque:</span> Dans le cas où vous opteriez pour le NAT, il ne faudra pas oublier d&#8217;indiquer à tous les serveurs de votre ferme que la route par défaut est le Director, à savoir la patte LAN de votre serveur LVS.</p>
<p><span style="text-decoration: underline;">Remarque:</span> Un exemple d&#8217;implémentation de serveur LVS avec le protocole NAT est décrit dans l&#8217;exemple ci-dessus en 2.2.2).</p>
<p>2.3.2) DR (Direct Routing)</p>
<p><em>2.3.2.a) Présentation</em></p>
<p>Le mode DR, comme son nom le suggère, ne va pas utiliser de translation d&#8217;adresse mais va faire suivre les paquets directement au serveur désigné comme idéal par l&#8217;algorithme d&#8217;analyse de charge. Une fois le paque traité par le serveur réel, celui-ci ne va pas renvoyer la réponse au serveur LVS qui n&#8217;en a que faire mais va directement la transmettre à sa gateway comme le montre le schéma ci dessous :</p>
<p style="text-align: center;"><a href="http://cx.cx/wp-content/uploads/2011/03/flux_dr.jpg"><img class="aligncenter size-full wp-image-384" title="flux_dr" src="http://cx.cx/wp-content/uploads/2011/03/flux_dr.jpg" alt="" width="533" height="341" /></a></p>
<p>On allège ainsi le LVS de la gestion de tous les flux de retour et de la gestion des translations d&#8217;adresses, c&#8217;est largement plus performant et donc c&#8217;est l&#8217;option qui doit être considérée en premier.</p>
<p>Pour indiquer à votre serveur LVS qu&#8217;un serveur doit répondre au protocole DR, vous devrez l&#8217;indiquer à ipvsadm avec la commande:</p>
<pre><strong>shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 --real-server 192.168.1.1:80 --gatewaying --weight 10
shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 --real-server 192.168.1.2:80 --gatewaying --weight 10
shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 --real-server 192.168.1.3:80 --gatewaying --weight 10</strong></pre>
<p><em>2.2.2.b) Problématique du routage</em></p>
<p>Nous sommes donc dans ce cas là dans une problématique de routage pur. Le serveur LVS va router le paquet ayant pour adresse cible l&#8217;IPV vers un des serveurs rééls, c&#8217;est là que les ennuis commencent : étant donné que l&#8217;adresse cible est l&#8217;IPV et que le serveur réel possède une autre adresse ip, l&#8217;adresse IP réelle,il va en toute logique refuser le paquet. Pour pallier à ce problème, nous allons simplement rajouter, sur tous les serveurs rééls de la ferme, une adresse ip secondaire (alias) qui sera l&#8217;IPV. Attention, il ne faut surtout pas rajouter cet alias à une carte ethernet du serveur car auquel cas, des trames sortiront sur le réseau (brodcast) de tous les serveurs avec la même IPV, vous aurez alors des conflits d&#8217;IP sur tout le média =&gt; catastrophe, plus rien ne fonctionnera.</p>
<p>Pour pallier à ce problème, il suffit d&#8217;ajouter l&#8217;alias à la loopback qui ne s&#8217;annonce pas sur les réseaux par définition mais qui permettra à un serveur réel de considérer que un paque à destination de l&#8217;IPV est bien pour lui.</p>
<p>Généralement, il suffit d&#8217;aller modifier le fichier /etc/sysconfig/network/ifcfg-lo tel que :</p>
<pre>
<div id="_mcePaste"><strong>#DESC de l'IPV de votre ferme :</strong></div>
<div id="_mcePaste"><strong>IPADDR_0=192.168.1.10  </strong><strong>                </strong></div>
<div id="_mcePaste"><strong>NETMASK_0=255.255.255.255
NETWORK_0=192.168.1.0
BROADCAST_0=192.168.1.255</strong></div>
<div id="_mcePaste">#----------------------------------
<em>IPADDR=127.0.0.1
NETMASK=255.0.0.0
NETWORK=127.0.0.0
BROADCAST=127.255.255.255
STARTMODE=onboot
USERCONTROL=no
FIREWALL=no</em></div>
</pre>
<p><span style="text-decoration: underline;">Remarque:</span> Dans le cas où vous opteriez pour le DR, il ne faudra pas oublier d&#8217;indiquer à tous les serveurs de votre ferme que la route par défaut est l&#8217;adresse IP de la patte interne de votre routeur / firewall.</p>
<p><span style="text-decoration: underline;">2.3) Algorithmes d&#8217;analyse de charge (RR, WRR, &#8230;)</span></p>
<p>Un algorithme de répartition de charge est à indiquer à votre serveur LVS lorsque vous créez une IPV (un cluster) grâce au commutateur &#8211;scheduller (voir 2.2.1))</p>
<p>Les algorithmes d&#8217;analyse de répartition de charge des IPVS sont larges, en voici un bref descriptif des plus usités:</p>
<li style="padding-left: 30px;"><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; line-height: 21px;">rr (<em>Round-Robin):</em> Répartition 1 pourt 1. Un internaute par serveur à tour de role, c&#8217;est la distribution équitable des demandes sur les serveurs, la plus basique et la moins gourmande.</span></li>
<li style="padding-left: 30px;"><em>wrr (Weighted Round-Robin): </em>Même répartition que &#8220;rr&#8221; mais en donnant plus de charge aux serveurs affectés de poids supérieurs.</li>
<li style="padding-left: 30px;"><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; line-height: 21px;">lc (<em>Least Connected): </em>La répartition de charge s&#8217;éffectue sur le mode rr mais en prenant en compte prioritairement les serveurs qui possèdent le moins de connexions actives à un instant &#8220;t&#8221;.</span></li>
<li style="padding-left: 30px;"><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; line-height: 21px;">wlc (<em>Weighted Least Connected): </em></span>Même répartition que &#8220;lc&#8221; mais en donnant plus de charge aux serveurs affectés de poids supérieurs.</li>
<p>D&#8217;autres algorithmes plus rares d&#8217;utilisation existent, consulter <a href="http://www.linuxvirtualserver.org/Documents.html" target="_blank">la doc</a> pour plus d&#8217;informations <img src='http://cx.cx/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><span style="text-decoration: underline;">Rappel:</span> le protocole d&#8217;analyse de charge est à utiliser avec ipvsadm lors de la définition d&#8217;un Cluster sur le Director et en fin de commande (voir 2.2.1)</p>
<p><span style="text-decoration: underline;">2.4) LVS /FailOver :</span></p>
<p>Evidement, si votre serveur de répartition de charge ne répond plus, quelle qu&#8217;en soit la raison, inutile d&#8217;avoir une ferme de site web en dessous si votre solution de HA s&#8217;arrête ici. Pour pallier à cela, il vous faut installer une couche supplémentaire qui gère cette notion de Haute Disponibilité et la possibilité de démarrer rapidement dynamiquement un serveur secondaire si le primaire ne répond plus. Deux grandes voies se dessinent : HeartBeat et KeepAlived. Pour des raisons purement subjectives nous avons choisi <strong><span style="text-decoration: underline;">KeepAlived</span></strong> alors que HeartBeart rempli strictement le même rôle&#8230; Il fallait bien en choisir un <img src='http://cx.cx/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>KeepAlived apporte la configuration automatique du serveur LVS, et oui, tout ce que vous avez lu est à mettre à la poubelle, c&#8217;était pour tester votre attention <img src='http://cx.cx/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  (envoyer les insultes à <em>contact@edfgdf.fr</em> svp, c&#8217;est très tendance).</p>
<p>En fait KeepAlived apporte la configuration automatique du serveur et la gestion d&#8217;un serveur en FailOver de votre Director, ce qui vous permet aisément d&#8217;assurer totalement la haute disponibilité de vos services TCP/IP.</p>
<p>2.4.1) Téléchargement</p>
<ul>
<li><span style="line-height: 18px;">KeepAlived  :<a href="http://www.keepalived.org/software/keepalived-1.2.2.tar.gz" target="_blank"> http://www.keepalived.org/software/keepalived-1.2.2.tar.gz</a></span></li>
</ul>
<p>2.4.2) Installation</p>
<p>Décompressez l&#8217;archive dans un répertoire temporaire :</p>
<pre>shell&gt; cd /datas/downloads/
shell&gt; tar -zxvf keepalived-1.2.2.tar.gz</pre>
<p>Compilez les fichiers objets en indiquant le repertoire d&#8217;installation avec</p>
<pre>shell&gt; ./configure --prefix=/data/keepAlived/</pre>
<p>Vous pouvez rencontrer des erreurs à ce statde, elle ne concernent généralement que des packages manquant mais nécessaires dans votre distribution, ne les négilgez pas au risque de dysfonctionnements ultérieurs.</p>
<p>Linkez et terminez votre installation par</p>
<pre>shell&gt; make

...

shell&gt; make install

...</pre>
<p>Voilà, KeepAlived est installé &#8230;</p>
<p>L&#8217;install vous amène les fichiers suivants:</p>
<ul>
<li><span style="line-height: 18px;">keepalived et son fichier de conf keepalived.conf (placez le de preference dans /etc/keepalived/)</span></li>
<li><span style="line-height: 18px;">./rc.d/keepalied pour le fichier d&#8217;init de init.d (places le dans /etc/init.d/rc3.d et créez les liens)</span></li>
<li><span style="line-height: 18px;">genhash (un utilitaire md5 pour keepalived afin de vérifier le contenu de certains flux retournés)</span></li>
</ul>
<p>A vous de disposer ces fichiers dans vos répertoires préférés pour que tout fonctionne bien.</p>
<p>2.4.3) Utilisation</p>
<p>Tout se trouve dans la configuration (élémentaire) de /etc/keepalived/keepalived.conf.</p>
<p>2.4.3.a) Configuration globales</p>
<p>Les configurations globales de keepAlived consistent principalement en la définition d&#8217;un nom (ID) pour votre serveur LVS Director et quelques informations pour envoyer des emails d&#8217;alertes tel que :</p>
<pre>global_defs {
   notification_email {
     admin1@domaine.com admin2@domaine.com
   }
   notification_email_from director-1@domaine.com
   smtp_server smtp.domaine.com
   smtp_connect_timeout 30
   router_id LVS1
}</pre>
<p>routeur_id doit être unique sur les différents serveurs LVS que vous allez configurer et qui vont composer votre cluster en FailOver. Les autres paramètres sont triviaux.</p>
<p>2.4.3.b) Configuration du protocole de surveillance du FailOver (VRRP)</p>
<pre>vrrp_instance VRRP1 {
    <span style="color: #ff6600;">state MASTER</span>
    interface eth0
    virtual_router_id 50
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 6841665145
    }
    virtual_ipaddress {
        192.168.1.10
    }
}</pre>
<div>Voici un bref descriptif de ces paramètres:</div>
<ul>
<li><span style="line-height: normal;"><strong>state</strong>: MASTER ou BACKUP, il définit le serveur primaire (actif) de vos serveurs LVS, c&#8217;est grâce à cette information que KeepAlived saura basculer sur un serveur esclave si le master ne répond plus.</span></li>
<li><span style="line-height: normal;"><strong>interface</strong>: quelle est l&#8217;interface réseau </span><span style="text-decoration: underline;">dédiée </span><span style="line-height: normal;">à la surveillance du cluster en VRRP. On évite de positionner l&#8217;interface de production afin de ne pas perturber les temps de réponse et de déclencher une bascule à tort.</span></li>
<li><span style="line-height: normal;"><strong>virtual_router_id</strong>: un numéro <span style="text-decoration: underline;">UNIQUE</span> pour l&#8217;ensemble de vos serveurs LVS</span></li>
<li><span style="line-height: normal;"><strong>priority</strong>: Désirez-vous basculer prioritairement vers un serveur plustôt qu&#8217;au autre en cas d&#8217;echec VRRP? Si non, mettez la même valeur dans tous les serveurs LVS.</span></li>
<li><strong>authentication</strong><span style="line-height: normal;">: un login / pass pour que les serveurs dialogue en VRRP de façon sécurisée entre eux (il doit être identique de partout évidement&#8230;)</span></li>
<li><span style="line-height: normal;"><strong>virtual_ipadress</strong>: le nom est assez parlant, l&#8217;IPV ou les IPV de votre serveur LVS</span></li>
</ul>
<div>2.4.3.c) Configuration d&#8217;un serveur virtuel et de ses serveurs rééls associés</div>
<div>Nous allons prendre comme exemple un serveur virtuel répondant sur l&#8217;IPV <strong>192.168.10.10</strong> et qui fait du load balancing en <strong>Round Robin</strong> sur 3 serveurs physiques,</div>
<div>
<ul>
<li><span style="line-height: normal;">192.168.1.1</span></li>
<li><span style="line-height: normal;">192.168.1.2</span></li>
<li><span style="line-height: normal;">192.168.1.3</span></li>
</ul>
</div>
<div>Le service est celui d&#8217;une ferme Web, il faut donc laisser passer les protocoles <strong>HTTP </strong>(port 80) et <strong>HTTPS </strong>(port 443).</div>
<div>Dans cette première version, nous allons considérer que un serveur réel est &#8220;up&#8221; si on peut se connecter dessus sur le port 80 (nous verrons d&#8217;autres méthodes plus fines plus loin):</div>
<pre>virtual_server <span style="color: #339966;"><strong>192.168.1.10 80</strong></span> {

        delay_loop 10
        <span style="color: #ff6600;">lb_algo RR</span>
        <span style="color: #ff6600;">lb_kind DR</span>
        <span style="color: #ff6600;">persistence_timeout 360</span>
        protocol TCP

        <span style="color: #339966;"><strong>real_server 192.168.1.1 80</strong></span> {
                weight 1
		<span style="color: #ff6600;">TCP_CHECK</span> {
			<span style="color: #ff6600;">connect_port    80</span>
			connect_timeout 3
		}
        }

        <strong><span style="color: #339966;">real_server 192.168.1.2 80</span></strong> {
                weight 1
		<span style="color: #ff6600;">TCP_CHECK {
			connect_port    80</span>
			connect_timeout 3
		}
        }

        <strong><span style="color: #339966;">real_server 192.168.1.3 80</span></strong> {
                weight 1
		<span style="color: #ff6600;">TCP_CHECK {
			connect_port    80</span>
			connect_timeout 3
		}
        }
}</pre>
<p><span style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', verdana, arial, Tahoma, Verdana, sans-serif; white-space: normal;">Voici un bref descriptif de ces paramètres:</span></p>
<ul>
<li><span style="line-height: 18px;"><strong>virtual_server</strong>: l&#8217;adresse IP Virtuelle de votre serveur virtuel et son port d&#8217;écoute</span>
<ul>
<li><span style="line-height: 18px;"><strong>delay loop</strong>: intervalle en secondes entre les différents tests de présence des serveurs réels</span></li>
<li><span style="line-height: 18px;"><strong>protocol</strong>: ici on utilise TCP (on peut aussi utiliser UDP dans certains cas)</span></li>
<li><span style="line-height: 18px;"><strong>lb_algo</strong>: algorithme de LoadBalancing (rr, wrr, dr, wdrr, &#8230; : voir 2.4))</span></li>
<li><span style="line-height: 18px;"><strong>lb_kind</strong>: méthode de routage (NAT ou DR, voir 2.3))</span></li>
<li><span style="line-height: 18px;"><strong>real_server</strong>: définition d&#8217;un serveur réél dans cette ferme, adresse réelle et port d&#8217;écoute</span>
<ul>
<li><span style="line-height: 18px;"><strong>weight:</strong> poids du serveur pour load balancing </span></li>
<li><strong>tcp_check</strong><span style="line-height: 18px;">: on va régulièrement vérifier que le port 80 de ce serveur réel répond, et, au bout de 3 secondes en echec, on considère que le serveur est mort, le serveur LVS va alors l&#8217;éliminer dynamiquement de la ferme jusqu&#8217;à ce que celui-ci réponde de nouveau.</span></li>
</ul>
</li>
</ul>
</li>
</ul>
<div><span style="line-height: 18px;">Nous avions dit plus haut que notre ferme doit répondre en HTTP et en HTTPS, il suffit donc de recopier ce fichier de conf et d&#8217;y rajouter les mêmes lignes en substituant 80 par 443, c&#8217;est tout &#8230;</span></div>
<div><span style="line-height: 18px;">2.4.3.d) Comment vérifier qu&#8217;un serveur réel répond toujours ?</span></div>
<div><span style="line-height: 18px;">Comme nous l&#8217;avons vu en 2.4.3.c) dans chaque real_server nous avons la possibilité d&#8217;utiliser la config &#8220;TCP_CHECK&#8221; pour vérifier qu&#8217;un serveur http répond correctement, mais ceci se limite à une connexion sur le port 80, un code retour HTTP/200 et un code retour HTTP/500 sont deux succès au sens de l&#8217;établissement de la connexion, mais pourtant dans un cas le serveur répond normalement, dans l&#8217;autre, il provoque un plantage général &#8230;</span></div>
<div><span style="line-height: 18px;">Voici d&#8217;autres méthodes plus pertinentes:</span></div>
<div>
<ul>
<li><span style="line-height: 18px;"><strong>HTTP_GET</strong>: Vous pourrez établir une connexion sur le port 80, récupérer une page de votre site web et en vérifier le contenu, ce qui est largement plus recommandé dans le cadre d&#8217;une Ferme Web que TCP_CHECK</span></li>
<li><span style="line-height: 18px;"><strong>SSL_GET</strong>:Même chose que HTTP_GET mais pour le protocole HTTPS</span></li>
<li><span style="line-height: 18px;"><strong>MISC_CHECK</strong>: Vous permet de définir des tests personalisés</span></li>
</ul>
</div>
<p><span style="text-decoration: underline;">Exemple HTTP_GET:</span></p>
<p>C&#8217;est l&#8217;algorithme MD5 qui va nous permettre de vérifier que le contenu d&#8217;une page ne varie pas et est réglementaire. Prenez par exemple la page /test.php de votre site web, faite lui faire une connexion à votre database, une opération élémentaire en php afin que le résultat présente par exemple &#8220;TRUE&#8221; en cas de réussite ou &#8220;FALSE&#8221; en cas d&#8217;echec.</p>
<p>Utilisez l&#8217;utilitaire genhash pour calculer le hash MD5 de ce retour http avec la commande suivante :</p>
<pre><span style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', verdana, arial, Tahoma, Verdana, sans-serif; white-space: normal;">
shell&gt; genhash -s 192.168.1.1 -p 80 -u /test.php

shell&gt; 53f43f0f4f1c99c10230f5f0758915f1
</span></pre>
<p>Ici, la clé MD5 du résultat de cette page test est donc &#8220;53f43f0f4f1c99c10230f5f0758915f1&#8243;. Il faut que ce fichier soit évidement sur chaque serveur réel de votre ferme.</p>
<p>Vous devez donc simplement remplacer la clause TCP_CHECK (voir 2.4.3.c)) par celle-ci:</p>
<p><span style="line-height: normal;"> </span></p>
<pre style="font: normal normal normal 12px/normal 'Courier New', Courier, 'Lucida Console', Monaco, 'DejaVu Sans Mono', 'Nimbus Mono L', 'Bitstream Vera Sans Mono', monospace; overflow-x: auto; overflow-y: auto; white-space: pre-wrap; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; margin-top: 0.25em; margin-right: 0px; margin-bottom: 0.75em; margin-left: 0px; background-position: initial initial; background-repeat: initial initial; padding: 10px; border: 1px solid #dddddd;">HTTP_GET {

<span style="white-space: pre;">		</span>url {

<span style="white-space: pre;">		</span>     path /test.php

<span style="white-space: pre;">		</span>     digest 53f43f0f4f1c99c10230f5f0758915f1

<span style="white-space: pre;">	</span>}

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 2

}</pre>
<p>Le descriptif des paramètre est trivial &#8230; On va essayer d&#8217;aspirer http://192.168.1.1:80/test.php avec un timeout de 3 secondes et nous allons réessayer 3 fois par intevalle de 2 secondes avant de considérer un echec. Une réussite est vraie si le checksum MD5 du contenu retourné est conforme à la clé indiqué par &#8220;digest&#8221;.</p>
<p>Le test GET_HTTPS se configure de la même façon.</p>
<p>Exemple MISC_CHECK:</p>
<p>Imaginez que l&#8217;indication de conne santé d&#8217;un serveur réel dépende du déclanchement d&#8217;un script (qui doit retourner 1 en cas de bon fonctionnement et 0 en cas d&#8217;echec), alors la clause HTTP_CHECK sera replacée par :</p>
<pre><span style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', verdana, arial, Tahoma, Verdana, sans-serif; white-space: normal;">
MISC_CHECK {

<span style="white-space: pre;">	</span>misc_path /data/scripts/mon_script.sh param1 param2

}
</span></pre>
<p><span style="line-height: normal;">Assez simple à priori <img src='http://cx.cx/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </span></p>
<p><span style="line-height: normal;">2.4.4) Gestion d&#8217;un serveur LVS secondaire (&#8220;backup&#8221;) :</span></p>
<p><span style="line-height: normal;"><br />
</span></p>
<p>Dans le cadre d&#8217;un cluster en FailOver, il faut au moins un deuxième serveur LVS, sachant que vous pouvez sécuriser l&#8217;ensemble à plus que 2 serveurs dans le cluster (parano quand tu nous tiens &#8230;).</p>
<p>Pour ce faire, rien d&#8217;extraordinaire, il suffit simplenent de disposer d&#8217;une deuxième serveur à l&#8217;identique en configuration du Director et d&#8217;apporter les modifications suivantes au fichier /etc/keepalived/keepalived.conf :</p>
<pre>vrrp_instance VRRP2 {
    <strong><span style="color: #ff6600;">state BACKUP</span></strong>
    interface eth0
    <strong><span style="color: #ff6600;">virtual_router_id 51</span></strong>
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 6841665145
    }
    virtual_ipaddress {
        192.168.1.10
    }
}</pre>
<div>Le mot clé &#8220;BACKUP&#8221; va indiquer que ce serveur est potentiellement habilité à prendre la place du MASTER Director en cas de panne avérée. N&#8217;oubliez pas d&#8217;affeter un virtual_router_id différent et unique pour tous les serveurs LVS, MASTER et BACKUP(s) &#8230;</div>
<div></div>
<p><span style="line-height: normal;"><span style="text-decoration: underline;"><strong>3) Utilisation de LVS et monitoring</strong></span></span></p>
<div><span style="text-decoration: underline;"><strong><br />
</strong></span></div>
<div>Si vous avez bien fait les choses, il vous suffiera de déclencher votre script d&#8217;init /etc/init.d/keepalived start pour que, en fonction du contenu de /etc/keepalived/keepalived.conf, KeepAlived configure votre serveur LVS avec la commande ipvsadm mais le tout entièrement dynamiquement&#8230; Un vrai plaisir.</div>
<div>Vérifiez que tout va bien avec &#8220;ipvsadm &#8211;list&#8221;, vous devriez voir apparaître un écran qui ressemble à celui montré en 2.2.3) et indiquant que tout va bien.</div>
<div>Faites des tests élémentaires (extinction d&#8217;un serveur réel, extinction du LVS MASTER, &#8230;) pour vérifier que tout est ok et que tous les comportements sont correctement configurés.</div>
<div>Vous disposez maintenant d&#8217;une FermeWeb Load Balancée!</div>
<div>Evidement cet article n&#8217;est qu&#8217;une présentation sommaire de IPVS/KEEPALIVED, si vous désirez de plus amples informations, rendez vous sur <a href="http://www.linuxvirtualserver.org/"><strong>http://www.linuxvirtualserver.org</strong></a> et <a href="http://www.keepalived.org/"><strong>http://www.keepalived.org</strong></a> !</div>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/03/23/repartiteur-de-charge-lvs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ignite : Une alternative à la DBConsole</title>
		<link>http://cx.cx/2011/02/26/ignite-une-alternative-a-dbconsole-enterprise/</link>
		<comments>http://cx.cx/2011/02/26/ignite-une-alternative-a-dbconsole-enterprise/#comments</comments>
		<pubDate>Sat, 26 Feb 2011 19:00:23 +0000</pubDate>
		<dc:creator>xavier</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=320</guid>
		<description><![CDATA[Dans de nombreux cas, les entreprises ne peuvent pas se &#8220;payer&#8221; la version Enterprise d&#8217;Oracle et sont réduites à utiliser une version &#8220;Standard&#8221;. Outre les importantes limitations physiques et logiques imposées telles Deux sockets maximum par serveur Pas de DataGuard autorisé Pas d&#8217;Oracle Streams autorisé (même si ce n&#8217;est pas vraiment un cadeau&#8230;) Pas de [...]]]></description>
			<content:encoded><![CDATA[<p>Dans de nombreux cas, les entreprises ne peuvent pas se &#8220;payer&#8221; la version Enterprise d&#8217;Oracle et sont réduites à utiliser une version &#8220;Standard&#8221;. Outre les importantes limitations physiques et logiques imposées telles</p>
<ul>
<li><span style="line-height: 18px;"><em>Deux sockets maximum par serveur</em></span></li>
<li><span style="line-height: 18px;"><em>Pas de DataGuard autorisé</em></span></li>
<li><span style="line-height: 18px;"><em>Pas d&#8217;Oracle Streams autorisé (même si ce n&#8217;est pas vraiment un cadeau&#8230;)</em></span></li>
<li><span style="line-height: 18px;"><em>Pas de sauvegarde incrémentales Rman possibles</em></span></li>
<li><span style="line-height: 18px;"><em>Pas de flashback database possible</em></span></li>
<li><span style="line-height: 18px;"><em>Pas de partitionnement autorisé</em></span></li>
<li><span style="line-height: 18px;"><em>Pas de &#8230; pas de &#8230; etc  (et il en reste &#8230;)</em></span></li>
</ul>
<p><span style="line-height: 18px;">Autrement dit, la pluspart des innovations apportées en 10g sont interdites en version &#8220;standard&#8221;. Au delà de ces nombreuses limitations (non exhaustives), Oracle vous interdit de plus l&#8217;achat et/ou l&#8217;utilisation des Options Pack(<span style="text-decoration: underline;">qui sont pourtant installés par défaut</span> lorsque vous installez une version &#8220;standard&#8221; ce qui est limite illégal de la part d&#8217;Oracle) , à savoir :</span></p>
<ul>
<li><span style="line-height: 18px;"><strong><em>Diagnostick Pack</em></strong></span></li>
<li><span style="line-height: 18px;"><strong><em>Tunnig Pack</em></strong></span></li>
<li><span style="line-height: 18px;"><strong><em>Configuration Pak</em></strong></span></li>
</ul>
<p><span style="line-height: 18px;">Autrement dit, la DBConsole ne vous sert à quasiment à  &#8221;<span style="text-decoration: underline;">rien</span>&#8220;, <em>l&#8217;onglet &#8220;Performances&#8221; est grisé,</em> et vous devez, comme toute version antérieure à 10g, confectionner vous même tous les outils de surveillance&#8230; </span></p>
<p>Pour pallier à ce manque, il existe d&#8217;autres solutions, du moins en terme de monitoring et de l&#8217;analyse des performances de votre database, de tunning. Nous allons nous intéresser dans cet article au remplacement des Packs Oracle &#8220;Diagnostic&#8221; et &#8220;Tunning&#8221; pour lesquels d&#8217;exellentes alternatives existent, notamment &#8220;<a href="http://www.confio.com/English/Products/Ignite_for_Oracle.php" target="_blank"><strong>IGNITE for Oracle</strong></a>&#8221; de la société <a href="http://www.confio.com" target="_blank">Confio</a>.</p>
<p><span id="more-320"></span></p>
<p><strong>1) Introduction: </strong></p>
<p>Vous aurez malheureusement le loisir de constater que ce logiciel est loin d&#8217;être gratuit mais il constitue malgré tout une économie énorme comparée au prix de l&#8217;Entreprise Oracle selon votre configuration matérielle.</p>
<p>Le logiciel s&#8217;installe avec une facilité déconcertante. Celui-ci est basé sur un référentiel stoqué dans une database Oracle (pas celle qu&#8217;il faut surveiller évidement) et d&#8217;un accès aux vues systèmes de la database à surveiller afin de stoquer régulièrement l&#8217;état de l&#8217;ensemble des objets de l&#8217;instance.</p>
<p><span style="text-decoration: underline;">Remarque:</span> Ignite a une très grande possibilité d&#8217;historisation des données, de fabrication de report, etc, et vous permettra rapidement de fournir les éléments nécessaires dont les développeurs auront besoin pour corriger un problème de performance par exemple.</p>
<p>Ignite est joignable par l&#8217;intermédiaire d&#8217;un site web qui vous permettra d&#8217;observer l&#8217;activité de votre database en direct ou sur des périodes données.</p>
<p>Afin de rendre totalement indépendante la prise de mesure de l&#8217;état de la machine qui héberge votre database à surveiller, nous allons installer le référentiel Ignite (un simple schéma Oracle) sur une autre database située sur une autre machine que la machine de production. Ainsi, même en cas de grave problème sur la machine de production, vous pourrez tout de même interroger Ignite.</p>
<p><span style="text-decoration: underline;"><strong>2) Périmètre</strong></span></p>
<p><span style="text-decoration: underline;">2.1) Introduction:</span></p>
<p>Dans notre exemple, la machine<span style="text-decoration: underline;"> Oracle de production est une machine physique de 64G de RAM et 12 cores</span>, c&#8217;est en fonction de cette &#8220;puissance&#8221; que vous paierez plus ou moins cher votre licence Ignite, un peu à la sauce Oracle, mais en moins cher évidement&#8230;</p>
<p>Pour ne pas rajouter au coût, nous avons choisi d&#8217;installer le produit sur une <span style="text-decoration: underline;">openSuSE 11.3 (32bits)</span> qui exploitera un référentiel basé sur ce même OS à travers un <span style="text-decoration: underline;">Oracle XE 10gR2</span>. Le tout tournera sous une VM installée sur le serveur de votre choix (des solutiçons de virtualisations de tout niveau existent maintenant dans toutes les entreprises), cette solution ne coûtera donc pas un sous de plus que le prix du produit lui même.</p>
<p><span style="text-decoration: underline;">2.2) Téléchargements:</span></p>
<ul>
<li><span style="line-height: 18px;">openSuSE 11.3 / 32b: <a href="http://software.opensuse.org/113/fr" target="_blank">http://software.opensuse.org/113/fr</a></span></li>
<li>oraRun: <a href="http://ftp.novell.com/partners/oracle/sles-10/orarun.rpm" target="_blank">http://ftp.novell.com/partners/oracle/sles-10/orarun.rpm</a></li>
<li>Oracle XE 10gR2: <a href="http://www.oracle.com/technetwork/database/express-edition/downloads/102xelinsoft-102048.html">http://www.oracle.com/technetwork/database/express-edition/downloads/102xelinsoft-102048.html</a></li>
<li><span style="line-height: 18px;">Ignite: <a href="http://www.confio.com/English/Products/Ignite_for_Oracle.ph">http://www.confio.com/English/Products/Ignite_for_Oracle.ph</a>p</span></li>
</ul>
<p>Donc : l&#8217;OS + Oracle Express + le produit, c&#8217;est tout !</p>
<p><span style="text-decoration: underline;">Remarque: </span>Oracle XE, de par ses limitations, vous impose une limitation à 1 core et 1024M de RAM pour calibrer votre VM, c&#8217;est pour cela que il n&#8217;existe pas de version 64bits, n&#8217;installez donc pas un OS 64 bits, vous ne rencontrerez que des problèmes inutiles&#8230;</p>
<p><span style="line-height: 18px;"><strong><span style="text-decoration: underline;">3) Installation &amp; configuration</span></strong></span></p>
<p><span style="line-height: 18px;"><span style="text-decoration: underline;">3.1) Installation de OpenSuSE 11.3 32b</span></span></p>
<p>L&#8217;installation de l&#8217;openSuSE 11.3 ne nécessite strictement aucune compétence particulière, suivez l&#8217;assistant d&#8217;installation qui vous guidera de façon parfaite.</p>
<p>Une petite recommandation sur le partitionnement cependant:</p>
<pre>
<li><span style="line-height: 18px;">/                &lt;= 6Gb:  largement suffisant pour la racine (n'installez rien de superflu)</span></li>
<li><span style="line-height: 18px;">/var/log         &lt;= 2Gb:  pour ne pas géner les applications en cas de logging excessif</span></li>
<li><span style="line-height: 18px;">/usr/lib/oracle  &lt;= 3Gb:  par défaut le répertoire d'install de Oracle XE</span></li>
<li><span style="line-height: 18px;">/datas           &lt;= 5Gb:  vos archives (max 1gb) et votre database (max 4gb en XE)</span></li>
</pre>
<p><span style="line-height: 18px;"><br />
</span></p>
<p><span style="line-height: 18px;"><span style="text-decoration: underline;">3.2) Installation de &#8220;OraRUN&#8221;</span></span></p>
<p><span style="line-height: 18px;">Ce package disponible pour les SLESS et les openSuSE est optionnel mais est bien pratique, il vous paramètrera par défaut toutes les préconisations Oracle liées à votre OS, inutile d&#8217;aller mettre les mains dans sysctl.conf, etc. </span></p>
<p><span style="line-height: 18px;">Vous pouvez ne pas l&#8217;installer et configurer vous mêmes les prérequis, à vous de voir.</span></p>
<pre><span style="font-family: 'Lucida Grande', 'Lucida Sans Unicode', verdana, arial, Tahoma, Verdana, sans-serif; font-size: x-small;"><span style="line-height: 18px; white-space: normal;">&gt; </span></span>rpm -ivh /datas/downloads/orarun.rpm
&gt; chkconfig 35 oracle
&gt; rcoracle start</pre>
<p><span style="line-height: 18px;"><br />
</span></p>
<p><span style="line-height: 18px;"><span style="text-decoration: underline;">3.3) Installation de Oracle XE</span></span></p>
<p>Si vous n&#8217;avez pas installé OraRun comme indiqué précédement:</p>
<p style="padding-left: 30px;"><strong>a</strong> &#8211; Créez un user &#8220;<strong>oracle</strong>&#8221; ayant pour home dir &#8220;<strong>/home/oracle</strong>&#8221; et appartenant aux deux groupes à créer également que sont &#8220;<strong>dba</strong>&#8221; et &#8220;<strong>oinstall</strong>&#8220;.</p>
<p style="padding-left: 30px;"><strong>b</strong> &#8211; Affectez le user oracle et le groupe dba à /home/oracle.</p>
<p style="padding-left: 30px;"><strong>c</strong> &#8211; editez le fichier /etc/profile et ajoutez à la fin les lignes suivantes:</p>
<pre style="padding-left: 60px;">export ORACLE_BASE=/usr/lib/oracle
export ORACLE_HOME=$ORACLE_BASE/xe/app/oracle/product/10.2.0/server
export ORACLE_SID=XE</pre>
<pre style="padding-left: 60px;">export PATH=$PATH://usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin</pre>
<p style="padding-left: 90px;">
<p>Installez la version téléchargée de XE telle avec :</p>
<pre><span style="line-height: 18px;">&gt; rpm -ivh /datas/downloads/oracle-xe-10.2.0.1-1.0.i386.rpm
</span><span style="line-height: 18px;">&gt; ...
</span><span style="line-height: 18px;">&gt; /etc/init.d/oracle-xe  configure
</span><span style="line-height: 18px;"><em>&gt; ... <span style="color: #999999;">(laissez toutes les options par défaut)</span>
</em></span>&gt; /etc/init.d/oracle-xe  start</pre>
<p><span style="line-height: 18px;">Vérifiez que votre database est correctement installée et que votre instance est disponible :</span></p>
<pre>&gt; su  -  oracle
<span style="line-height: 18px;">&gt; [oracle] : sqlplus  /  as sysdba
</span>&gt; SQL*Plus: Release 10.2.0.1.0 - Production on Wed Mar 2 15:21:00 2011
&gt; Copyright (c) 1982, 2005, Oracle.  All rights reserved.
&gt; Connected to:
&gt; Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
&gt; SQL&gt; select INSTANCE_NAME, DATABASE_STATUS from v$instance;
<span style="line-height: 18px;">&gt; 
</span>&gt; INSTANCE_NAME    DATABASE_STATUS
&gt; ---------------- -----------------
&gt; XE               ACTIVE</pre>
<p><span style="line-height: 18px;"> </span></p>
<div>Tout va alors bien, on peut continuer  !</div>
<p><span style="line-height: 18px;"><span style="text-decoration: underline;">3.4) Installation de Ignite</span></span></p>
<p><em>3.4.1) Installation du web server IGNITE</em></p>
<p>L&#8217;installation des binaires Ignite ne pose aucun problème, il faut simplement les exécuter tel que et accepter (presque) toutes les options par défaut, sauf peut être celle du répertoire de destination&#8230;  :</p>
<pre>cd /datas/downloads
tar -xvf ignite_pi_tf_8_1_118.tar
chmod +x ./ignite_pi_tf_8_1_118/ignite_pi_tf_8_1_118_installer.sh
<strong><span style="color: #339966;">./ignite_pi_tf_8_1_118_installer.sh</span></strong>

Verifying archive integrity... All good.

Uncompressing Ignite PI 8.0.110 installation files.........

Before installing and running Ignite PI, you must agree to the following

software license agreement (EULA).  Press [enter] to view the license...

. . . . . 

Do you agree with the license? [y/n]:y

Searching for java executable... This may take a few minutes, please be patient.

Found java executable at [/usr/lib/jvm/jre/bin/java].

Please note the following before proceeding:

Ignite PI is a web server.  You should install Ignite PI on a server that:

   - has network connectivity to the Repository and the monitored databases, and

   - is available at all times (a laptop might not be a good choice), and

    - is not running applications where performance is critical.

Proceed with installation? [Y/n]:y

This script will extract Ignite PI into a directory of your choosing.

The directory must already exist and must be writable by the current user.

Ignite PI will be extracted into its own version-specific directory under

the directory you enter below.  For example, if you enter "/home/ignite"

as the destination directory, Ignite PI will be extracted into the directory

"/home/ignite/pi_8_0_110".

Enter destination directory for Ignite PI [/datas/downloads]: /datas/ignite

Extracting Ignite PI to directory [/datas/ignite].......................................................................done.

Please view the readme.txt for startup and upgrade instructions.  The readme

will explain how to get Ignite PI running.  Once it is running, an Ignite PI

wizard will walk you through creating a Repository and monitoring database

instances. The readme.txt is located at: /datas/ignite/pi_8_0_110/readme.txt

Would you like to view the readme.txt now? [Y/n]:n

Ignite PI installation complete.</pre>
<p>Ensuite si tout va bien, vous devrez démarrer le démon http IGNITE avec la commande :</p>
<pre>&gt; nohup   /data/ingite/pi_8_0_110/startup.sh   &amp;</pre>
<p>Vérifiez que le fichier /data/ignite/pi_8_0_110/nohup.out se termine bien par la phrase &#8220;Exiting script after webserver launched&#8221;, c&#8217;est que tout se passe bien pour le moment: un démon http écoute sur le port 8123, vérifiez par sécurité en exécutant la commande :</p>
<pre>netstat -len | grep :8123</pre>
<p>Si ceci est ok, vous pouvez utiliser votre navigateur web préféré pour commencer à configurer le référentiel Ignite en vous connectant sur &#8220;<strong>http://&lt;ip_du_serveur_ignite&gt;:8123</strong>&#8220;, vous verrez alors les écrans suivants apparaitres et à valider :</p>
<p>a) Veuillez &#8220;valider&#8221; votre intention de créer un repository pour les futures mesures:</p>
<p style="text-align: center;"><a href="http://cx.cx/wp-content/uploads/2011/03/17.jpg"><img class="aligncenter size-full wp-image-354" title="17" src="http://cx.cx/wp-content/uploads/2011/03/17.jpg" alt="" width="609" height="409" /></a></p>
<p>b) Validez vous vous désirez créer ce repository dans une base Oracle:</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/16.jpg"><img class="aligncenter size-full wp-image-353" title="16" src="http://cx.cx/wp-content/uploads/2011/03/16.jpg" alt="" width="609" height="396" /></a></p>
<p>c) Indiquez les paramètres nécessaires pour se connecter à la database Oracle qui contiendra le repository (ORACLE_SID, ip du serveur, port du listener) ainsi que le password du user &#8220;system&#8221; de cette database (et pas le pass du users &#8220;sys&#8221;!) :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/15.jpg"><img class="aligncenter size-full wp-image-352" title="15" src="http://cx.cx/wp-content/uploads/2011/03/15.jpg" alt="" width="609" height="407" /></a></p>
<p>d) Entrez un USERNAME / password  pour le schéma du repository :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/14.jpg"><img class="aligncenter size-full wp-image-351" title="14" src="http://cx.cx/wp-content/uploads/2011/03/14.jpg" alt="" width="609" height="410" /></a></p>
<p>e) Dans quel TableSpace le repository doit-il être stoqué ? (et quel est son tbs temporaire?) :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/13.jpg"><img class="aligncenter size-full wp-image-350" title="13" src="http://cx.cx/wp-content/uploads/2011/03/13.jpg" alt="" width="609" height="401" /></a></p>
<p>f) Voici un récapitulatif de vos choix, lise le avec soin et validez pour passer à la suite :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/12.jpg"><img class="aligncenter size-full wp-image-349" title="12" src="http://cx.cx/wp-content/uploads/2011/03/12.jpg" alt="" width="609" height="404" /></a></p>
<p>g) Vérifiez que tout s&#8217;est bien passé en parcourant la log et en validant que &#8220;Respository has been created&#8221;, sinon, inutile d&#8217;aller plus loin et trouvez le problème (et la solution <img src='http://cx.cx/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> )</p>
<p>Cliquez ensuite sur &#8220;Register database to monitor&#8221; pour configurer la database à surveiller.</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/11.jpg"><img class="aligncenter size-full wp-image-348" title="11" src="http://cx.cx/wp-content/uploads/2011/03/11.jpg" alt="" width="609" height="402" /></a></p>
<p>h) Dans notre cas, évidement, sélectionnez &#8220;Oracle&#8221; comme type de database, puis continuez :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/10.jpg"><img class="aligncenter size-full wp-image-347" title="10" src="http://cx.cx/wp-content/uploads/2011/03/10.jpg" alt="" width="609" height="398" /></a></p>
<p>i) Définissez l&#8217;ensemble des paramètres nécessaires pour accèder à l&#8217;instance à monitorer (méthode de connexion : ici EazyConnect, hostname et port (1521) puis login / password de DBA (pas le user &#8220;sys&#8221; par sécurité) :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/9.jpg"><img class="aligncenter size-full wp-image-346" title="9" src="http://cx.cx/wp-content/uploads/2011/03/9.jpg" alt="" width="609" height="404" /></a>Puis cliquez sur &#8220;Next&#8221;&#8230;</p>
<p>j) Il faut, pour monitorer la database cible, créer un use Oracle sur celle ci, pour cela, il faudra donc préciser le tablespace par défaut du user (nous vous recommendaons de créer un tb spécifique pour ce schéma afin de ne pas géner les autres users de production de la database) ainsi que son tablespace temporaire (le tbs temp standard suffit) :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/8.jpg"><img class="aligncenter size-full wp-image-345" title="8" src="http://cx.cx/wp-content/uploads/2011/03/8.jpg" alt="" width="609" height="407" /></a></p>
<p>Cliquez sur &#8220;Next&#8221; !!</p>
<p>k) Il faut ensuite donner le mot de passe du user sys de votre database à monitorer, simplement pour qu&#8217;un user soit créé et qu&#8217;on lui donne le droit de visualiser les tables et vues de sys, ce que seul sys peut donner :</p>
<p style="text-align: center;"><a href="http://cx.cx/wp-content/uploads/2011/03/7.jpg"><img class="aligncenter size-full wp-image-344" title="7" src="http://cx.cx/wp-content/uploads/2011/03/7.jpg" alt="" width="609" height="405" /></a></p>
<p style="text-align: left;">Et Next encore une fois!</p>
<p style="text-align: left;">
<p>l) Choisissez le tablespace sur lequel votre user sera autorisé à écrire sur la base distante. Evitez de lui donner le droit d&#8217;écrire sur les tbs de production, de toute façon, très peut d&#8217;informations seront stoquées dans ce schéma, je vous conseille de pointer vers le tbs users standard:</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/6.jpg"><img class="aligncenter size-full wp-image-343" title="6" src="http://cx.cx/wp-content/uploads/2011/03/6.jpg" alt="" width="609" height="409" /></a></p>
<p>m) Vérifiez que tout est ok avant de cliquer définitivement sur &#8220;Register Database Instance&#8221; :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/5.jpg"><img class="aligncenter size-full wp-image-342" title="5" src="http://cx.cx/wp-content/uploads/2011/03/5.jpg" alt="" width="609" height="408" /></a></p>
<p>n) Si vous voyez apparaitre à la fin de la log écran &#8220;The database instance has been registrer and is now beeing monitored&#8221; c&#8217;est que tout est ok, sinon &#8230; cherchez l&#8217;erreur <img src='http://cx.cx/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/4.jpg"><img class="aligncenter size-full wp-image-341" title="4" src="http://cx.cx/wp-content/uploads/2011/03/4.jpg" alt="" width="609" height="404" /></a></p>
<p>o) Cliquez sur le bouton &#8220;Licence Managmnent&#8221; pour renseigner votre licence (Permanente ou Trial), sinon Ignite ne vous autorisera pas à visualiser les stats des données récoltées, ce qui est un peu dommage &#8230;</p>
<p>Notez que la version Trial est limitée à 30jours, que toutes les fonctionnalités n&#8217;apparaissent pas, et que vous serez obligé d&#8217;installer une autre version de Iginte si vous obtenez une licence permanente, par souci de lutte contre le piratage, la version capable d&#8217;accepter des licences permanentes ne figure pas en téléchargement libre mais un login/password pour la télécharger vous est communiqué dès que vous avez acquis la licence :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/3.jpg"><img class="aligncenter size-full wp-image-340" title="3" src="http://cx.cx/wp-content/uploads/2011/03/3.jpg" alt="" width="609" height="156" /></a></p>
<p>p) Renseigner votre clé, et cliquez sur &#8220;Add Licence&#8221;</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/03/2.jpg"><img class="aligncenter size-full wp-image-339" title="2" src="http://cx.cx/wp-content/uploads/2011/03/2.jpg" alt="" width="609" height="168" /></a></p>
<p><strong><span style="text-decoration: underline;">4) Utilisation </span></strong></p>
<p>Utilisez maintenant votre browser préféré et allez à http://&lt;ip_de_votre_machine&gt;:8123, donnez le mot de passe du user ignite de votre repository créé en 3.d) et vous verrez alors appraitre l&#8217;interface IGNITE qui vous donnera un apperçu temps reel de la cpu de votre machine Oracle, des IO physiques et logiques, des différentes opérations qui ont été consomatrices heure par heure, &#8230;</p>
<p>Vous pouvez consulter la partie &#8220;CURRENT&#8221; qui est le temps réel pour la partie &#8220;TREND&#8221; qui est l&#8217;archivage, pour regarder à postérieure le comportement de votre database.</p>
<p>Vous verrez que le produit est très complet et qu&#8217;il vous permet de retourner dans tous les sens les indicateurs de perfs (les users, les programmes, les temps, les waits, les requetes, &#8230;)</p>
<p>A vous de découvrir le produit !</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/ignite.jpg"><img class="aligncenter size-full wp-image-361" title="ignite" src="http://cx.cx/wp-content/uploads/2011/02/ignite.jpg" alt="" width="586" height="377" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/26/ignite-une-alternative-a-dbconsole-enterprise/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serveur de logs central</title>
		<link>http://cx.cx/2011/02/24/server-syslog-centralise/</link>
		<comments>http://cx.cx/2011/02/24/server-syslog-centralise/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 15:07:52 +0000</pubDate>
		<dc:creator>xavier</dc:creator>
				<category><![CDATA[Générale]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[centralisation]]></category>
		<category><![CDATA[event id]]></category>
		<category><![CDATA[event manager]]></category>
		<category><![CDATA[rsyslog]]></category>
		<category><![CDATA[serveur de logs]]></category>
		<category><![CDATA[syslog]]></category>
		<category><![CDATA[windows event]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=236</guid>
		<description><![CDATA[Lorsque le parc de machine d&#8217;un administrateur commence à devenir un peu trop grand, il est souvent très fastidieux de se rendre sur l&#8217;un et l&#8217;autre des serveurs, consulter leurs fichiers de logs locaux, tout ceci pour identifier un éventuel problème lié à la mauvaise communication entre ces serveurs, ou autre. l&#8217;idéal est de disposer [...]]]></description>
			<content:encoded><![CDATA[<p>Lorsque le parc de machine d&#8217;un administrateur commence à devenir un peu trop grand, il est souvent très fastidieux de se rendre sur l&#8217;un et l&#8217;autre des serveurs, consulter leurs fichiers de logs locaux, tout ceci pour identifier un éventuel problème lié à la mauvaise communication entre ces serveurs, ou autre.</p>
<p>l&#8217;idéal est de disposer d&#8217;une <strong>console unique</strong> dans l&#8217;entreprise où les différents serveurs vont inscrire leurs diverses informations initialement destinés à des fichiers de log locaux. Une telle console permet de superviser rapidement l&#8217;ensemble des messages de l&#8217;ensemble des serveurs d&#8217;une entreprise.</p>
<p>Un élément essentiel qui peut par exemple se coupler à un <em>superviseur Nagios</em> pour une vue parfaite des resources de l&#8217;entreprise.</p>
<p><strong><span style="text-decoration: underline;">1) Introduction</span></strong></p>
<p><strong><span style="text-decoration: underline;"><br />
</span></strong></p>
<p><span style="text-decoration: underline;">11. Généralités</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Il existe <span style="text-decoration: underline;">plusieurs formats</span> de gestion de messages de logs, les plus connus sont <strong>SYSLOG </strong>(qui se décline en plusieurs normes) et <strong>WindowsEvent</strong>. Les formats SYSLOG sont généralement utilisés dans les mondes UNIX-like alors que les autres utilisent des formats propriétaires &#8230; (no comment).</p>
<p>Nous avons choisi de construire le Serveur de Logs Central (SLC) sous le format syslog dernière génération (norme RSYSLOG) et de convertir les autres formats vers celui-ci (syslog, syslog-ng et WindowsEvent) afin de faire remonter sur cette console tous les logs de l&#8217;entreprise sans discrimination.</p>
<p><span style="text-decoration: underline;">1.2 Le serveur SYSLOG</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Un serveur SysLog est un serveur comme un autre, il a la faculté d&#8217;écouter d&#8217;éventuels clients qui veulent lu idélivrer des messages de log sous divers formes (sockets UNIX, sockets IP, etc) et, selon la configuration que l&#8217;on en fera, stoquera ces messages en fonction de divers critères et sur différents médias (fichiers text, base de données, mails, &#8230;).</p>
<p>Nous avons choisi dans notre exemple d&#8217;utiliser le protocole syslog pour que celui-ci stoque tous les messages qui lui sont annoncés dans une base de données au format MySQL, permet de greffer éventuellement et facilement une interface web permettant d&#8217;administrer facilement ces différents messages?</p>
<p><em>Exemple de réalisation web pour l&#8217;entreprise XXX :</em></p>
<p><em><a href="http://cx.cx/wp-content/uploads/2011/02/log.jpg"><img class="aligncenter size-medium wp-image-229" title="log" src="http://cx.cx/wp-content/uploads/2011/02/log-300x178.jpg" alt="" width="300" height="178" /></a><br />
</em></p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/log.jpg"><em> </em></a></p>
<p><span style="text-decoration: underline;">1.3 Bases de construction de cet exemple</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Dans cet article, notre SLC est basé sur une distribution Linux openSuSE 11.3 64bits.</p>
<p>Les prérequis sont, parmi les packages standards de cette distribution (rien d&#8217;extraordinaire) :</p>
<p><em>- RSYSLOG</em></p>
<p><em>- MYSQL community edition</em></p>
<p><em>- php 5.x + module php_mysql</em></p>
<p><em><br />
</em></p>
<p><strong><span style="text-decoration: underline;">2) Les serveurs au format SYSLOG</span></strong></p>
<p><strong><span style="text-decoration: underline;"><br />
</span></strong></p>
<p><span style="text-decoration: underline;">2.1 Présentation d&#8217;un serveur RSYSLOG (dernière génération)</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Le fichier de configuration du serveur RSyslog est généralement <strong>/etc/rsyslog.conf.</strong></p>
<p>Prenons par exemple la configuration RSyslog pour un serveur de mails (postfix) :</p>
<pre>$ModLoad immark.so
$ModLoad imuxsock.so
$ModLoad imklog.so
$klogConsoleLogLevel 1
$WorkDirectory                  /var/log/rsyslog.work
$ActionQueueType                LinkedList
$ActionQueueFileName            srvrfwd
$ActionResumeRetryCount         -1
$ActionQueueSaveOnShutdown      on</pre>
<pre><span style="color: #339966;">mail.info               /var/log/mail.info
mail.warning            @@logserver:514
mail.err                @@logserver:514</span></pre>
<pre><span style="color: #339966;"> </span><span style="color: #ff6600;"><strong>if      ($programname != 'postfix') \
</strong><strong>then    @@logserver:514
</strong><strong>&amp;       ~</strong></span></pre>
<p>Dans cet exemple, le serveur &#8220;<strong>logserver</strong>&#8221; est le nom DNS de notre serveur central de logs, celui-ci est indiqué dans le fichier /etc/hosts du serveur local.</p>
<p>Ici nous demandons plusieurs choses, l&#8217;envoi en <strong>UDP (port 514 standard) </strong>de tous les messages syslog que reçoit le serveur Rsyslog local de ce serveur, ceci pour tous les messages de la facility &#8220;<strong>mail</strong>&#8221; et la criticité &#8220;<strong>warning</strong>&#8221; ou &#8220;<strong>err</strong>&#8220;. Cela signifie tous les messages de logs envoyés par les programmes qui se signent en &#8220;mail&#8221; et qui précisent que les messages sont de type warning ou error.</p>
<p>Les message de type &#8220;<strong>info</strong>&#8221; sont en revanche très nombreux sur un serveur smtp très solicité,nous ne préférons pas engorger le réseau avec ce type de flux et préférons continuer le stockage de ces informations dans un fichier local au serveur (il n&#8217;y a généralement pas d&#8217;information intéréssante à glaner dans les messages de type &#8220;info&#8221; =&gt; inutile de les faire remonter inutilement&#8230;)</p>
<p>Notons aussi la directive &#8220;workdirectory&#8221;, elle est très importante et consiste en un répertoire de spool dans lequel stoquer les messages dans le cas où le serveur central serait injoignale pendant un certain temps en afin de ne pas perdre ces messages.</p>
<p>Enfin, en plus de la politique précédente, dans les dernières lignes, notons que nous ne souhaitons pas recevoir sur le SLC les lessages provenant du serveur &#8220;postfix&#8221; mais que nous souhaitons recevoir tous les autres (messages systèmes, etc).</p>
<p>Généralement nous ne nous attarderons pas à &#8220;éliminer&#8221; certains messages de logs à envoyer vers le SLC mais de temps en temps, comme dans le cas d&#8217;un serveur de mails, d&#8217;un DNS, etc, il peut arrive de vouloir exclure une partie des messages dans un but de lisibilité et de performance.</p>
<p><span style="text-decoration: underline;">2.2 Communication avec d&#8217;autres serveurs de Log</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p><span style="text-decoration: underline;">2.2.1 Rsyslog vers Rsyslog</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Informations décrites en 2.1, voir descriptif du <span style="text-decoration: underline;">/etc/rsyslog.conf</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p><span style="text-decoration: underline;">2.2.1 syslog vers Rsyslog</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Syslogd est la premire version des démons syslog, le fichier de conf est /etc/syslog.conf.</p>
<p>Le principe est le même, on donne des règles de log (fichiers locaux, mails, &#8230;) en fonction de falility (signature des programmes &#8220;mail&#8221;, &#8220;cron&#8221;, &#8230;) et des levels (info, warning, err, &#8230;).</p>
<p>Exemple de /etc/syslog.conf:</p>
<pre>*.info;mail.none;authpriv.none;cron.none                /var/log/messages

authpriv.*                                              /var/log/secure

mail.*                                                  /var/log/maillog

cron.*                                                  /var/log/cron

*.emerg                                                 *

uucp,news.crit                                          /var/log/spooler

local7.*                                                /var/log/boot.log</pre>
<p>Dans cet exemple, nous avons un syslog.conf classique qui ne logg que dans des fichiers locaux en fonction de &lt;facility&gt;.* ou de *.&lt;level&gt; au choix.</p>
<div id="_mcePaste">Si on souhaite rediriger certains messages vers un serveur syslog qui accepterait ces requêtes, il faudrait avoir une ligne telle que :</div>
<pre><span style="color: #339966;">local7.*                                                 @@serveur.de.logs:544</span></pre>
<p>Ou 544 est par défaut le port UDP sur lequel le serveur répondant au nom DNS serveur.de.logs devra écouter.</p>
<p><span style="text-decoration: underline;">2.2.2 syslog-NG vers Rsyslog</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Les serveurs syslog-NG (NextGeneration) trouvent leur configuration dans /etc/syslog-ng/syslog-ng.conf.</p>
<p>On trouve globalement 3 notions utile dans notre cas dans ces fichiers:</p>
<p>- &#8220;options&#8221; : le réglagage général du démon syslog-ng</p>
<p>- &#8220;source&#8221; : identification d&#8217;une source de message (facility, level, &#8230;)</p>
<p>- &#8220;destination&#8221; : que doit on faire de ces messages (écriture fichier local, renvoi vers un autre démon syslog, etc)</p>
<p>Exemple:</p>
<pre>options {

        use_dns(yes);          &lt;-- utilise les résolutions DNS (recommandé)

        dns_cache(yes);        &lt;-- utilise un cache client DNS (très recommandé)

        use_fqdn(yes);         &lt;-- utilise des full qualified domain name au lieu de noms courts

        keep_hostname(yes);    &lt;-- hostname rewriting ?

        check_hostname(no);

        chain_hostnames(off);

        sync(0);               &lt;-- nombre de lignes à buffersier avant de traiter un flux: 0</pre>
<pre>                                   recommandé hautement si cvous ne souhaitez pas perdre de message

        stats(43200);

};

source s_everything {          &lt;-- description d'une source potentielle de message et attribution
                                   d'un nom "s_everything"
        internal();

        unix-stream("/dev/log");   &lt;-- tout se qui écrit sur le périphérique /dev/log (ie: tout)

        udp();                     &lt;-- on veut receptionner de l'UDP uniquement

};

<span style="color: #339966;">destination d_logserver   {  tcp("logserver" port(514)); }; &lt;-- destination "d_logserver"

log {  source(s_everything);  destination(d_logserver); };  &lt;-- on log en fonction de la source
                                                            s_everything et de d_logserver</span>

destination d_fichier { file("/var/log/messages.log"); };    &lt;-- destination "d_fichier"

log { source(s_everything); destination(fichier); };         &lt;-- on log en fonction de la source
                                                             s_everything et de d_fichier</pre>
<p>Vous le voyez, vraiment rien de sorcier !</p>
<p><span style="text-decoration: underline;">2.2.4 WindowsEvent vers Rsyslog</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p><span style="text-decoration: underline;">2.2.4.1 &#8211; </span><span style="text-decoration: underline;">Introduction</span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
<p>Bon, c&#8217;est évidement là que cela commence à pêcher&#8230; Car évidement, histoire de ne pas faire dans les standards établis, Microsoft a décidé d&#8217;employer un autre protocole de communication pour les messages de log exploités notemmenent dans le monde Windows par l&#8217;EventManager que tout le monde ne connait que trop bien.</p>
<p>Le messages ont des niveaux de criticité, des facility, sont présents dans des types de journaux, &#8230; un peu comme dans SysLog mais ne sont pas au format SysLog&#8230;</p>
<p>Il existe cependant dans le monde du libre et de l&#8217;OpenSource des tas de petits softs qui se chargent de traduire un format de message Windows en un format SYSLOG dans le but de l&#8217;envoyer vers un serveur SYSLOG, et cela fonctionne très bien!</p>
<p>Nous avons jeté notre dévolu sur l&#8217;agent <strong>SNARE </strong>développé par la société <strong>INTERSECTALLIANCE </strong>et qui est télévhargeable ici dans une version libre : <a style="color: #536a86; outline-style: none; outline-width: initial; outline-color: initial; text-decoration: none;" href="http://sourceforge.net/projects/snare/"><strong>http://sourceforge.net/projects/snare/</strong></a></p>
<p>l&#8217;Agent SNARE pour Windows fait le café en matière de traduction de message Windows vers du SYSLOG, mais IntersectAlliance propose aussi une version commerciale si vous souhaitez avoir le sucre et le nuage de lait &#8230; A mon sens vraiment pas nécéssaire.</p>
<p>Par exemple, SNARE dans sa version gratuite ne sait pas écouter sur les ports TCP mais uniquement sur les ports UDP ce qui est loin d&#8217;être un drâme car toutes les versions des différents serveurs SYSLOG parlent l&#8217;UDP et que il n&#8217;est pas forcément recommandé de faire de l&#8217;UDP sur un serveur SYSLOG centralisé afin de ne pas se faire engorger en cas d&#8217;afflux massif de messages et de provoquer un deni de service&#8230;</p>
<p><em>2.2.4.1 &#8211; Installation de l&#8217;Agent SNARE</em></p>
<p>Là aussi c&#8217;est d&#8217;une difficulté déconcertante, du moment que vous disposez d&#8217;un index normalement constitué pour cliquer sur &#8220;Next&#8221;, tout se passera bien!</p>
<p>La configuration du logiciel agent SNARE sur votre serveur windows est par contre à peine plus complexe.</p>
<p>2.2.4.2 &#8211; Configuration de l&#8217;Agent SNARE</p>
<p>Une fois l&#8217;agent installé, vous disposez en local d&#8217;un petit serveur web qui vous permet de configurer l&#8217;agent, de déterminer l&#8217;emplacement du serveur SYSLOG Central, de déterminer les mappings Event Windows / Message Syslog que vous souhaitez ainsi exporter vers ce serveur, l&#8217;ensemble est sommes toute très bien fait.</p>
<p>Utilisez votre navigateur http préféré depuis votre serveur Windows et connectez vous sur <strong>http://localhost:6161</strong> vous verrez alors apparaitre l&#8217;écran suivant :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_1.png"><img class="aligncenter size-medium wp-image-244" title="snare_1" src="http://cx.cx/wp-content/uploads/2011/02/snare_1-300x155.png" alt="" width="300" height="155" /></a></p>
<p>Plusieurs options s&#8217;offrent à vous dans le menu de gauche :</p>
<p><strong>A) NETWORK CONFIGURATION:</strong></p>
<p><strong><br />
</strong></p>
<p>Ce menu vous permet de renseigner la localisation du serveur syslog central qui va recevoir les message traduits de l&#8217;EventViewer de Vindows.</p>
<p>Les principaux champs à renseigner sont :</p>
<pre>Override detected DNS Name with :    NOM_MACHINE     &lt;-- le 'hostname' syslog de votre machine
Destination Snare Server address:    logs.domaine.fr &lt;-- le nom dns (ou ip) du serveur syslog central
Destination Port:               :    514             &lt;-- port UDP standard
Enable SYSLOG Header?           :    CHECKED         &lt;-- sinon cela ne sera pas un message syslog
SYSLOG Facility                 :    local7          &lt;-- une facility à associer aux messages Win64
SYSLOG Priority                 :    DYNAMIC         &lt;-- choisissez cette option absolument</pre>
<p><span style="text-decoration: underline;">Rem: </span>Si &#8220;SYSLOG Priority&#8221; ne vaut pas &#8220;DYNAMIC&#8221;, alors tous vos messages auront tous la même priorité (bof)</p>
<p><span style="text-decoration: underline;">Rem: </span>&#8220;Syslog Facility&#8221; est la facility avec laquelle ce message va s&#8217;annoncer, vous pourrez en fonction de cette information traiter les messages d&#8217;une certaine façon et les différencier des autres. Généralement local7 n&#8217;est pas ou très peu utilisé.</p>
<p>Cliquez sur &#8220;<strong>CHANGE CONFIGURATION</strong>&#8221; pour que les paramètres soient enregistrés (mais pas encore pris en compte)</p>
<p><strong>B) REMOTE CONTROL CONFIGURATION</strong></p>
<p>Simplement pour restreindre l&#8217;utilisation de cette interface web au localhost, ie aux personnes habilitées à ouvrir une session RDP sur le serveur (Administrateurs généralement) :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_8.png"><img class="aligncenter size-medium wp-image-251" title="snare_8" src="http://cx.cx/wp-content/uploads/2011/02/snare_8-300x108.png" alt="" width="300" height="108" /></a></p>
<p>Cochez simplement la case &#8220;Restrict remote control of SNARE agent to certain hosts&#8221; et indiquez &#8220;127.0.0.1&#8243; (ou &#8220;localhost&#8221;) dans le champ &#8220;IP Address allowed to remote control SNARE&#8221;, l&#8217;interface est vérouillée.</p>
<p>C) OBJECTIVES CONFIGURATION</p>
<p>C&#8217;est cette partie qui va vous permette de définir le mapping entre un message Windows et un message au format SysLog.</p>
<p>Par défaut, vous verrez un certain nombre de message déjà configurés, symbolisés par une ligne dans un tableau html. Généralement ces messages ne conviennent pas et sont uniquement donnés à titre d&#8217;exemples, je vous conseille de les supprimer en cliquant autant de fois que nénessaire sur le bouton &#8220;<strong>DELETE</strong>&#8221; pour chaque ligne.</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_7.png"><img class="aligncenter size-medium wp-image-250" title="snare_7" src="http://cx.cx/wp-content/uploads/2011/02/snare_7-300x194.png" alt="" width="300" height="194" /></a></p>
<p>Une fois les lignes d&#8217;exemples supprimées, vous allez pouvoir ajouter vos propres lignes de mapping de message, c&#8217;est à dire de traduction de messages windows spécifiques en messages de type syslog et à envoyer vers votre serveur syslog central.</p>
<p>Cliquez sur &#8220;<strong>ADD</strong>&#8220;, la fenêtre suivante apparaît alors :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_4.png"><img class="aligncenter size-medium wp-image-247" title="snare_4" src="http://cx.cx/wp-content/uploads/2011/02/snare_4-300x202.png" alt="" width="300" height="202" /></a></p>
<p>Voici la signification des difrérents champs &#8220;utiles&#8221; et les &#8220;best pratice&#8221; à appliquer :</p>
<pre><span style="text-decoration: underline;">Identify the high level event:</span> Indique le type d'évènement Windows concerné (les logons/logoff, les arret/marche de services, ...), il convient, dans la pluspart des cas de choisir "ANY EVENT(S)"</pre>
<pre><span style="text-decoration: underline;">Select the Event ID Match Type:</span> Une notion d'inclusion / exclusion. Sauf dans certains cas complexes imposés par votre production, vous préfererez "INCLUDE"</pre>
<pre><span style="text-decoration: underline;">Event ID Search Term:</span> Des mots clés pour filtrer les messages Windows à intercepter. Nous allons dans la pluspart des cas choisir "*" ce qui signifie "tout les messages", mais vous pourriez être amenné, en fonction de vos applicatifs, à utiliser des wildcards plus complexes ("*toto*" &lt;-- bon ok, c'est pas très complexe... mais ça fonctionnerait)</pre>
<pre>General Search Term: *</pre>
<pre>User Search Term: *</pre>
<pre><span style="text-decoration: underline;">Identify the event types to be captured:</span> Les "Success Audit" et "Failure Audit" ne présentent pas grand intérêt pour notre utilisation, par contre "INFORMATION", "WARNING" et "ERROR" nous intéressent plus particulièrement dans le cadre des messages SYSLOG. Selon la valeur indiquée dans le paramètre suivant (Select the Alert Level) nous cocherons l'une ou l'autre de ces options. L'idée est: quelle est la notion de criticité que nous souhaitons paralléliser avec la notion de criticité d'un message syslog.</pre>
<pre><span style="text-decoration: underline;">Identify the event logs</span>: Les journaux Windows concernés. Si nous sommes intéressé par tous les message de type "ERREUR", pourquoi se limiter à un journal ? Nous allons donc cocher tous les journaux. Seul un cas particulier exigé par votre production pourra vous amener à effectuer un choix différent.</pre>
<pre><span style="text-decoration: underline;">Select the Alert Level:</span> paramètre FONDAMENTAL. Il s'agit, en fonction de tout ce que nous avons catégorisé précédemment, et notamment avec l'option "Identify the event types to be captured" de faire un parallèle avec un niveau de criticité SYSLOG. Essayez de faire un parallèle correct entre les deux notions pour ne pas avoir de niveaux de criticité incohérents par rapport à l’importance du message Windows...</pre>
<p>Une fois ces options indiquez, vous pourrez cliquer sur &#8220;CHANGE CONFIGURATION&#8221; pour la voir apparaître dans la liste des mappings de messages comme indiqué dans le début de ce chapitre (ouf enfin!)</p>
<p><strong>C) APPLY THE LATEST CONFIGURATION</strong></p>
<p>Une fois tout ceci fait, une fois toutes vos règles de mapping définies, celles-ci ne sont pour autant pas encore prise en compte par le démon SNARE, il faut pour cela se rendre dans la section &#8220;Apply the latest configuration&#8221; et cliquer sur &#8220;<strong>RELOAD SETTINGS</strong>&#8220;.</p>
<p>A partir de cet instant, vos mappings sont actifs et, normalement, SNARE doit envoyer toutes ces traductions de messages Windows vers votre serveur de logs SYSLOG central, vous pouvez vérifier cela en cliquant sur &#8220;<strong>LATEST EVENTS</strong>&#8221; dans le menu de gauche de l&#8217;interface web SNARE, vous verre zalors un écran du style :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_6.png"><img class="aligncenter size-medium wp-image-249" title="snare_6" src="http://cx.cx/wp-content/uploads/2011/02/snare_6-300x190.png" alt="" width="300" height="190" /></a></p>
<p>Ce qui signifie alors que (probablement) tout va bien! Il ne vous reste plus qu&#8217;a constater la conne reception de ces messages dans cotre SLC.</p>
<p><strong>3) Configuration du serveur SYSLOG central</strong></p>
<p><strong><br />
</strong></p>
<p>Dernière brique à notre édifice, la construction du serveur SLC. Celle-ci ne s&#8217;écarte pas vraiment d&#8217;une configuration standard hormis le fait que nous allons la configurer pour que tous les messages reçus soient inscrits dans une base de données MySQL dont nous allons créer dans un premier lieur la structure.</p>
<p><span style="text-decoration: underline;">3.1) Création de la base de données</span></p>
<p>Nous avons choisi ici le choix de MySQL car c&#8217;est le pokus simple à mettre en oeuvre et les structures de tables MyISAM s&#8217;appliquent tout à fait à ce genre de typologie en matière de stockage de données (très peu de requêtes croisées, très peu de jointures, beaucoup de balayage de tables simples).</p>
<p>Et puis en plus, pour le moment, dans sa version community, celle-ci est totalement gratuite et full founctionality. Ceci aurait été impossible à faire avec de l&#8217;Oracle par exemple sans que cela nous coûte très cher (même dans la version XE, la database ne doit pas exéder 4Gb, hors, dans notre cas, l&#8217;entreprise XXX qui utilise cette méthode depuis 1 mois pour son DataCenter possède déjà des tables de plus de 20Gb&#8230;)</p>
<pre>CREATE DATABASE `syslog`;

CREATE TABLE `client` (
  `client` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `libelle` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `login` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `ackSequence` text COLLATE utf8_unicode_ci,
  `allServersAccess` tinyint(4) DEFAULT '-1',
  `alerteSonore` tinyint(4) DEFAULT '-1',
  PRIMARY KEY (`client`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `clientHost` (
  `clientHost` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `client` INT(11) DEFAULT NULL,
  `ipaddr` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `libelle` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `abreviation` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`clientHost`),
  KEY `IDX1` (`ipaddr`)
) ENGINE=MYISAM AUTO_INCREMENT=76 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE INDEX `idxx_clientHost_ipaddr ON clientHost(ipAddr);

CREATE TABLE `clientLogsAck` (
  `clientLogsAck` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `client` BIGINT(20) DEFAULT '-1',
  `seq` BIGINT(20) DEFAULT '-1',
  `dateAck` DATE DEFAULT NULL,
  `timeAck` TIME DEFAULT NULL,
  PRIMARY KEY (`clientLogsAck`)
) ENGINE=MYISAM AUTO_INCREMENT=53016 DEFAULT CHARSET=latin1

CREATE TABLE `logsMasking` (
  `logsMasking` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `client` BIGINT(20) DEFAULT NULL,
  `wildcard` VARCHAR(255) DEFAULT NULL,
  `information` VARBINARY(255) DEFAULT NULL,
  `datecreation` DATETIME DEFAULT NULL,
  `ipaddr` VARCHAR(255) DEFAULT NULL,
  `actif` TINYINT(1) DEFAULT NULL,
  PRIMARY KEY (`logsMasking`)
) ENGINE=MYISAM AUTO_INCREMENT=71 DEFAULT CHARSET=latin1

CREATE TABLE `logs` (
  `seq` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `ipaddr` VARCHAR(20) COLLATE latin1_general_ci DEFAULT NULL,
  `host` VARCHAR(32) COLLATE latin1_general_ci DEFAULT NULL,
  `facility` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL,
  `priority` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL,
  `level` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL,
  `tag` VARCHAR(10) COLLATE latin1_general_ci DEFAULT NULL,
  `date` DATE DEFAULT NULL,
  `time` TIME DEFAULT NULL,
  `program` VARCHAR(15) COLLATE latin1_general_ci DEFAULT NULL,
  `msg` TEXT COLLATE latin1_general_ci,
  `ack` TINYINT(4) DEFAULT '-1',
  PRIMARY KEY (`seq`),
  KEY `host` (`host`),
  KEY `program` (`program`),
  KEY `time` (`time`),
  KEY `date` (`date`),
  KEY `priority` (`priority`),
  KEY `facility` (`facility`),
  KEY `IDX2` (`ipaddr`)
) ENGINE=MYISAM AUTO_INCREMENT=89272745 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci

CREATE INDEX `idx_logs_host ON `logs`(host);
CREATE INDEX `idx_logs_program ON `logs`(program);
CREATE INDEX `idx_logs_time ON `logs`(time);
CREATE INDEX `idx_logs_date ON `logs`(date);
CREATE INDEX `idx_logs_priotity ON `logs`(priotity);
CREATE INDEX `idx_logs_facility ON `logs`(facility);
CREATE INDEX `idx_logs_ipaddr ON `logs`(ipaddr);

CREATE DATABASE `syslog_arch;

CREATE TABLE `logsArchives` (
  `logsArchives` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `ipaddr` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
  `host` VARCHAR(32) COLLATE utf8_unicode_ci DEFAULT NULL,
  `facility` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `priority` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `level` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `tag` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `date` DATE DEFAULT NULL,
  `time` TIME DEFAULT NULL,
  `program` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL,
  `msg` TEXT COLLATE utf8_unicode_ci,
  `ack` TINYINT(4) DEFAULT NULL,
  PRIMARY KEY (`logsArchives`),
  KEY `host` (`host`),
  KEY `program` (`program`),
  KEY `time` (`time`),
  KEY `priority` (`priority`),
  KEY `facility` (`facility`),
  KEY `IDX2` (`ipaddr`)
) ENGINE=MYISAM AUTO_INCREMENT=3554442 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE INDEX `idx_logsArchives_host ON `logs`(host);
CREATE INDEX `idx_logsArchives_program ON `logs`(program);
CREATE INDEX `idx_logsArchives_time ON `logs`(time);
CREATE INDEX `idx_logsArchives_date ON `logs`(date);
CREATE INDEX `idx_logsArchives_priotity ON `logs`(priotity);
CREATE INDEX `idx_logsArchives_facility ON `logs`(facility);
CREATE INDEX `idx_logsArchives_ipaddr ON `logs`(ipaddr);</pre>
<div>Vous pouvez noter la création de deux databases dont au moins une table semble à peu près identique syslog.logs et syslog_arch.logsArchives. La raison en est simple: le nombre de messages syslog est telklement important chaque jour (près de 500000 lignes) que nous avons choisi de les archiver tous les soirs dans la base &#8220;syslog_arch&#8221;. Cette base &#8221;syslog_arch&#8221; est un lien NFS vers un réseau de moindre performance (NAS) que la base de production &#8220;syslog&#8221; qui elle est présente sur des disques locaux de haute capacité. A vous de voir!</div>
<div><em>On devine ici également le besoin de trier les messages par appartenance de la machine à un client X, ceci dans le but de mettre à disposition de chaque client une interface d&#8217;administration web qui lui est propre et qui lui permet de visualiser tous les messages Linux et Windows des machines hébergées dans le DataCenter. </em></div>
<div></div>
<div><span style="text-decoration: underline;">3.2) Configuration du serveur RSYSLOG :</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<div>La configuration du serveur rsyslog est détenue, comme nous l&#8217;avons déjà vu plus haut, dans le fichier /etc/rsyslog.conf. La seule particularité est qu&#8217;il va falloir indiquer à ce serveur que, tous les messages qu&#8217;il recevra devront être (entre autre) inscrit dans la base MySQL &#8220;syslog&#8221; précédement créée.</div>
<div></div>
<pre><span style="color: #ff0000;">$Modload ommysql </span>
$ModLoad immark
$ModLoad imuxsock
$ModLoad imklog
$ModLoad imudp.so
$ModLoad imtcp.so
*.info;mail.none;authpriv.none;cron.none                -/var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  -/var/log/cron
*.emerg                                                 *
uucp,news.crit                                          -/var/log/spooler
local7.*                                                /var/log/boot.log
<span style="color: #ff0000;">$template syslog,"insert into logs(ipaddr, host, facility, priority, level, tag, date, time, program, msg) values ('%fromhost-ip%', '%HOSTNAME%', '%syslogfacility-text%', '%syslogpriority-text%', '%syslogseverity-text%', '%syslogtag%', '%timereported:::date-mysql%', '%timereported:::date-mysql%', '%programname%', '%msg%')", SQL
*.* &gt;127.0.0.1,syslog,syslogLogin,syslogPassword;syslogTpl</span>
<span style="color: #339966;">$UDPServerRun 514
$UDPServerAddress 192.168.12.5
$InputTCPServerRun 514</span></pre>
<div>De couleur <strong><span style="color: #339966;">VERTE</span></strong>, vous trouverez les options générales du serveur, principalement l&#8217;adresse IP d&#8217;écoute et les deux ports, TCP et UDP, pour les programmes qui vont envoyer des messages (même si nous avons vu que UDP est préférable, certains serveurs fonctionneront de façon plus éfficace en envoyant leurs messages syslog en TCP plustôt qu&#8217;en UDP).</div>
<div></div>
<div>De couleur <strong><span style="color: #ff0000;">ROUGE</span></strong>, vous trouverez les options de configuration relatives à MySQL :</div>
<div>- $Modload ommysql : indique que le module suivant doit être utilisé, c&#8217;est grâce à lui que RSyslog pourra se connecter à un serveur MySQL.</div>
<div>- $template &lt;nom_template&gt; &lt;requete&gt;, &lt;type_language&gt; : indique à RSyslog que le masque de réaction (le template) nommé &#8220;syslog&#8221; doit être créé et que, pour chaque message, il fabrique à la volée une chaine de caractères (requête) qui contiendra les champs dynamiquement récupérés depuis la mémoire partagée de RSyslog. Le dernier paramètre de $template indique que RSyslog devra utiliser SQL pour dialoguer avec le serveur MySQL correspondant.</div>
<div>- *.* &gt; 127.0.0.1,syslog,syslogLogin,syslogPassword;syslogTpl; =&gt; indique que tous les messages (facility * et level *) doivent être envoyés au serveur 127.0.0.1 (le serveur MySQL aurait très bien pu être ailleurs) pour la base &#8220;syslog&#8221; avec l&#8217;authentification syslogLogin/syslogPassword, le template à utiliser sera &#8220;syslogTpl&#8221;;</div>
<div></div>
<div>Et voilà, bonne utilisation!</div>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/24/server-syslog-centralise/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redimensionner une partition Multipath</title>
		<link>http://cx.cx/2011/02/23/augmenter-la-taille-dune-parition-san-multipath/</link>
		<comments>http://cx.cx/2011/02/23/augmenter-la-taille-dune-parition-san-multipath/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 18:06:33 +0000</pubDate>
		<dc:creator>xavier</dc:creator>
				<category><![CDATA[Générale]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[fdisk]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[multipath]]></category>
		<category><![CDATA[parition]]></category>
		<category><![CDATA[qparted]]></category>
		<category><![CDATA[redimensionnement]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=179</guid>
		<description><![CDATA[1. Redimensionnement d’une partition MULTIPATH sur LINUX 1.1 Introduction Dans cet exemple, nous partons sur une base Linux REDHAT. La baie de disque utilisée est une HP EVA 5000 Une partition existante doit être redimensionnée, le principe est simple : - Redimensionnement de la structure du disque de la baie - Destruction de la partition OS - Re-Création de [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste"><strong><span style="text-decoration: underline;"><br />
</span></strong></div>
<div id="_mcePaste"><span style="text-decoration: underline;">1. Redimensionnement d’une partition MULTIPATH sur LINUX</span></div>
<div><span style="text-decoration: underline;"><strong><br />
</strong></span></div>
<div id="_mcePaste"><span style="text-decoration: underline;">1.1 Introduction</span></div>
<div><strong><span style="text-decoration: underline;"><br />
</span></strong></div>
<div id="_mcePaste">Dans cet exemple, nous partons sur une base Linux REDHAT.</div>
<div>La baie de disque utilisée est une HP EVA 5000</div>
<div id="_mcePaste">Une partition existante doit être redimensionnée, le principe est simple :</div>
<div id="_mcePaste">- Redimensionnement de la structure du disque de la baie</div>
<div id="_mcePaste">- Destruction de la partition OS</div>
<div id="_mcePaste">- Re-Création de la partition OS (avec les nouvelles valeurs)</div>
<div id="_mcePaste">- Redimensionement OS du FileSystem au x dimensions de la nouvelle partition</div>
<div id="_mcePaste">Tout ceci se fait offline.</div>
<div id="_mcePaste"><span style="text-decoration: underline;">1.2 Méthodologie</span></div>
<div><span style="text-decoration: underline;"><strong><br />
</strong></span></div>
<div><span style="text-decoration: underline;">1.2.1 repérer le nom de partition a agrandir</span></div>
<div><span style="text-decoration: underline;"><strong><br />
</strong></span></div>
<div id="_mcePaste">df -h</div>
<pre>/dev/mapper/mpath5p1   99G  188M   94G   1% /DATA/index
/dev/mapper/mpath6p1   99G  7,6G   86G   9% /DATA/data
/dev/mapper/mpath8p1   50G  8,2G   39G  18% /DATA/arch     &lt;== partition a redimensionner
/dev/mapper/mpath9p1   50G  533M   47G   2% /DATA/ctltemp
/dev/mapper/mpath12p1</pre>
<div id="_mcePaste"><span style="text-decoration: underline;">1.2.2 Reperer le UUID du nom de partition (au sens baie de disque) :</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste">multipathd -k</div>
<div id="_mcePaste">multipathd&gt; show multipaths</div>
<div id="_mcePaste">multipathd&gt; mpath7 dm-0  3600508b4000aef990000a00000110000</div>
<div id="_mcePaste">multipathd&gt; mpath8 dm-1  3600508b4000aef990000a00000150000 &lt;== UUID</div>
<div id="_mcePaste">multipathd&gt; mpath3 dm-2  3600508b4000aef990000a00000190000</div>
<div id="_mcePaste">multipathd&gt; mpath9 dm-3  3600508b4000aef990000a00000230000</div>
<div id="_mcePaste">&#8230;</div>
<div id="_mcePaste">multipathd&gt; mpath1 dm-5  3600508b4000aef990000800000300000</div>
<div id="_mcePaste">multipathd&gt; mpath2 dm-6  3600508b4000aef990000800000350000</div>
<div><span style="text-decoration: underline;">1.2.3 Agrandir la LUN avec le CommandView EVA (baie HP nuiquement)</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste">Se connecter en RDP sur le superviseur de la baie.</div>
<div id="_mcePaste">Lancer une console Internet Explorer sur https://localhost:2372/Login</div>
<div id="_mcePaste">Se connecter avec les login/password de la machine  locale (généralement Administrator /</div>
<div id="_mcePaste">password).</div>
<div id="_mcePaste">Cliquer dans le TreeView de gauche jusqu’à « Virtual Disk \ &lt; dimension folder&gt; \ VirtalDiskName&gt; »</div>
<div id="_mcePaste">Sous l’onglet « Capacity », modifier en l’augmentant, la valeur « Requested », et cliquer sur « Apply »</div>
<div><span style="text-decoration: underline;">1.2.4 demonter la partition</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<div>umount /dev/mapper/mpath8p1</div>
<div><span style="text-decoration: underline;">1.2.5 Reparer le fs</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<div>e2fsck -f /dev/mapper/mpath8p1</div>
<div><span style="text-decoration: underline;">1.2.6 Détruire la partition et la recreer aux maximum avec &#8220;parted&#8221; (car multipath)</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<pre><strong>parted /dev/mapper/mpath8</strong>
(parted) print
    Number  Start   End    Size   Type      File system  Fanions
    1      32,3kB  215GB  215GB  primaire  ext3
(parted) rm 1            &lt;== en cet instant il n'y a plus de donnees exploitables !
                             Soit vous allez au bout de la procédure, soit c'est la démission <img src='http://cx.cx/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ...
(parted) mkpart
    Type de partition?  primary/primaire/extended/étendue? primary
    Type de système de fichiers?  [ext2]? ext3
    Début? 32,3kB
    Fin? 120G
(parted) print
    Number  Start   End    Size   Type      File system  Fanions
    1      32,3kB  120GB  120GB  primaire  ext3       &lt;== verifier la prise en compte, c'est gagné...</pre>
<p><span style="color: #ff0000;"><strong><span style="text-decoration: underline;">Remarque</span>: </strong>Vous ne devez surtout pas utiliser <strong>fdisk </strong>(ou un autre utilitaire de manipulation des partitions de volumes simples) car celui-ci va détruire la configuration multipah associé à une LUN et risque de vous faire perdre la totalité de vos données.</span></p>
<p><span style="color: #ff0000;"><br />
</span></p>
<div><span style="text-decoration: underline;">1.2.7 Etendre le filesystem au maximum de la partition</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<pre>e2fsck -f /dev/mapper/mpath8p1
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/mapper/mpath8p1 to 29296527 (4k) blocks.
Le système de fichiers /dev/mapper/mpath8p1 a maintenant une taille de 29296527 blocs.</pre>
<div><span style="text-decoration: underline;">1.2.8 Monter la partition et verifier l&#8217;espace utilisable</span></div>
<div><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste">df -h</div>
<pre>/dev/mapper/mpath5p1   99G  188M   94G   1% /DATA/index
/dev/mapper/mpath6p1   99G  7,6G   86G   9% /DATA/data
/dev/mapper/mpath8p1   200G  8,2G   39G  8% /DATA/arch <strong><span style="color: #339966;">&lt;== ok !! On ne démissionne pas aujourd'hui!</span></strong>
/dev/mapper/mpath9p1   50G  533M   47G   2% /DATA/ctltemp
/dev/mapper/mpath12p1</pre>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/23/augmenter-la-taille-dune-parition-san-multipath/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cluster MySQL HA</title>
		<link>http://cx.cx/2011/02/23/cluster-mysql-ha/</link>
		<comments>http://cx.cx/2011/02/23/cluster-mysql-ha/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 05:22:59 +0000</pubDate>
		<dc:creator>dbaz</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Générale]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[drbd]]></category>
		<category><![CDATA[HA]]></category>
		<category><![CDATA[mysqld]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[slave]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=109</guid>
		<description><![CDATA[1.  Introduction 1.1       Le cluster MySQL : DRBD + HEARTBEAT + Master/Slave MySQL 1.1.1      Pourquoi un cluster HA au lieu d’un cluster NDB ? MySQL propose dans sa suite logicielle, un moteur de Cluster (NDB). Cette solution de continuité de service est très restrictive en matière applicative et ne s’adapte pas à nos besoins (requêtes à jointures complexes [...]]]></description>
			<content:encoded><![CDATA[<p><strong>1.  Introduction<br />
</strong><span style="font-size: 20px; line-height: normal;"> </span></p>
<p><span style="font-size: 20px; line-height: normal;">1.1       Le cluster MySQL : DRBD + HEARTBEAT + Master/Slave MySQL</span><br />
<strong> </strong></p>
<p><strong>1.1.1      Pourquoi un cluster HA au lieu d’un cluster NDB ?</strong></p>
<p><span style="line-height: normal;"><br />
</span></p>
<p>MySQL propose dans sa suite logicielle, un moteur de Cluster (<strong>NDB</strong>). Cette solution de <span style="text-decoration: underline;">continuité de service</span> est très restrictive en matière applicative et ne s’adapte pas à nos besoins (requêtes à jointures complexes non clusterisables).</p>
<p>Nous avons choisi une deuxième méthode de clusterisation, une solution de Haute Disponibilité (Hight Avaliability ou <strong>HA</strong>) basée sur plusieurs briques applicatives.</p>
<p><strong>1.1.2      Les différentes briques du cluster MySQL HA</strong></p>
<p><strong>1.1.2.1         Réplication des données avec « DRBD »</strong></p>
<p>DRBD (Data Replication Block Device) est un programme qui permet de faire de la réplication de données au sens « block » d’unité de stockage (disque, …)</p>
<p>DRBD s’interpose entre l’OS et le périphérique de stockage (dans notre exemple, une partition sur un disque en RAID1) : à chaque fois que l’OS ordonne l’écriture d’un block au contrôleur, c’est sur un périphérique virtuel (/dev/drbd) et une partition virtuelle (/dev/drbd0) que l’OS s’adresse.</p>
<p>DRBD va alors contacter son homologue pour la réplication de ce block (secondary server) et, celui-ci, va écrire le block sur sa propre partition, puis (optionnellement) envoyer une information d’écriture complétée (commit) au serveur maitre (primary server).</p>
<p>Les blocks répliqués peuvent se faire de façon synchrone ou asynchrone en fonction des configurations matérielles et du positionnement  des différents nœuds composant un cluster DRBD.</p>
<p><span style="text-decoration: underline;">Remarque :</span> Dans le cadre d’un cluster DRBD, la partition virtuelle (/dev/drbd0) du serveur secondaire n’est pas montée et n’est pas accessible par l’OS. En effet, il ne faut pas que l’OS du serveur secondaire écrive des blocks qui n’appartiendraient pas au serveur primaire : le cluster serait alors corrompu.</p>
<p><span style="text-decoration: underline;">Remarque :</span> La réplication au sens de DRBD se fait au niveau block-device et non au niveau logique (fileSystem). Si un block de données est corrompu, il sera répliqué et le serveur secondaire aura lui aussi le même block corrompu. Si cette corruption est fatale (partition illisible, filesystem irréparable, …) =&gt; Le cluster DRBD est définitivement perdu (le primaire et le secondaire).</p>
<h5>1.1.2.2         Bascule d’un nœud mort vers un nœud vivant avec « HeartBeat »</h5>
<p>Les deux nœuds du serveur DRBD sont en mode ACTIF / PASSIF. C&#8217;est-à-dire que, en cas de crash du primary server (le nœud actif), il faut aller démarrer l’ensemble des services sur le secondary server car ceux-ci sont arrêtés pour que la réplication puisse se faire correctement.</p>
<p>Pour automatiser la détection du nœud mort et d’automatiser la bascule et le démarrage automatique des services sur le nœud secondaire, nous allons utiliser le programme HeartBeat qui fera tout cela pour nous.</p>
<h5>1.1.2.3         Réplication MySQL native « Master / Slave »</h5>
<p>Afin de se prémunir de la corruption de blocks dans le cadre d’un cluster DRBD (voir 1.1.2.1) , même si ce cas de figure est très rare, nous allons mettre en place une réplication logique des données de notre cluster MySQL afin de pouvoir récupérer une version des données « au plus près » d’un crash et dans le cas de corruption du cluster DRBD.</p>
<h3>1.2       Le cluster « exemple » :</h3>
<p>Dans ce document, nous allons nous baser sur la configuration du cluster &#8220;XXX&#8221; (Cluster MySQL pour le client &#8220;XXX&#8221; de l&#8217;entreprise).</p>
<p>Ce cluster est composé de deux machines physiques pour le cluster MySQL / DRBD et d’une VM (pool Xen XXX-POOL) pour l’esclave MySQL issu de la réplication MASTER/SLAVE.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="64" valign="top">SQL1</td>
<td width="115" valign="top">Primary DRBD</td>
<td width="217" valign="top">192.168.13.98 (bond eth0+eth1)</p>
<p>192.168.168.1 (réseau DRBD)</p>
<p><em>192.168.194.55   (réseau backup)</em></td>
<td width="242" valign="top">login / pass = root / toto</td>
</tr>
<tr>
<td width="64" valign="top">SQL2</td>
<td width="115" valign="top">Secondary DRBD</td>
<td width="217" valign="top">192.168.13.99 (bond eth0+eth1)</p>
<p>192.168.168.2 (réseau DRBD)</p>
<p><em>192.168.194.56   (réseau backup)</em></td>
<td width="242" valign="top">login / pass = root / toto</td>
</tr>
<tr>
<td width="64" valign="top">SQL3</td>
<td width="115" valign="top">Slave MySQL</td>
<td width="217" valign="top">10.20.0.36</td>
<td width="242" valign="top">login / pass = root / toto</td>
</tr>
</tbody>
</table>
<p>Le « réseau DRBD » est destiné à la réplication au sens de DRBD, il est composé de deux interfaces GBits reliées par un cable croisé.</p>
<p>L’ensemble des données à répliquer au sens de DRBD sera monté dans un point de montage « /data » qui contiendra pour MySQL : les configurations, les datas, les sauvegardes, …</p>
<p><span style="text-decoration: underline;">Remarque :</span> Les trois machines ont un point commun : elles disposent toutes d’un serveur MySQL, nous utiliserons une normalisation du filesystem qui sera commune à toutes les machines du cluster pour une meilleure lisibilité.</p>
<p><strong> </strong></p>
<h3>2.  Installations et Configurations</h3>
<h3>2.1       Normalisation des filesystems</h3>
<p>Sur les trois nœuds du cluster MySQL, nous allons utiliser le nommage suivant :</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="245" valign="top">/data</td>
<td width="393" valign="top"></td>
</tr>
<tr>
<td width="245" valign="top">/data/downloads</td>
<td width="393" valign="top">Divers objets hors distrib</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql</td>
<td width="393" valign="top"></td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/conf</td>
<td width="393" valign="top">Le fichier de config de MySQL   « my.cnf »</p>
<p>Un lien sera fait de /etc/my.cnf   vers ce fichier.</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/backups</td>
<td width="393" valign="top">Les backups des databases</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/run</td>
<td width="393" valign="top">Le fichier de socket de MySQL</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/datafiles</td>
<td width="393" valign="top"></td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/datafiles/databases</td>
<td width="393" valign="top">Les données des bases de données   (MyIsam et InnoDB)</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/datafiles/innodb_default</td>
<td width="393" valign="top">Le tablespace par défaut du moteur   InnoDB</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/logs</td>
<td width="393" valign="top"></td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/logs/text</td>
<td width="393" valign="top">Les logs applicatives (pour le   debug)</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/logs/binnary</td>
<td width="393" valign="top">Les logs binaires (Redologs)</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/logs/undo</td>
<td width="393" valign="top">Les logs transactionnels   (Undologs)</td>
</tr>
<tr>
<td width="245" valign="top">/data/mysql/scripts</td>
<td width="393" valign="top">Les scripts (sauvegarde, …)</td>
</tr>
</tbody>
</table>
<p><span style="text-decoration: underline;">Remarque :</span> N’oublions pas que sur le secondary-DRBD le point de montage « /data » est vide car la partition n’est pas montée, seul le processus de réplication DRBD du serveur y a accès pour écrire les blocks provenant du primary-DRBD.</p>
<h3>2.2       Installation du cluster DRBD</h3>
<h4>2.2.1      Les packages</h4>
<p>Cette installation est basée sur une openSuSE 11.3 64bits. Les packages DRBD sont présents dans la distrib et installable par YAST:</p>
<p>-          <strong>drbd-8.3.7-2.5.x86_64</strong></p>
<p>-          yast2-drbd-2.13.1-221.2.noarch                (managment par Yast : optionnel)</p>
<p><strong><br />
</strong></p>
<h4>2.2.2      Configuration</h4>
<h5>2.2.2.1         Fichier de configuration principal</h5>
<p>Un seul fichier de configuration est nécessaire eu bon fonctionnement de DRBD, attention, ce fichier doit être <span style="text-decoration: underline;">identique</span> que le primary et le secondary.</p>
<h6>a.       Détails du fichier /etc/drbd.conf :</h6>
<p>global {   usage-count yes;    }</p>
<p>common {</p>
<p>protocol C;</p>
<p>handlers {</p>
<p>pri-on-incon-degr     &#8220;/usr/lib/drbd/notify-pri-on-incon-degr.sh;</p>
<p>/usr/lib/drbd/notify-emergency-reboot.sh;</p>
<p>echo b &gt; /proc/sysrq-trigger ;</p>
<p>reboot -f&#8221;;</p>
<p>pri-lost-after-sb     &#8220;/usr/lib/drbd/notify-pri-lost-after-sb.sh;</p>
<p>/usr/lib/drbd/notify-emergency-reboot.sh;</p>
<p>echo b &gt; /proc/sysrq-trigger ;</p>
<p>reboot -f&#8221;;</p>
<p>local-io-error         &#8220;/usr/lib/drbd/notify-io-error.sh;</p>
<p>/usr/lib/drbd/notify-emergency-shutdown.sh;</p>
<p>echo o &gt; /proc/sysrq-trigger ;</p>
<p>halt -f&#8221;;</p>
<p>}</p>
<p>startup {    }</p>
<p>disk {</p>
<p>on-io-error detach; ó Sur une I/O error, on arrête de répliquer !</p>
<p>}</p>
<p>net {</p>
<p>cram-hmac-alg &#8220;sha1&#8243;;</p>
<p>shared-secret &#8220;drbd-sql&#8221;;       ó clé de hashage pour la communication</p>
<p>entre les noeuds</p>
<p>}</p>
<p>syncer {</p>
<p>rate 800M;                 ó Taux de transfert voulu sur le lien de réplication</p>
<p>al-extents 257;</p>
<p>}</p>
<p>}</p>
<p><strong>resource cluster0</strong>{                                ó NOM DE NOTRE CLUSTER DRBD</p>
<p>protocol C;    <span style="text-decoration: underline;">TYPE DE REPLICATION :</span> C ó synchrone</p>
<p>A ó Asynchrone</p>
<p>B ó semi synchrone (en mémoire)</p>
<p>net {</p>
<p>cram-hmac-alg &#8220;sha1&#8243;;</p>
<p>shared-secret &#8220;drbd-sql&#8221;; ó mot de passe sha1</p>
<p>}</p>
<p>on <strong>sql-primaire</strong> {          ó nom DNS du primary DRBD</p>
<p>device /dev/drbd0;   ó nom de la partition virtuelle</p>
<p>disk /dev/sda4;                   ó nom de la partition réelle</p>
<p>address 192.168.168.1:8888; ó IP et port TCP de réplication DRBD</p>
<p>meta-disk internal;</p>
<p>}</p>
<p>on sql-secondaire {              ó Pareil sur le secondaire</p>
<p>device /dev/drbd0;</p>
<p>disk /dev/sda4;</p>
<p>address 192.168.168.2:8888;</p>
<p>meta-disk internal;</p>
<p>}</p>
<p>}</p>
<h6>b.       Importance du fichiers /etc/hosts</h6>
<p>Afin de se prémunir des problématiques DNS, il convient d’indiquer dans le fichier hosts de chaque nœud DRBD les adresses et noms de leurs homologues.</p>
<p>-          Sur le PRIMARY <span style="text-decoration: underline;">comme sur</span> le SECONDARY</p>
<p>…</p>
<p>192.168.13.98   sql-primaire</p>
<p>192.168.13.99   sql-secondaire</p>
<p>…</p>
<h4>2.2.2.2         La  préparation de la partition virtuelle DRBD</h4>
<p>Les deux serveurs DRBD sont dans notre cas configurés pour utiliser un disque logique « /dev/sda » en RAID-1 sur deux disques physiques.</p>
<p>Sur les deux serveurs, il va falloir créer une partition (« /dev/sda1 ») de même taille et de même nom.</p>
<p>Dans notre cas, nous allons utiliser une partition de 100Go sur le disque.</p>
<p>Attention cette partition ne doit pas être formatée car DRBD doit y inscrire des données qui lui sont propres (« méta données ») et qui servent à la réplication entre le primary et le secondary. Le formatage s’éffectuera sur la partition virtuelle de DRBD (voir ) qui saura préserver ainsi ses méta datas.</p>
<p><span style="text-decoration: underline;"> </span></p>
<p><span style="text-decoration: underline;"> </span></p>
<p><span style="text-decoration: underline;">Méthode à appliquer sur le PRIMARY (uniquement) : </span></p>
<p><span style="text-decoration: underline;"> </span></p>
<p>1)       fdisk /dev/sda                                                                       on crée la partion de 100Go /dev/sda1</p>
<p>2)      drbdadm create-md all                                                       création des metadatas dans la partinion</p>
<p>3)      rcdrbd start                                                                              démarrage du démon drbd</p>
<p>4)      drbdadm &#8212; &#8211;overwrite-data-of-peer primary all    ceci est le nœud primaire DRBD</p>
<p>5)      mkfs.ext3 /dev/drbd0                                                         formatage en préservant les métadonnées</p>
<p><span style="text-decoration: underline;">Remarque : </span></p>
<p><span style="text-decoration: underline;"> </span></p>
<p>Si des informations apparaissent sur les premiers blocks de la partition et indiquant que celle-ci a déjà été formatée auparavant, DRBD va refuser d’y créer les métadonnées, même si la partition a été détruite et re-créée. Il faut détruire les blocks avec :</p>
<p>-          dd if=/dev/zero bs=1M count=1 of=/dev/sda4</p>
<p>-          sync</p>
<p>Puis poursuivre au point 2).</p>
<p><span style="text-decoration: underline;">Méthode à appliquer sur le SECONDARY (uniquement) : </span></p>
<p>Même chose que pour le PRIMARY à l’exception du formattage ext3. Nous allons également renseigner ce nœud qu’il est le secondaire.</p>
<p>1)      fdisk /dev/sda                                                                               on crée la partion de 100Go /dev/sda1</p>
<p>2)      drbdadm create-md all                                                                              création des metadatas dans la partition</p>
<p>3)      rcdrbd start                                                                                     démarrage du démon drbd</p>
<p>4)      drbdadm secondary all                                                                               ceci est le nœud secondaire DRBD</p>
<p><span style="text-decoration: underline;">Remarque :</span> Il faut attendre un certain temps avant que la totalité de la partition drbd soit répliquée sur le nœud secondaire, on peut voir l’évolution avec  (dans cette exemple depuis le PRIMARY NODE):</p>
<p>&gt; cat /proc/drbd</p>
<p>version: 8.3.7 (api:88/proto:86-92)</p>
<p>srcversion: 04F43AA72D62F7D4F0CB048</p>
<p>0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r&#8212;-</p>
<p>ns:13985900 nr:0 dw:1947208 dr:12043684 al:930 bm:752 lo:1 pe:115</p>
<p>ua:142 ap:0 ep:1 wo:b oos:101513508</p>
<p>[=&gt;..................] sync&#8217;ed: <strong>12.1%</strong> (99132/112756)M</p>
<p>finish: 0:13:22 speed: 126,520 (108,976) K/sec</p>
<p>Lorsque la synchronisation sera achevée la commande donnera un message ressemblant à :</p>
<p>&gt; cat /proc/drbd</p>
<p>version: 8.3.7 (api:88/proto:86-92)</p>
<p>srcversion: 04F43AA72D62F7D4F0CB048</p>
<p>0: cs:<strong>Connected</strong> ro:<strong>Primary/Secondary</strong> ds:<strong>UpToDate/UpToDate</strong> C r&#8212;-</p>
<p>ns:115495756 nr:0 dw:1947208 dr:113549000 al:930 bm:7048 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0</p>
<h4>2.2.3      Arrêt / Marche du Cluster DRBD</h4>
<p>Le script d’init /etc/init.d/drbd (ou rcdrbd) accepte les commutateurs « stop » ou « start ». Ceci a pour effet de démarrer le processus DRBD, sur le primary comme sur le secondary, mais les datas ne sont pas encore disponible à ce stade, il faudra monter la partition sur le point de montage voulu, à savoir :</p>
<p>Sur chacun des serveurs, le processus de réplication écoute, comme indiqué dans le fichier de configuration global, sur le port TCP 8888.</p>
<h5>2.2.3.1         Démararge du CLUSTER DRBD :</h5>
<p>Deux opérations sont à éffectuer :</p>
<p>-          Sur le PRIMARY  (en premier):</p>
<p><strong>rcdrbd start</strong></p>
<p><strong>mount /dev/drdb0   /data</strong></p>
<p>-          Sur le SECONDARY :</p>
<p><strong>rcdrbd  start</strong></p>
<p><em>(pas de montage de /data évidement…)</em></p>
<p>Arrêt du cluster DRDB :</p>
<p>-          Sur le PRIMARY  (en premier)</p>
<p>rcdrbd stop</p>
<p>umount /data</p>
<p>-          Sur le SECONDARY</p>
<p>rcdrbd stop</p>
<h4>2.2.4      Supervision du cluster DRBD</h4>
<p>L’état de la réplication DRBD, sur le primaire comme sur le secondaire, s’éffectue en capturant le contenu de « /proc/drbd »</p>
<p>Sur le primary :</p>
<p>&gt; cat /proc/drbd</p>
<p>&gt; version: 8.3.7 (api:88/proto:86-92)</p>
<p>&gt; srcversion: 04F43AA72D62F7D4F0CB048</p>
<p>&gt; 0: <strong>cs:Connected</strong> ro:<strong>Primary</strong>/Secondary ds:<strong>UpToDate/UpToDate</strong> C r&#8212;-</p>
<p>&gt;    ns:72 nr:0 dw:1164292 dr:115974011 al:218 bm:7071 lo:0 pe:0 ua:0 &gt;ap:0 ep:1 wo:b oos:0</p>
<p>Sur le secondary :</p>
<p>&gt; cat /proc/drbd</p>
<p>&gt; version: 8.3.7 (api:88/proto:86-92)</p>
<p>&gt; srcversion: 04F43AA72D62F7D4F0CB048</p>
<p>&gt; 0: <strong>cs:Connected</strong> ro:<strong>Secondary</strong>/Primary ds:<strong>UpToDate/UpToDate</strong> C r&#8212;-</p>
<p>&gt;    ns:72 nr:0 dw:1164292 dr:115974011 al:218 bm:7071 lo:0 pe:0 ua:0 &gt;ap:0 ep:1 wo:b oos:0</p>
<p>Avec :</p>
<p>RO=Primary/X sur le primaire, Secondary/X sur le secondaire</p>
<p>avec X={ Primary | Secondary | DUnknown &lt;= problème ! }</p>
<p>CS=état de la connexion réseau de réplication</p>
<p>NS=bytes émis</p>
<p>NR=bytes reçus</p>
<p>DW=données écrites physiquement sur le disque</p>
<p>DR=Données lues sur le disque</p>
<h3>2.3       Installation de la réplication MySQL Maitre / Esclave</h3>
<h4>2.3.1      Configuration du maitre</h4>
<p>Activer la journalisation des logs binaires dans /etc/my.cnf :</p>
<p>log-bin</p>
<p>Créer un user pour la réplication et qui sera utilisé par le SLAVE, puis lui donner les droits d’accèder au processus de réplication :</p>
<p>mysql&gt; create user replic identified by replic ;</p>
<p>mysql&gt; GRANT REPLICATION SLAVE ON *.* TO &#8216;replic&#8217;@'%&#8217; IDENTIFIED BY &#8216;replic&#8217;;</p>
<p>mysql&gt; GRANT SELECT, PROCESS, FILE, SUPER, RELOAD ON *.* TO &#8216;replic&#8217;@'%&#8217; IDENTIFIED BY &#8216;replic&#8217;;</p>
<p>Modifier le fichier de conf global du maitre (/etc/my.cnf)  pour lui indiquer les bases qu’il ne doit pas répliquer :</p>
<p>…</p>
<p>binlog-ignore-db = mysql</p>
<p>binlog-ignore-db = base_a_exclure</p>
<p>…</p>
<h4>2.3.2      Configuration de l’esclave</h4>
<h5>2.3.2.1         Modification du fichier de conf global</h5>
<p>Modifier le fichier /etc/my.cnf du SLAVE et ajouter :</p>
<p>server-id           = 10  ó identifiant différent de celui du maitre</p>
<p>relay-log           =/data/mysql/logs/binary/relaybinlog.rotation</p>
<p>relay-log-index     =/data/mysql/logs/binary/relaybinlog.index</p>
<p>relay-log-info-file =/data/mysql/conf/relay-log.info</p>
<p>master-info-file    =/data/mysql/conf/master.info</p>
<p>Redémarrer MySQL pour le prendre en compte (« rcmysql restart »)</p>
<h5>2.3.2.2         Initiation du processus de réplication</h5>
<p>a)      Arreter (éventuellement) le processus ESCLAVE :</p>
<p>Mysql&gt; stop slave ;</p>
<p>b)      Faire un dump SUR LE MAITRE des bases à restaurer SUR L’ESCLAVE pour initier le processus :</p>
<p>Maitre&gt; mysqldump            -h localhost</p>
<p>-uroot</p>
<p>&#8211;lock-all-tables</p>
<p><strong>&#8211;master-data </strong><em>ó</em><em>Contient les SCN des binarylogs pour l’esclave</em><strong> </strong></p>
<p><strong>&#8211;databases mabase </strong></p>
<p><strong>&#8211;flush-logs </strong></p>
<p>&#8211;add-drop-database &#8211;allow-keywords</p>
<p>&#8211;quick</p>
<p>&#8211;complete-insert</p>
<p>&#8211;add-drop-table</p>
<p>&#8211;create-options</p>
<p>&#8211;dump-date</p>
<p>&#8211;triggers &#8211;routines &#8211;events</p>
<p>&#8211;debug-info</p>
<p>&#8211;verbose</p>
<p>&#8211;comments</p>
<p>&#8211;result-file=mondump.sql</p>
<p>c) restaurer le dump précédent sur l’esclave</p>
<p>esclave&gt; mysql –uroot –D mabase &lt; mondump.sql</p>
<p>d)      Repérer dans le dump précédent le nom du fichier de log binaire renseigné par le Maitre lors du dump ainsi que la position dans ce log.</p>
<p><em>(imaginons que le nom du log soit « &#8217;binarylog.000062 », que la position dans le log soit « 106 » et que l’addresse IP source physique du maitre soit &#8217;192.168.13.98&#8242;)</em></p>
<p>Il faut ensuite informer l’esclave de ces données en tapant :</p>
<p>mysql&gt; change master to</p>
<p>master_host=    &#8217;192.168.13.98&#8242;,</p>
<p>master_user=    &#8216;replic&#8217;,</p>
<p>master_password=&#8217;replic&#8217;,</p>
<p>master_log_file=&#8217;binarylog.000062&#8242;,</p>
<p>master_log_pos= 106;</p>
<p>Il faut ensuite démarrer le processus de récplication sur l’esclave :</p>
<p>mysql&gt; start slave ;</p>
<p>mysql&gt; show slave status\G ;</p>
<h3>2.4       Installation de HeartBeat</h3>
<h4>2.4.1      Présentation</h4>
<p>HeartBeat est basé sur une interrogation régulière de ses voisins afin de déterminer si, oui ou non, un nœud d’un cluster est mort ou non (/etc/ha.d/ha.cf)</p>
<p>S le cas où HeartBeat constate, depuis un nœud « passif », qu’un nœud dit « actif » est mort, alors un ensemble de processus est déclanché pour prendre l’identité de l’ancien nœud actif maintenant mort (/etc/ha.d/haresources).</p>
<p>L’ensemble des programmes et scripts dont HeartBeat va se servir sont dans /etc/ha.d/resource.d/.</p>
<h4>2.4.2      Configuration de /etc/ha.d/ha.cf</h4>
<p>Ce fichier contient la config générale de HeartBeat, il doit être présent à l’identique sur le nœud ACTIF et sur le nœud PASSIF.</p>
<p>logfile /var/log/ha.log              fichier de log standard</p>
<p>debugfile /var/log/ha-debug.log      fichier de log supplémentaire (debug)</p>
<p>logfacility     local0               facility de syslogd</p>
<p>keepalive 2                          On teste toutes les 2 secondes l’état des nœuds.</p>
<p>warntime 8                           On alerte si un nœud ne répond pas durant 8 secondes.</p>
<p>deadtime 15                          A 15 secondes, on considère que le nœud est mort.</p>
<p>initdead 30                          Temps de démarrage max toléré avant de diagnostiquer  que le nœud est mort.</p>
<p>mcast bond0 225.0.0.1 694 1 0        cartes réseaux (mcast ou bcast) pour atteindre les HeartBeats</p>
<p>mcast eth2  225.0.0.1 694 1 0        cartes réseaux (mcast ou bcast) pour atteindre les HeartBeats</p>
<p>auto_failback off                    Pas de retour arrière automatique, trop dangereux</p>
<p>node sql-primaire                 quels sont les nœuds composant la ferme HeartBeat ?</p>
<p>node sql-secondaire               quels sont les nœuds composant la ferme HeartBeat ?</p>
<p>ping 192.168.13.253                  Chaque nœud doit également pouvoir accèder à la gateway</p>
<p>pour être caractérisé de « vivant ».</p>
<p>deadping 5                           si le ping ne répond pas pendant 5 secondes, la cible est considérée comme morte.</p>
<p>respawn hacluster /usr/lib64/heartbeat/ipfail</p>
<p>apiauth ipfail gid=haclient uid=hacluster</p>
<h4>2.4.3      Configuration des resources HA</h4>
<p>Dans le cas où un nœud passif HeartBeat considère que son pendant actif est mort, il va déclancher un certain nombre d’actions pour prendre son identité. Ces actions sont décrites dans le fichier <strong>/etc/ha.d/</strong><strong> haresources.</strong></p>
<p>Les ordres commencent par spécifier le hostname du serveur actif à monitorer (le primaire) puis une série d’actions séparées par des espaces.</p>
<p>Si une (ou plusieurs) adresse IP figurent comme action dans une liste d’action, cela signifie que HeartBeat doit dynamiquement assigner à une de ses cartes réseaux cette adresse IP (principe d’adresse IP virtuelle). Ce procédé permet de s’affranchir d’un LoadBalancer.</p>
<p><span style="text-decoration: underline;">Exemple sur le custer SQL :</span></p>
<p><span style="text-decoration: underline;"> </span></p>
<p>…</p>
<p>otsql-primaire   192.168.13.100    drbddisk::cluster0    Filesystem::/dev/drbd0::/data::ext3    mysql</p>
<p>…</p>
<p><span style="text-decoration: underline;">Découpage : </span></p>
<p>hostname du primaire actif : otsql-primaire       (ne pas oublier de renseigner les fichiers hosts)</p>
<p>Action 1 : drbddisk::cluster0</p>
<p>Action 2 : Filesystem::/dev/drbd0::/data::ext3</p>
<p>Action 3 : 192.168.13.100</p>
<p>Action 4 : mysql</p>
<p><span style="text-decoration: underline;">Explications :</span></p>
<p>Action1 : va déclencher le programme /etc/ha.d/resources.d/drbddisk avec le paramètre cluster0. Ce programme a pour effet de positionner dynamiquement le nœud DRBD comme PRIMARY  (voir 2.2.2.2)</p>
<p>Action2 : déclenche le programme /etc/ha.d/resources.d/Filesystem en lui passant trois paramètres « /dev/drbd0 », « /data » et « ext3 ». Ce programme va dynamiquement monter la partition virtuelle DRBD sur la partition physique qui lui est associée sur le point de montage /data.</p>
<p>Action3 : assigne l’adresse IP 192.168.13.100 à une de ses interfaces présente sur ce réseau</p>
<p>Action4 : déclenche le programme /etc/ha.d/resources.d/mysql qui démarre le serveur MySQL sur le nœud nouvellement actif.</p>
<h3>2.5       Bascule du cluster : FAIL-OVER / FAIL-BACK</h3>
<p>Le Cluster HA DRBD/MySQL doit basculer sur le nœud SECONDAIRE en cas d’indisponibilité du nœud PRIMARY jugé par HeartBeat. Cette indisponibilité est caractérisée par l’impossibilité des deux HeartBeat de se voir mutuellement et d’un certain nombre de critères (Je ne vois pas le HeartBeat en face mais vois-je la passerelle ? etc).</p>
<h4>2.5.1      FAIL OVER :</h4>
<p>Dans le cas « théorique » où l’on voudrait basculer du nœud primaire vers le nœud secondaire du cluster DRBD (dans le cadre d’une maintenance par exemple), il faut faire croire au nœud secondaire que le processus HEARTBEAT du nœud primaire est mort, il suffit donc de le stopper :</p>
<p><strong>PRIMARY&gt; rchertbeat stop</strong></p>
<p><strong> </strong></p>
<p>Sur le primary : Heartbeat va alors stopper les services associés aux haressources (drbd et mysql) puis va se libérer de l’adresse ip virtuelle.</p>
<p>Sur le secondary : le Heartbeat local va constater le décès du heartbeat primaire, va alors s’affecter l’adresse IP virtuelle, monter la partition drbd dans /data puis démarrer mysql  =&gt; le cluster a basculé.</p>
<h4>2.5.2      FAIL BACK :</h4>
<p>Pour revenir en arrière (« <span style="text-decoration: underline;">fail back</span> » ó basculer du secondaire au primaire), il faut dans la même logique taper :</p>
<p><strong>PRIMARY&gt; rcheartbeat start</strong></p>
<p><em> (attendre quelques instants par sécurité que heatbeat soit ok)</em></p>
<p><strong>SECONDARY&gt; rcheartbeat stop</strong></p>
<p><em>(attendre quelques instants par sécurité pour être sur que le nœud PRIMAIRE a bien pris la main)</em></p>
<p><strong>SECONDARY&gt; rcheartbeat start </strong>ß on remet le SECONDARY node en observation.</p>
<p>Pour les mêmes raisons, tout a démarré sur le PRIMARY, tout a été stoppé sur le SECONDARY, la réplication reprend son cours normal.</p>
<h3>3. Sauvegarde et restauration des données MySQL du CLUSTER</h3>
<h1><span style="font-size: 20px; letter-spacing: normal;">3.1       Introduction</span></h1>
<p>Le cluster MySQL au sens de DRBD se résume à l’administration d’un serveur MySQL classique. Les données ne sont en effet présentes à un instant « t » que sur un serveur (le nœud DRBD actif) et en secours sur le serveur SLAVE MySQL.</p>
<p>Comme dans le cadre d’un serveur classique, le principe réside dans la réalisation d’un dump d’une base de données effectué base ouverte et active en s’assurant de la cohérence des données. Les tables stoquées par le moteur MyISAM seront verrouillées pendant ce backup et ne sont pas recommandées pour cela alors que les tables du moteur InnoDB ne le seront pas.</p>
<h3>3.2       Sauvegarde</h3>
<p>Le script <strong>/data/mysql/scripts/sauvegarde_full.sh</strong> permet de lancer un dump ds bases de données du Cluster en profitant des fonctionnalités transactionnelles de InnoDB pour en assurer la cohérence</p>
<p>Une transaction est ouverte avant de dumper puis est fermée une fois le dump terminé =&gt; Les données sont donc cohérentes.</p>
<p>Ce script est automatisé par la crontab et réalise les dumps dans <strong>/data/mysql/backups/</strong></p>
<p><span style="text-decoration: underline;">Remarque :</span> Les dumps contiennent en fin de fichier l’information « &#8211; Dump completed on YYYY-MM-DD HH :MM :SS », une information qui peut être très intéressante dans le cadre d’un recovery.</p>
<p><span style="text-decoration: underline;">Attention :</span> les tables du moteur <span style="text-decoration: underline;">MyISAM</span> ne seront pas cohérentes ! Si un programmeur persiste à utiliser ce moteur, il faudra utiliser le script /data/mysql/scripts/sauvegarde_full_MYISAM.sh mais les tables seront verrouillées pendant le dump, ce qui peut parfois s’avérer très gênant.</p>
<h3>3.3       Restauration de données</h3>
<h4>3.3.1      Introduction</h4>
<p><span style="text-decoration: underline;">Définition :</span></p>
<p>Une restauration (ou « <strong>RESTORE</strong> ») consiste à rétablir les données d’une database à celles exactement présentent dans une sauvegarde (dump SQL dans notre cas).</p>
<p>Un recouvrement (ou « <strong>RECOVER</strong> ») consiste à rejouer la vie d’une database à partir d’un certain moment (celui d’un RESTORE généralement) jusqu’à un autre point (avant un crash, avant une erreur utilisateur, …)</p>
<p>Avant toute restauration, il faudra empêcher les utilisateurs externes d’accéder à vos databases, sous peine de corrompre les données. Pour cela, il faut ajouter le commutateur « <strong>skip-networking</strong> » dans la section « [MYSQLD] » de votre fichier de configuration globale « /etc/my.cnf ». Il ne faudra pas oublier d’enlever ce commutateur une fois la restauration terminée…</p>
<p>Le commutateur skip-networking comme son nom l’indique interdit les accès réseau (IP) et seules les opérations basées sur les sockets Unix sont autorisées, dont feront parti vos ordres de restauration en command line.</p>
<p>Plusieurs types de restauration de données peuvent être demandés :</p>
<p>-          <strong>Restauration totale</strong> : on parle de  « restauration totale ». Il s’agit de la restauration d’un dump précis. Cette restauration peut être restreinte à une base de données ou une table d’une base de données.</p>
<p>-          <strong>Restauration partielle sur erreur :</strong> (Point In Time Recovery) : Une bêtise à été commise par un utilisateur à une heure H, les utilisateurs demandent à ce que une base B soit restaurée à sa situation avant l’erreur utilisateur et au plus près de H</p>
<p>-          <strong>Restauration partielle après un crash :</strong> Un crash s’est produit. Il est demandé de restaurer une database au plus près possible d’avant le crash.</p>
<p>Une restauration « <strong>partielle</strong> » consiste en la restauration totale d’un fichier de sauvegarde (<strong>RESTORE</strong>) et l’application d’un journal de transactions DDL et DML (<strong>RECOVER</strong>) jusqu’à un certain point (un numéro de transaction ou une date &amp; heure).</p>
<h4>3.3.2      Restauration totale</h4>
<p>C’est le cas le plus simple, celui où un utilisateur demande la restauration totale d’une base de données par l’injection d’un dump réalisé précédemment.</p>
<p><em>Imaginons dans ce cas que le dump ainsi pointé par l’utilisateur est /data/backups/mondump.sql.</em></p>
<p>-          Restauration d’une database « MABASE » sauvegarde par le dump « <em>dump_de_ma_base.sql » :</em></p>
<p>&gt; cd <em>/data/backups/</em></p>
<p><em>&gt; mysql  -uroot  &lt;  dump_de_ma_base.sql</em></p>
<p><em><br />
</em></p>
<h4>3.3.3      Restauration partielle</h4>
<h5>3.3.3.1         Introduction</h5>
<p>Une restauration « partielle » ou « PITR (PointInTimeRecovery)» consiste en une restauration FULL (<strong>RESTORE</strong>) et en l’application des instructions DDL et DML (<strong>RECOVER</strong>) jusqu’à une certaine date, heure ou encore un certain numéro de transaction SQL.</p>
<p>Une restauration (RESTORE) n’est possible que si l’on dispose du dump contenant les données exigées (un dump est réalisé à heures fixes ou sur demandes, …) pour une date/heure précise.</p>
<p>Il est possible d’effectuer après cela un RECOVER en fonction de diverses situations (erreur DBA ou erreur utilisateur, crash d’un fichier, crash server, …), ceci afin de remonter la database au plus près de la réalité des données avant l’erreur critique.</p>
<p>MySQL permet d’enregistrer les ordres DDL et DML utiles adressées à votre base de données sous la forme d’un format de fichiers binaires appelés « <strong>binary logs</strong> ».</p>
<p>L’activation de cette trace SQL se fait par ajout du commutateur « log-bin » dans my.cnf et d’un ensemble de paramètres de gestion des logs binaires (voir section 4.1.1).</p>
<p><strong>mysqlbinlog</strong> est un utilitaire permettant de lire les fichiers de logs binaires et d’en exporter les informations sous un format textuel afin de les « rejouer » sur une base de données après un « RESTORE ».</p>
<h5>3.3.3.2         Restauration totale au plus près d’avant un crash</h5>
<p><span style="text-decoration: underline;">Cas classique :</span> Une sauvegarde FULL d’une database MABASE a été effectuée le matin à 00h00 sous la forme d’un dump SQL exécuté par myssqldump.</p>
<p>A 06h00, un fichier composant tout ou partie d’une des databases InnoDB présente une erreur d’intégrité. La database est alors inaccessible.</p>
<p><span style="text-decoration: underline;">Méthode :</span></p>
<p>-          Fermer l’accès du serveur aux utilisateurs</p>
<p><em>Ajouter « skip-networking » dans /etc/my.cnf + rcmysql restart</em></p>
<p><em> </em></p>
<p>-          Détruire la database</p>
<p><em>&gt; mysql –uroot   -e ‘drop database dbname ; ’</em></p>
<p><em> </em></p>
<p>-          Restaurer le dump SQL (au sens de mysqldump) le plus récent possible.</p>
<p><em>&gt; mysql  –uroot   &lt;  /data/mysql/backups/dump_dbname_YYYYMMDD_HHIISS.sql</em></p>
<p><em> </em></p>
<p>-          Appliquer les ordres DDL et DML des journaux binaires à partir de la date de génération du dump</p>
<p>&gt; mysqlbinlog  /data/mysql/logs/binary/binarylog.*</p>
<p>&#8211;database=dbname ß recover restreint à la database « dbname »</p>
<p>&#8211;start-datetime=&#8221;2010-12-29 09:57:23&#8243; ß date de fin du dump</p>
<p>&#8211;to-last-log ß jusqu’à la fin du dernier log binaire disponible</p>
<p>&#8211;result-file=/tmp/ordres_a_rejouer.sql</p>
<p><span style="text-decoration: underline;">Remarque :</span> la date de fin du dump se trouve dans le dump sql de la sauvegarde Full, en bas de fichier.</p>
<p><span style="text-decoration: underline;">Remarque :</span> mysqlbinlog va ensuite lire les logs binaires et en extraire un contenu textuelle d’ordres DDL et / ou DML, ce fichier est indiqué par –result-file=…. Il faudra appliquer ces logs SQL exactement de la même façon que l’on applique un DUMP :</p>
<p><em> &gt; mysql  -uroot   &lt;   /tmp/ordres_a_rejouer.sql</em></p>
<p>-          Ouvrir l’accès du serveur aux utilisateurs</p>
<p><em>Commenter « skip-networking » dans /etc/my.cnf + rcmysql restart</em></p>
<p><em> </em></p>
<p><span style="text-decoration: underline;">Attention </span>: un PITR à une heure près est risqué car, en une seule seconde, plusieurs instructions peuvent altérer la database, il n’est donc pas certain que une heure à la seconde près soit une méthode « sure » pour pratiquer un Recover dans le temps.</p>
<p>Il est plus sur d’indiquer un numéro de transaction  (« log position » en MySQL).  Ce numéro est identifié par « MASTER_LOG_POS » qui  trouve en haut de chaque dump dans le champ comme par exemple :</p>
<p>&#8211; CHANGE MASTER TO MASTER_LOG_FILE=&#8217;binarylog.000547&#8242;, <strong>MASTER_LOG_POS=106</strong>;</p>
<p>Ici, l’ordre de recover serait :</p>
<p>mysqlbinlog  /data/mysql/logs/binary/binarylog.*</p>
<p>&#8211;database=dbname</p>
<p>&#8211;start-position  =&#8221;107&#8243;</p>
<p>&#8211;to-last-log</p>
<p>&#8211;result-file=/tmp/ordres_a_rejouer.sql</p>
<p><em> </em></p>
<h5>3.3.3.3         Restauration totale, Recouvrement partiel (PITR)</h5>
<p>Comme dans le point précédent, il faut d’ahabord restaurer le dump de la dernière sauvegarde FULL.</p>
<p>Ensuite, il faut pratiquer un recover, mais pas jusqu’au au bout.</p>
<h6>a.       <span style="text-decoration: underline;">Exemple 1 :</span> Indication horaire</h6>
<p><strong> </strong></p>
<p>Par exemple, à 12:00:00 un programme a détruit des tables, les applis ne fonctionne plus et on demande de restaurer à 11 :59 :00.</p>
<p>La procédure est strictement identique à celle d’un recover total sauf que le commutateur « &#8211;to-last-log » doit être remplacé par « &#8211;end-datetime=&#8221;2010-12-29 11:59:00&#8243; »</p>
<p><strong>mysqlbinlog </strong></p>
<p><strong>/data/mysql/logs/binary/binarylog.* </strong></p>
<p><strong>&#8211;database=dbname </strong></p>
<p><strong>&#8211;start-position  =&#8221;107&#8243; </strong><strong> </strong></p>
<p><strong>&#8211;end-datetime=&#8221;2010-12-29 11:59:00&#8243; </strong><strong> </strong></p>
<p><strong>&#8211;result-file=/tmp/ordres_a_rejouer.sql</strong><strong> </strong></p>
<p>Comme indiqué dans le point précédent, cette méthode est incertaine car en une seconde (11 :59 :00) il peut se passer plusieurs transactions et on peut ainsi rejouer les ordres SQL destructeurs rendant le recovery inutile ou au contraire rater les ordres qui se sont joués en fait la seconde d’après …</p>
<h6>b.       <span style="text-decoration: underline;">Exemple 2:</span> Indication fonctionnelle :</h6>
<p>L’utilisateur vous indique que un ordre « drop table ma_table » a été passé par erreur, provoquant la catastrophe qui a suivi.</p>
<p>Il faut alors repérer dans les logs binaires le LOG_POS de cette ordre pour demander un recover jusqte avant celui-ci.</p>
<p>mysqlbinlog binarylog.* | grep -B 5 -i &#8220;DROP TABLE MA_TABLE&#8221;</p>
<p>&#8230; (5 lignes &#8216;B&#8217;efore)</p>
<p>&gt; at 2627</p>
<p>&gt; 101228 16:39:09 server id 1  <strong>end_log_pos 2654</strong></p>
<p>&gt; drop table matable</p>
<p>Dans cet exemple, le dernier LOG_POS <span style="text-decoration: underline;">AVANT</span> le drop est le « 2654 », il faut donc pratiquer un recover jusqu’à ce numéro inclus :</p>
<p><strong>mysqlbinlog </strong></p>
<p><strong>/data/mysql/logs/binary/binarylog.* </strong></p>
<p><strong>&#8211;database=dbname </strong></p>
<p><strong>&#8211;start-position  =&#8221;107&#8243; </strong><strong> </strong></p>
<p><strong>&#8211;stop-position=&#8221;2654&#8243;</strong></p>
<p><strong>&#8211;result-file=/tmp/ordres_a_rejouer.sql</strong><strong> </strong></p>
<p>Pour résumer, s’il est IMPOSSIBLE de connaitre un LOG_POSITION (ou s’il n’y a aucunne embiguité mais c’est assez rare), on préférera les Recover à base de STOP-POSITION plustôt que ceux à base de END-DATETIME.</p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<h3>4.  Annexes</h3>
<h3>4.1       Fichiers de configuration MySQL</h3>
<h4>4.1.1      Configuration sur les nœuds du cluster DRBD</h4>
<p><strong>/etc/my.cnf</strong><strong> </strong></p>
<p>[client]</p>
<p>port                            = 3306</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>[mysqld]</p>
<p>port                            = 3306</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>server-id                       =1</p>
<p>skip-external-locking</p>
<p>skip-ndbcluster</p>
<p>default-storage-engine=INNODB</p>
<p># LOGGING #</p>
<p>log_error                       = /data/mysql/logs/text/error.log</p>
<p>general_log                     = ON</p>
<p>general_log_file                = /data/mysql/logs/text/general_log_file.log</p>
<p>log_slow_queries                = ON</p>
<p>slow_query_log_file             = /data/mysql/logs/text/slow_queries.log</p>
<p>long_query_time                 = 4</p>
<p>binlog_format                   = ROW</p>
<p>max_binlog_size                 = 100M</p>
<p>log_bin_index                   = /data/mysql/logs/binary/index.log</p>
<p>log-bin                         = /data/mysql/logs/binary/binarylog.rotation</p>
<p>expire_logs_days                = 15</p>
<p>binlog-ignore-db                = mysql</p>
<p>binlog-ignore-db                = test</p>
<p># Parametrages myISAM #</p>
<p>datadir                         = /data/mysql/datafiles/databases</p>
<p>key_buffer_size                 = 16M</p>
<p>max_allowed_packet              = 1M</p>
<p>table_open_cache                = 64</p>
<p>sort_buffer_size                = 512K</p>
<p>net_buffer_length               = 8K</p>
<p>read_buffer_size                = 256K</p>
<p>read_rnd_buffer_size            = 512K</p>
<p>myisam_sort_buffer_size         = 8M</p>
<p># Parametrage InnoDB #</p>
<p>innodb_data_home_dir            = /data/mysql/datafiles/innodb_default</p>
<p>innodb_data_file_path           = ibdata01:50M:autoextend</p>
<p>innodb_file_per_table           = 1</p>
<p>innodb_log_group_home_dir       = /data/mysql/logs/undo</p>
<p>innodb_buffer_pool_size        = 8192M</p>
<p>innodb_additional_mem_pool_size= 2M</p>
<p>[safe_mysqld]</p>
<p>log-error                       = /data/mysql/logs/text/mysqld.log</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>[mysqldump]</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>quick</p>
<p>max_allowed_packet              = 16M</p>
<p>[mysql]</p>
<p>no-auto-rehash</p>
<p>[myisamchk]</p>
<p>key_buffer_size                 = 20M</p>
<p>sort_buffer_size                = 20M</p>
<p>read_buffer                     = 2M</p>
<p>write_buffer                    = 2M</p>
<p>[mysqlhotcopy]</p>
<p>interactive-timeout</p>
<p>[mysqld_multi]</p>
<p>mysqld                          = /usr/bin/mysqld_safe</p>
<p>mysqladmin                      = /usr/bin/mysqladmin</p>
<p>log                             = /data/mysql/logs/text/mysqld_multi.log</p>
<h4>4.1.2      Sur le serveur MySQL SLAVE</h4>
<p><strong>/etc/my.cnf</strong><strong> </strong></p>
<p>[client]</p>
<p>port                            = 3306</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>[mysqld]</p>
<p>port                            = 3306</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>server-id                       = 10</p>
<p>skip-external-locking</p>
<p>default-storage-engine=INNODB</p>
<p>log_error                       = /data/mysql/logs/text/error.log</p>
<p>general_log                     = ON</p>
<p>general_log_file                = /data/mysql/logs/text/general_log_file.log</p>
<p>slow_query_log                  = ON</p>
<p>slow_query_log_file             = /data/mysql/logs/text/slow_queries.log</p>
<p>long-query-time                 = 1</p>
<p>relay-log                       =/data/mysql/logs/binary/relaybinlog.rotation</p>
<p>relay-log-index                 =/data/mysql/logs/binary/relaybinlog.index</p>
<p>relay-log-info-file             =/data/mysql/conf/relay-log.info</p>
<p>master-info-file                =/data/mysql/conf/master.info</p>
<p>datadir                         = /data/mysql/datafiles/databases</p>
<p>key_buffer_size                 = 16M</p>
<p>max_allowed_packet              = 1M</p>
<p>table_open_cache                = 64</p>
<p>sort_buffer_size                = 512K</p>
<p>net_buffer_length               = 8K</p>
<p>read_buffer_size                = 256K</p>
<p>read_rnd_buffer_size            = 512K</p>
<p>myisam_sort_buffer_size         = 8M</p>
<p>innodb_data_home_dir            = /data/mysql/datafiles/innodb_default</p>
<p>innodb_data_file_path           = ibdata01:50M:autoextend</p>
<p>innodb_file_per_table           = 1</p>
<p>innodb_log_group_home_dir       = /data/mysql/logs/undo</p>
<p>[safe_mysqld]</p>
<p>log-error                       = /data/mysql/logs/text/mysqld.log</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>[mysqldump]</p>
<p>socket                          = /data/mysql/run/mysql.sock</p>
<p>quick</p>
<p>max_allowed_packet              = 16M</p>
<p>[mysql]</p>
<p>no-auto-rehash</p>
<p>[myisamchk]</p>
<p>key_buffer_size                 = 20M</p>
<p>sort_buffer_size                = 20M</p>
<p>read_buffer                     = 2M</p>
<p>write_buffer                    = 2M</p>
<p>[mysqlhotcopy]</p>
<p>interactive-timeout</p>
<p>[mysqld_multi]</p>
<p>mysqld                          = /usr/bin/mysqld_safe</p>
<p>mysqladmin                      = /usr/bin/mysqladmin</p>
<p>log                             = /data/mysql/logs/text/mysqld_multi.log</p>
<h3>4.2       Fichiers de configuration DRBD</h3>
<p><strong>/etc/drbd.conf</strong><strong> </strong></p>
<p>global {</p>
<p>usage-count yes;</p>
<p># minor-count dialog-refresh disable-ip-verification</p>
<p>}</p>
<p>common {</p>
<p>protocol C;</p>
<p>handlers {</p>
<p>pri-on-incon-degr &#8220;/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b &gt; /proc/sysrq-trigger ; reboot -f&#8221;;</p>
<p>pri-lost-after-sb &#8220;/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b &gt; /proc/sysrq-trigger ; reboot -f&#8221;;</p>
<p>local-io-error &#8220;/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o &gt; /proc/sysrq-trigger ; halt -f&#8221;; # fence-peer &#8220;/usr/lib/drbd/crm-fence-peer.sh&#8221;;</p>
<p># split-brain &#8220;/usr/lib/drbd/notify-split-brain.sh root&#8221;;</p>
<p># out-of-sync &#8220;/usr/lib/drbd/notify-out-of-sync.sh root&#8221;;</p>
<p># before-resync-target &#8220;/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 &#8212; -c 16k&#8221;;</p>
<p># after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;</p>
<p>}</p>
<p>startup {</p>
<p># wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb;</p>
<p>}</p>
<p>disk {</p>
<p># on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes</p>
<p># no-disk-drain no-md-flushes max-bio-bvecs</p>
<p>on-io-error detach;</p>
<p>}</p>
<p>net {</p>
<p># sndÃ¢f-size rcvbuf-size timeout connect-int ping-int ping-timeout max-buffers</p>
<p># max-epoch-size ko-count allow-two-primaries cram-hmac-alg shared-secret</p>
<p>cram-hmac-alg &#8220;sha1&#8243;;</p>
<p>shared-secret &#8220;drbd-sql&#8221;;</p>
<p># after-sb-0pri after-sb-1pri after-sb-2pri data-integrity-alg no-tcp-cork</p>
<p>}</p>
<p>syncer {</p>
<p># rate after al-extents use-rle cpu-mask verify-alg csums-alg</p>
<p>rate 800M;</p>
<p>al-extents 257;</p>
<p>}</p>
<p>}</p>
<p>resource cluster0{</p>
<p>protocol C;</p>
<p>net {</p>
<p>cram-hmac-alg &#8220;sha1&#8243;;</p>
<p>shared-secret &#8220;drbd-sql&#8221;;</p>
<p>}</p>
<p>on sql-primaire {</p>
<p>device /dev/drbd0;</p>
<p>disk /dev/sda4;</p>
<p>address 192.168.168.1:8888;</p>
<p>meta-disk internal;</p>
<p>}</p>
<p>on sql-secondaire {</p>
<p>device /dev/drbd0;</p>
<p>disk /dev/sda4;</p>
<p>address 192.168.168.2:8888;</p>
<p>meta-disk internal;</p>
<p>}</p>
<p>}</p>
<h3>4.3       Fichiers de configuration de HeartBeat</h3>
<p><strong>/etc/ha.d/ha.cf</strong></p>
<p><strong> </strong></p>
<p><strong>debugfile /var/log/ha-debug.log</strong></p>
<p><strong>logfile /var/log/ha.log</strong></p>
<p><strong>logfacility     local0</strong></p>
<p><strong> </strong></p>
<p><strong>keepalive 2</strong></p>
<p><strong>deadtime 15</strong></p>
<p><strong>warntime 8</strong></p>
<p><strong>initdead 30</strong></p>
<p><strong> </strong></p>
<p><strong># interfaces reseaux en multicast pour envoyer les battements de coeur</strong></p>
<p><strong>mcast bond0 225.0.0.1 694 1 0</strong></p>
<p><strong>mcast eth2  225.0.0.1 694 1 0</strong></p>
<p><strong> </strong></p>
<p><strong># pas de retour-arriere automatique en cas de panne, trop dangereux</strong></p>
<p><strong>auto_failback off</strong></p>
<p><strong> </strong></p>
<p><strong># quels sont les noeuds concernes par le cluster heartbeat</strong></p>
<p><strong>node sql-primaire</strong></p>
<p><strong>node sql-secondaire</strong></p>
<p><strong> </strong></p>
<p><strong># on verifie que le host peut joindre l&#8217;interface publique</strong></p>
<p><strong>ping 192.168.13.253</strong></p>
<p><strong>deadping 5</strong></p>
<p><strong> </strong></p>
<p><strong>respawn hacluster /usr/lib64/heartbeat/ipfail</strong></p>
<p><strong>apiauth ipfail gid=haclient uid=hacluster</strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong>/etc/ha.d/haresources.cf</strong></p>
<p><strong> </strong></p>
<p><strong>otsql-primaire drbddisk::cluster0 Filesystem::/dev/drbd0::/data::ext3 192.168.13.100 mysql</strong></p>
<p><strong> </strong></p>
<p><strong>/etc/ha.d/resource.d/mysql </strong><em>(non présent après l’installation)</em><strong> </strong></p>
<p><strong><br />
</strong></p>
<p><strong> </strong></p>
<p><strong>#!/bin/bash</strong></p>
<p><strong>#</strong></p>
<p><strong># This script is inteded to be used as resource script by heartbeat</strong></p>
<p><strong>#</strong></p>
<p><strong># Mar 2006 by Monty Taylor</strong></p>
<p><strong>#</strong></p>
<p><strong>###</strong></p>
<p><strong>. /etc/ha.d/shellfuncs</strong></p>
<p><strong>case &#8220;$1&#8243; in</strong></p>
<p><strong> start)</strong></p>
<p><strong> res=`/etc/init.d/mysql start`</strong></p>
<p><strong> ret=$?</strong></p>
<p><strong> ha_log $res</strong></p>
<p><strong> exit $ret</strong></p>
<p><strong> ;;</strong></p>
<p><strong> stop)</strong></p>
<p><strong> res=`/etc/init.d/mysql stop`</strong></p>
<p><strong> ret=$?</strong></p>
<p><strong> ha_log $res</strong></p>
<p><strong> exit $ret</strong></p>
<p><strong> ;;</strong></p>
<p><strong> status)</strong></p>
<p><strong> if [[ `ps -ef | grep '[m]ysqld&#8217;` &gt; 1 ]] ; then</strong></p>
<p><strong> echo &#8220;running&#8221;</strong></p>
<p><strong> else</strong></p>
<p><strong> echo &#8220;stopped&#8221;</strong></p>
<p><strong> fi</strong></p>
<p><strong> ;;</strong></p>
<p><strong> *)</strong></p>
<p><strong> echo &#8220;Usage: mysql {start|stop|status}&#8221;</strong></p>
<p><strong> exit 1</strong></p>
<p><strong> ;;</strong></p>
<p><strong>esac</strong></p>
<p><strong>exit 0</strong></p>
<p><span style="text-decoration: underline;"><strong>CopyLeft: </strong></span></p>
<p><span style="text-decoration: underline;"><strong> </strong></span>Ce document est issu d&#8217;un document d&#8217;entreprise interne dans la mise en place d&#8217;un cluster MySQL HA et ce, dans de rééelles conditions de production.</p>
<p><strong> </strong></p>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/23/cluster-mysql-ha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RMAN : Sauvegardes à chaud</title>
		<link>http://cx.cx/2011/02/23/rman-sauvegardes-a-chaud/</link>
		<comments>http://cx.cx/2011/02/23/rman-sauvegardes-a-chaud/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 03:20:11 +0000</pubDate>
		<dc:creator>golgoth20</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Sauvegardes et Restaurations]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[rman]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=74</guid>
		<description><![CDATA[RMAN permet d&#8217;éffectuer la sauvegarde, à froid comme à chaud, de vos bases oracle, en mode total, incrémentiel et/ou cumulatif (nous verrons plus loin ces notions). Comme indiqué dans le chapitre REFERENTIEL RMAN, RMAN peut utiliser les fichiers de contrôle d&#8217;une base de données pour y stoquées les informations utiles pour ses sauvegardes (et donc ses [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>RMAN permet d&#8217;éffectuer la sauvegarde, à froid comme à chaud, de vos bases oracle, en mode total, incrémentiel et/ou cumulatif (nous verrons plus loin ces notions).</p>
<p>Comme indiqué dans le chapitre <a href="http://cx.cx/2011/02/22/rman-presentation-et-referentiel/">REFERENTIEL RMAN</a>, RMAN peut utiliser les fichiers de contrôle d&#8217;une base de données pour y stoquées les informations utiles pour ses sauvegardes (et donc ses restaurations), mais cela pose de nombreux problèmes en cas de perte de ceux ci. L&#8217;altéernative est de stoquer le catalogue dans une database prévue à cet effet (ce que nous vous conseillons).<img title="Lire la suite…" src="http://www.startupmount.com/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /></p>
<p><span style="text-decoration: underline;"><strong>1 &#8211; Nomenclature:</strong></span></p>
<p>RMAN peut éffectuer de simples copies des fichiers de données, on parle alors de &#8220;IMAGE COPY&#8221;, ou de gérer l&#8217;ensemble des copies qu&#8217;il éffectue pour vous dans un format propriétaire nommé &#8220;BACKUP SET&#8221;.</p>
<p>Une ImageCopy est exactement la même chose que si vous aviez copié des fichiers par l&#8217;OS : c&#8217;est de loin la meilleure option.</p>
<p>Le BackupSet en revanche permet de ne sauvegarder que les blocs oracles utilisés dans les datafiles, ce qui allège considérablement le poids des sauvegardes avec un <span style="text-decoration: underline;">rapport de 1/5</span>, ce qui est loin d&#8217;être négligeable. De plus, un BackupSet peut être découpé logiquement en plusieurs parties nommées &#8220;BACKUP PIECES&#8221; ceci pour répondre à des problématiques de limite de stockage (un DBF de 10Go sur une bande de 4Go par exemple).</p>
<p><span style="text-decoration: underline;">Rappel:</span> Que cela soit avec RMAN ou un autre outil de sauvegarde, il n&#8217;y a pas de miracle, une <span style="text-decoration: underline;">sauvegarde à chaud</span>d&#8217;une database ne peut s&#8217;éffectuer <span style="text-decoration: underline;">QUE</span> si celle si l&#8217;archivage des fichiers journaux (<span style="text-decoration: underline;">archivelogs</span>) est activé, sinon cela n&#8217;est pas possible. Une sauvegarde &#8220;à chaud&#8221;, avec ou sans RMAN, est de toute façon incohérente, il conviendra d&#8217;appliquer les journaux archivés aux fichiers de données restaurés pour obtenir une sauvegarde &#8220;cohérente&#8221;.</p>
<p><span style="text-decoration: underline;"><strong>2 &#8211; Sauvegarde non incrémentale :</strong><br />
</span></p>
<p>Comme vous pouvez vous en douter, BACKUP est l&#8217;instruction de RMAN qui va vous permettre d&#8217;effectuer une sauvegarde de votre base de données complète ou partielle, full ou incrémentale. Elle vous permet de sauvegarder un fichier de données, un tablespace, la database entière, le spfile et les fichiers de contrôles, les journaux et journaux archivés.</p>
<p>La syntaxe est assez simple :  RMAN&gt; BACKUP &lt;ordre&gt; &lt;options&gt;</p>
<p>Les [] symbolisent ici des éléments non obligatoires, les caractères gras les commutateurs les plus habituels en production.</p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;"><strong>2.1 &#8211; Ordres de la commande BACKUP :</strong></span></p>
<p>[ incremental level &lt;n&gt; [ cumulative] ]</p>
<p>permet les sauvegardes incrémentales de niveau 0 ou 1, avec l&#8217;option de cumuler les sauvegardes pour l&#8217;amélioration des performances à la restauration</p>
<p>[ validate ]</p>
<p>Doit &#8211; on vérifier la sauvegarde après sa génération ?</p>
<p>[ as [ copy | [compressed] backupset ]</p>
<p>Quel est le type de sauvegarde ? (&#8220;backup set&#8221; recommandé)</p>
<p>[ database | tablespace &lt;ts_name&gt; | datafile &lt;df_name&gt; | current controlfile | spfile ]</p>
<p>que sauvegarder ?</p>
<p>[ archivelog &lt;cible&gt; ]</p>
<p>faut il sauvegarder les archivelogs et où ?</p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;"><strong>2.2 &#8211; Options de la commande BACKUP :</strong></span></p>
<p>[ include current controlfile ]</p>
<p>généralement à faire, sauve si sauvegarde automatique du CTL file déjà prévue (voir plus loin)</p>
<p>[ plus archivelog ]</p>
<p>à effectuer en mode archivelogs dans le cas des sauvegardes à chaud car c&#8217;est indispensable pour obtenir une database cohérente après restauration.</p>
<p>[ delete [ all ] input ]</p>
<p>généralement à effectuer : détruit les archivelogs qui ne sont plus nécessaires</p>
<p>[ format = '&lt;format&gt;' ]</p>
<p>format de la sauvegarde (voir plus loin)</p>
<p>[ tag = '&lt;libelle_de_marqueur&gt;' ]</p>
<p>Très utile : ajouter un tag (marqueur informatif) à une sauvegarde. Il sera possible d&#8217;interroger RMAN sur ces tags.</p>
<p>[ not backed up &lt;clause&gt;]</p>
<p>[ ALL | FROM TIME &lt;time&gt; | UNTIL TIME &lt;time&gt; | TIME BETWEEN &lt;t1&gt; AND &lt;t2&gt; ]</p>
<p><span style="text-decoration: underline;"><strong>Exemples d&#8217;utilisation:</strong></span></p>
<p><em>Fait un backup de la database et valide que les fichiers sont restaurables:</em></p>
<pre>RMAN&gt; backup validate database tag='full_20080701_2015' plus archivelog delete input;</pre>
<p><em>Fait un backup de la database et des archivelogs si elles n&#8217;ont pas été sauvegardées au moins 3 fois:</em></p>
<pre>RMAN&gt; backup database plus archivelog not backed up since 3 times;</pre>
<p><em>Fait un backup des TableSpaces &#8216;datats&#8217; et &#8216;indexts&#8217; et backup également les controlfiles et spfiles.</em></p>
<pre>RMAN&gt; backup tablespace datats, indexts include current controlfile;</pre>
<p><em>Fait un backup du datafile #7:</em></p>
<pre>RMAN&gt; backup datafile 7, '/data/madatabase/datafiles/mondbf01.dbf';</pre>
<p><span style="text-decoration: underline;"><em>Remarque 1 : </em></span></p>
<p>Une sauvegarde RMAN est une sauvegarde (intelligente) des fichiers composants la base de données (entre autre les datafiles). <span style="text-decoration: underline;">Ces fichiers</span>, quel que soit le mode de sauvegarde (database, datafile, &#8230;) <span style="text-decoration: underline;">sont copiés les uns après les autres</span>, il est don cfort à parier que, si la base de données &#8220;vie&#8221; un minimum, que les fichiers soient positionnés à des <span style="text-decoration: underline;">SCN différents</span> lors de leur sauvegarde.</p>
<p>Les <span style="text-decoration: underline;">journaux</span> et les <span style="text-decoration: underline;">journaux archivés</span> sont alors <span style="text-decoration: underline;">indispensables</span> lors de la restauration car <span style="text-decoration: underline;">il faudra pratiquer un recovery après restauration</span> des datafiles pour rendre l&#8217;ensemble de la base &#8220;cohérente&#8221; (cad toutes les en-têtes des fichiers sont de même SCN).</p>
<p>Les commutateurs &#8220;PLUS ARCHIVELOG&#8221; sont alors strictement nécessaires, nes les oubliez pas !</p>
<p><span style="text-decoration: underline;"><em>Remarque 2 </em>:</span> Il est possible de sauvegarder manuellement les archivelogs par la commande &#8220;BACKUP ARCHIVELOG ALL&#8217;&#8221;.</p>
<p><span style="text-decoration: underline;"><em>Remarque 3:</em></span> Nous verrons par la suite qu&#8217;il est souvent inutile de préciser certains commutateurs car ceux ci font partie d&#8217;une conguration globale de RMAN et sont donc inclus par défaut.</p>
<p><span style="text-decoration: underline;"><strong>3 &#8211; Sauvegarde incrémentale :</strong><br />
</span></p>
<p><span style="text-decoration: underline;">Note:</span> Cette option n&#8217;existe quà partir du niveai de licence &#8220;Enterprise&#8221;.</p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;"><strong>3.1 &#8211; Incrémentale basée sur les traçage de blocs indiqué par Oracle :</strong><br />
</span></p>
<p>La sauvegarde incrémentale au sens de RMAN peut appuyer sur la technologie de <span style="text-decoration: underline;">traçage des blocs modifiés</span>d&#8217;une instance Oracle par le moteur de base de données.  Cette option activée indique au moteur de base de données qu&#8217;il doit spécifier dans un fichier particulier l&#8217;ensemble des blocs modifiés depuis l&#8217;instant T. Cette liste sera consultée par RMAN dans le cadre d&#8217;une sauvegarde incrémentale et celui-ci n&#8217;ira alors sauvegardé que les blocs marqués par Oracle comme modifiés dans ce fichier de trace.</p>
<p><span style="text-decoration: underline;">Syntaxe:</span></p>
<pre>SQL&gt; database <span style="text-decoration: underline;">enable block change tracking</span> using file '&lt;chemin_fichier&gt;';</pre>
<p style="padding-left: 30px;"><span style="text-decoration: underline;"><strong>3.2 &#8211; Incrémentale basée sur les traçages de blocs non indiqués par Oracle :</strong><br />
</span></p>
<p>Le traçage de blocs Oracle par le moteur de base de données comme indiqué dans 3.1) n&#8217;est pas obligatoire pour éffectuer une sauvegarde incrémentale avec RMAN mais, dans ce cas là, celui-ci ne peut pas connaitre la liste exhaustive des blocs modifiés et est obligé de parcourir tous les blocs d&#8217;un tablespace afin de déterminer quels sont les blocs modifiés depuis sa dernière sauvegarde.</p>
<p>Le résultat sera exactement le même qu&#8217;avace le traçage de blocs Oracle par le moteur de base de données mais les performances s&#8217;écroulent : <span style="text-decoration: underline;">n&#8217;hésitez pas à utiliser le traçage de blocs Oracle par le moteur de base de données </span>!</p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;"><strong>3.3 &#8211; Niveau de sauvegarde :</strong></span></p>
<p>Une sauvegarde incrémentale au sens de RMAN possède un <span style="text-decoration: underline;">NIVEAU</span>. Le niveau d&#8217;une sauvegarde incrémentale indique à RMAN quelle est la sauvegarde de base que celui-ci doit considérer pour évaluer le &#8220;delta&#8221; avec une situation actuelle à sauvegarder.</p>
<p>- NIVEAU 0 : Même si la sauvegarde est dite incrémentale, le niveau 0 indique en fait à RMAN que tout doit être sauvegardé, même si RMAN ne considère pas une telle sauvegarde comme FULL, elle contient pourtant tous les blocs de la base de données et est restaurable.</p>
<p>- NIVEAU 1 : Si une incrémentale est de niveau 1, alors RMAN ne sauvegardera QUE la différence avec la dernière sauvegarde équivalente de niveau 1 ou de niveau 0 : C&#8217;est une sauvegarde <span style="text-decoration: underline;">différentielle</span>.</p>
<p>Le principe étant de faire régulièrement des sauvegardes de niveau 0 et, périodiquement, des sauvegardes de niveau 1 alors beaucoup plus rapides à éffectuer.</p>
<p style="padding-left: 30px;"><span style="text-decoration: underline;"><strong>3.4 &#8211; Sauvegarde cumulative</strong></span></p>
<p>Une sauvegarde cumulative est une sauvegarde de niveau 1 qui contient tous les blocs modifiés depuis la dernière sauvegarde de niveau 0, même si des sauvegardes intermédiaires de niveau 1 ont été éffectées.</p>
<p>Ce type de sauvegarde consiste à demander à RMAN de repérer tous les blocs modifiés depuis la dernière sauvegarde de niveau 0, puis de les sauvegarer, une opération qui peut s&#8217;avérer lourde si la date de la dernière sauvegarde de niveau 0 est ancienne et que l&#8217;activité de la database est importante. Pour réduire ce phénomène, on pourra faire appel au pointage des blocs modifiés par le moteur de base de donnés Oracle et non par RMAN comme indiqué dans 3.1).</p>
<p>L&#8217;avantage est évidement : les opérations de restaurations sont beaucoup plus rapides puisque aucunne sauvegarde de niveau 1 non cumulative n&#8217;est à appliquer.</p>
<p>La syntaxe générale d&#8217;une sauvegarde incrémentale est :</p>
<p>RMAN&gt; BACKUP INCREMENTAL LEVEL [0 | 1 ] [ CUMULATIVE ] &lt;ordre&gt; &lt;option&gt;</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/23/rman-sauvegardes-a-chaud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fail2Ban : Install / config</title>
		<link>http://cx.cx/2011/02/22/fail2ban-installation-et-configuration/</link>
		<comments>http://cx.cx/2011/02/22/fail2ban-installation-et-configuration/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 18:43:30 +0000</pubDate>
		<dc:creator>dbaz</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[spammers]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=121</guid>
		<description><![CDATA[1.  Présentation 1.1       Introduction Fail2Ban est un utilitaire permettant de surveiller divers logs fichier, de repérer à l’intérieur des messages critiques synonymes de tentatives de hack et à minima d’automatiser le bannissement des adresses IP concernées. Fail2Ban permet de se prémunir des attaques par bruteForce sur les principaux logiciels serveurs (sshd, pop3d, imapd, httpd, ftpd, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>1.  Présentation</strong></p>
<p><strong>1.1       Introduction</strong></p>
<p>Fail2Ban est un utilitaire permettant de surveiller divers logs fichier, de repérer à l’intérieur des messages critiques synonymes de tentatives de hack et à minima d’automatiser le bannissement des adresses IP concernées.</p>
<p>Fail2Ban permet de se prémunir des attaques par bruteForce sur les principaux logiciels serveurs (sshd, pop3d, imapd, httpd, ftpd, …), d’automatiser un ban sur une durée D1 et d’automatiser le déban au bout d’un temps D2.</p>
<p>Le fichier fail2ban.zip (joint l’article RTFM de ce même document) contient la version 0.8.4 de jail2Ban.</p>
<p>Les updates de fail2Ban peuvent se trouver ici : <a href="http://sourceforge.net/projects/fail2ban/files/">http://sourceforge.net/projects/fail2ban/files/</a></p>
<p><strong>1.2       Prérequis</strong></p>
<p>fail2ban est un script écrit en Python, il ne nécessite aucun outil de compilation.</p>
<p>La version de Python exigée (à minima) est 2.3</p>
<p>Les librairies de développement de Pyhton sont nécessaires au déploiement de fail2ban (incluses dans toutes les distributions)</p>
<p><strong>2.  Installation</strong></p>
<p>-          Décompresser l’archivefail2ban dans un dossier temporaire D</p>
<p>-          Entrer dans le dossier D et taper la commande <strong>« python   setup.py   install</strong> »</p>
<p>-          Créer le fichier <strong>/etc/init.d/fail2ban</strong> tel que :</p>
<p>#! /bin/sh</p>
<p># Copyright (c) XXX.</p>
<p># All rights reserved.</p>
<p>#</p>
<p># Author:XXX</p>
<p># Please send feedback to http://sss/</p>
<p>#</p>
<p># /etc/init.d/fail2ban</p>
<p>#</p>
<p>### BEGIN INIT INFO</p>
<p># Provides:          fail2ban</p>
<p># Required-Start:    $syslog $network $dovecot</p>
<p># Required-Stop:</p>
<p># Default-Start:     3 5</p>
<p># Default-Stop:      0 1 2 6</p>
<p># Description:       Fail2Ban Server</p>
<p>### END INIT INFO</p>
<p>. /etc/rc.status</p>
<p># Reset status of this service</p>
<p>rc_reset</p>
<p>case &#8220;$1&#8243; in</p>
<p>start)</p>
<p>echo -n &#8220;Starting FAIL2BAN &#8221;</p>
<p>/usr/local/bin/fail2ban-client -v -c /etc/fail2ban start</p>
<p>echo &#8220;Etat des tables &#8221;</p>
<p>/usr/sbin/iptables &#8211;list</p>
<p>;;</p>
<p>stop)</p>
<p>echo -n &#8220;Stopping FAIL2BAN &#8221;</p>
<p>/usr/local/bin/fail2ban-client -v -c /etc/fail2ban stop</p>
<p>echo &#8220;Etat des iptables &#8221;</p>
<p>/usr/sbin/iptables &#8211;list</p>
<p>;;</p>
<p>restart)</p>
<p>$0 stop</p>
<p>$0 start</p>
<p>rc_status</p>
<p>;;</p>
<p>status)</p>
<p>echo -n &#8220;Statut FAIL2BAN &#8221;</p>
<p>/usr/local/bin/fail2ban-client -v -c /etc/fail2ban status</p>
<p>echo &#8220;Etat des tables &#8221;</p>
<p>/usr/sbin/iptables &#8211;list</p>
<p>;;</p>
<p>*)</p>
<p>echo &#8220;Usage: $0 {start|stop|restart|status}&#8221;</p>
<p>exit 1</p>
<p>;;</p>
<p>esac</p>
<p>rc_exit</p>
<p>-          Taper les commandes :</p>
<ul>
<li><strong>chmod +x /etc/init.d/fail2ban</strong></li>
<li><strong>chkconfig    &#8212; add   fail2ban   35 </strong></li>
<li><strong>ln   –s   /etc.init.f/fail2ban   /usr/sbin/fail2ban</strong></li>
</ul>
<p><strong>3.  Configuration</strong></p>
<p><strong>3.1       Configuration de base</strong></p>
<p><strong>3.1.1      Fichier « /etc/fail2ban/fail2ban.conf »</strong></p>
<p>Voici les notions importantes à modifier, le reste peut rester en commentaires ou en valeurs par défaut :</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="255" valign="top">loglevel = 4</td>
<td width="402" valign="top">Permet   d’agrémenter un niveau de log suffisament verbeu pour les premiers tests, en   production, il faudra le remettre à 1.</td>
</tr>
<tr>
<td width="255" valign="top">logtarget = /var/log/fail2ban.log</td>
<td width="402" valign="top">Emplacement   du fichier de log de fail2ban</td>
</tr>
<tr>
<td width="255" valign="top">socket = /var/run/fail2ban/fail2ban.sock</td>
<td width="402" valign="top">Emplacement   du fichier de socket unix de fail2ban (il faudra créér ce répertoire + chown   –R root:root )</td>
</tr>
</tbody>
</table>
<p><strong>3.1.2      Fichier « /etc/fail2ban/jail.conf »</strong></p>
<p><strong>3.1.2.1         Configuration générale</strong></p>
<p>Ce fichier contient une configuration par défaut de fail2ban (section « [DEFAULT] ») telle que :</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="262" valign="top">bantime  = 3600</td>
<td width="397" valign="top">Si on doit bannir une IP, combien de temps reste-t-elle   bannie ? (ici 1 heure)</td>
</tr>
<tr>
<td width="262" valign="top">findtime  = 600</td>
<td width="397" valign="top">Quel est l’intervalle de temps pendant lequel fail2ban   compte les tentatives de hack avant d’atteindre le maximum toléré (maxretry)   dans ce même intervalle ?</td>
</tr>
<tr>
<td width="262" valign="top">maxretry = 3</td>
<td width="397" valign="top">Maximum de tentatives infructueuses tolérée</td>
</tr>
<tr>
<td width="262" valign="top">backend = auto</td>
<td width="397" valign="top"></td>
</tr>
</tbody>
</table>
<p>Les autres sections de ce fichier de configuration sont des  « JAILS » (prisons).</p>
<p>Les JAILS indiquent la façon dont on va observer un fichier de log particulier, pour observer quel type de hack éventuel décris par des expressions régulières et quelles actions éventuelles seront alors à éffectuer (banissement temporaire d’IP ou autre), les JAILS sont décrits dans 3.1.2</p>
<p><strong>3.1.2.2         Configuration des « JAILS »</strong></p>
<p>Une JAIL est la description du besoin d’observer le contenu d’un fichier de log et de définir des actions en cas de tentative de hack. Les JAILS sont décrites dans le fichier /etc/fail2ban/jail.conf décrit en 3.1.2.</p>
<p>-          <span style="text-decoration: underline;">JAIL standard pour SSH :</span></p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="286" valign="top"><strong>[ssh-iptables]</strong></td>
<td width="355" valign="top">Nom de la JAIL</td>
</tr>
<tr>
<td width="286" valign="top"><strong>enabled    = true</strong></td>
<td width="355" valign="top">Est-elle pris en compte au démarrage de   fail2ban ?</td>
</tr>
<tr>
<td width="286" valign="top"><strong>filter     = sshd</strong></td>
<td width="355" valign="top">Nom du filtre à utiliser pour parser le   fichier de log concerné par cette JAIL (voir 3.1.2.3)</td>
</tr>
<tr>
<td width="286" valign="top"><strong>action=</strong></p>
<p><strong>iptables[name=SSH,   port=ssh, protocol=tcp]</strong></td>
<td width="355" valign="top">Quelle action doit-on entreprendre en cas de   tentative de hack avérée ? (voir 3.1.2.4)</td>
</tr>
<tr>
<td width="286" valign="top"><strong>logpath       = /var/log/auth_sshd.log</strong></td>
<td width="355" valign="top">Fichier de log dans lequel   l’authentification sur le serveur sshd doit être tracée pour traquer les   failures.</td>
</tr>
<tr>
<td width="286" valign="top"><strong>maxretry = 3</strong></td>
<td width="355" valign="top">Nombre de tentative maximum tolérée sur un   intervalle glissant de &lt;findtime&gt; secondes</td>
</tr>
<tr>
<td width="286" valign="top"><em>bantime    = 3600</em></td>
<td width="355" valign="top"><em>Optionnel </em>:   Combien de temps en secondes un user banni le restera avant dé-banissement ?</td>
</tr>
<tr>
<td width="286" valign="top"><em>findtime    = 600</em></td>
<td width="355" valign="top"><em>Optionnel</em> :   Intervalle glissant en secondes pendant lequel on compte les echecs   d’authentification (jusqu’à maxretry)</td>
</tr>
</tbody>
</table>
<p>-          <span style="text-decoration: underline;">Construction d’une JAIL personalisée (exemple : DOVECOT pour mySQL) :</span></p>
<p><span style="text-decoration: underline;"> </span></p>
<p>Dovecot est souvent utilisé comme serveur POP3/IMAP4, il est la pluspart du temps couplé avec mySQL dans lequel il trouvera la base utilisateurs (logins et passwords). Cependant, il n’existe pas de JAIL standard préconfigurée. Il faut donc faire tracer l’authentification de Dovecot dans un fichier précis, choisissons « /var/log/dovecot.log »,.</p>
<p>-          Paramétrage de DoveCot</p>
<ul>
<li>Editer « /etc/dovecot/dovecont.conf » et fixer « log_path » à «  /var/log/dovecot.log », puis relancer Dovecot</li>
</ul>
<p>-          Paramétrage de fail2ban (ajout d’une JAIL)</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="262" valign="top"><strong>[dovecot]</strong></td>
<td width="355" valign="top">Nom de la jail</td>
</tr>
<tr>
<td width="262" valign="top"><strong>enabled   = true</strong></td>
<td width="355" valign="top">Celle-ci doit être active</td>
</tr>
<tr>
<td width="262" valign="top"><strong>filter =   dovecot</strong></td>
<td width="355" valign="top">L’expression régulière permettant   d’identifier un hack dans le fichier de log de Dovecot sera repérée grâce au   filtre nommé « dovecot » (voir 3.1.2.3)</td>
</tr>
<tr>
<td width="262" valign="top"><strong>action=iptables[name=dovecot,   port=pop3, protocol=tcp]</strong></td>
<td width="355" valign="top">Quelle action doit-on entreprendre en cas de   tentative de hack avérée ? (voir 3.1.2.4)</td>
</tr>
<tr>
<td width="262" valign="top"><strong>logpath   = /var/log/dovecot.log</strong></td>
<td width="355" valign="top">Fichier de log d’authentification de dovecot</td>
</tr>
<tr>
<td width="262" valign="top"><strong>maxretry   = 5</strong></td>
<td width="355" valign="top">On tolère un peu plus d’echecs que pour SSH,   ici 5</td>
</tr>
</tbody>
</table>
<p>-          Paramétrage d’un Filtre « dovecot » (voir en 3.1.2.3)</p>
<p>-          L’action choisie dans cet exemple est la même que pour un la JAIL « ssh-iptables », celle-ci est donc déjà écrite il n’y a rien à faire, sinon il aurait fallu créer une action comme en 3.1.2.4.</p>
<p><strong>3.1.2.3         Configuration d’un filtre</strong></p>
<p>Les « filtres » de fail2ban sont dans le dossier « /etc/fail2ban/filter.d/ ».</p>
<p>Il existe un fichier unique par nom de filtre déclaré danes les JAILS, par exemple « /etc/fail2ban/filter.d/sshd.conf » pour la JAIL « ssh-iptables » décrite en 3.1.2.2.</p>
<p>Un filtre est principalement caractérisé par une expression régulière plus ou moins complexe décrite par le paramètre « failregex » du fichier de filtre. Si l’expression régulière « match » sur une nouvelle ligne dans le fichier de log d’une JAIL, alors fail2ban considèrera qu’une tentative de hack a été réalisée.</p>
<p>-          <span style="text-decoration: underline;">Exemple : Expression régulière du filtre sshd :</span></p>
<p>-          <span style="text-decoration: underline;"> </span></p>
<p>failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from &lt;HOST&gt;\s*$</p>
<p>^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from &lt;HOST&gt;\s*$</p>
<p>^%(__prefix_line)sFailed (?:password|publickey) for .* from &lt;HOST&gt;(?: port \d*)?(?: ssh\d*)?$</p>
<p>^%(__prefix_line)sROOT LOGIN REFUSED.* FROM &lt;HOST&gt;\s*$</p>
<p>^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from &lt;HOST&gt;\s*$</p>
<p>^%(__prefix_line)sUser \S+ from &lt;HOST&gt; not allowed because not listed in AllowUsers$</p>
<p>^%(__prefix_line)sauthentication failure; logname=\S* uid=\S* euid=\S* tty=\S* ruser=\S* rhost=&lt;HOST&gt;(?:\s+user=.*)?\s*$</p>
<p>^%(__prefix_line)srefused connect from \S+ \(&lt;HOST&gt;\)\s*$</p>
<p>^%(__prefix_line)sAddress &lt;HOST&gt; .* POSSIBLE BREAK-IN ATTEMPT!*\s*$</p>
<p>^%(__prefix_line)sUser \S+ from &lt;HOST&gt; not allowed because none of user&#8217;s groups are listed in AllowGroups$</p>
<p>-          <span style="text-decoration: underline;">Exemple : Création d’un filtre « dovecont » pour la JAIL « dovecot »</span></p>
<p>La technique consiste à repérer dans le fichier de log (ici « /var/log/dovecot.log ») une ligne représentant un échec d’authentification puis, à l’aide des expressions régulières, la renseigner dans le paramètre failregex un fichier « /etc/fail2ban/filter.d/dovecot.conf » à créer.</p>
<p>Le fichier /var/log/dovecot.log contient des erreurs du style :</p>
<p>« dovecot: Oct 05 15:24:46 Info: auth-worker(default): sql(unUserBidon,192.168.10.19): unknown user »</p>
<p>L’expression régulière symbolisant cette chaine peut être par exemple :</p>
<p>« sql.*,&lt;HOST&gt;\).*unknown user »</p>
<p>Le paramètre &lt;HOST&gt; représente ici l’adresse IP que fail2ban peut récupérer dynamiquement dans cette expression régulière et qui sera passée en paramètre à son « action » correspondante et permettra un ban par iptables ou autre.</p>
<p>Le filtre de dovecot est donc le fichier « « /etc/fail2ban/filter.d/dovecot.conf » tel que :</p>
<p># Fail2Ban configuration file</p>
<p>#</p>
<p># Author: XXX</p>
<p># Modified by: XXX</p>
<p>#</p>
<p># $Revision: 1 $</p>
<p>#</p>
<p>[Definition]</p>
<p># Option:  failregex</p>
<p># Notes.:  regex to match the password failures messages in the logfile. The</p>
<p>#          host must be matched by a group named &#8220;host&#8221;. The tag &#8220;&lt;HOST&gt;&#8221; can</p>
<p>#          be used for standard IP/hostname matching and is only an alias for</p>
<p>#          (?:::f{4,6}:)?(?P&lt;host&gt;[\w\-.^_]+)</p>
<p># Values:  TEXT</p>
<p>#</p>
<p>#failregex = LOGIN FAILED, .*, ip=\[&lt;HOST&gt;\]$</p>
<p># exemple:</p>
<p># dovecot: Oct 04 17:59:00 Info: auth(default): pam(contact@hotel-lesvoyageurs.com,86.193.160.20): pam_authenticate() failed: Authentication failure</p>
<p>#failregex  = pam.*,&lt;HOST&gt;\).*failure</p>
<p># exemple:</p>
<p># dovecot: Oct 05 15:21:13 Info: auth-worker(default): sql(xaxaxa,192.168.10.19): unknown user</p>
<p>failregex  = sql.*,&lt;HOST&gt;\).*unknown user</p>
<p>ignoreregex =</p>
<p># Option:  ignoreregex</p>
<p># Notes.:  regex to ignore. If this regex matches, the line is ignored.</p>
<p># Values:  TEXT</p>
<p>#</p>
<p>ignoreregex =</p>
<p>Il suffit de relancer fail2ban pour prendre en compte ces modifications.</p>
<p><span style="text-decoration: underline;">Remarque)</span> Pour vérifier la liste des IP(s) temporairement bannies par fail2ban, il faut utiliser la commande « iptables   &#8211;list ».</p>
<p><strong>3.1.2.4         Configuration d’une action</strong></p>
<p>Ce document ne documente pas cette section car les actions existantes par défaut dans fail2ban sont à priori largement suffisantes.</p>
<p>Les actions se trouvent dans le dossier « /etc/fail2ban/actions.d ».</p>
<p>Les paramètres récupérés dynamiquement dans les expressions régulières des filtres sont récupérable dynamiquement dans les scripts « actions ».  S’inspirer des scripts existant pour en créer de nouveaux.</p>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/22/fail2ban-installation-et-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installation d&#8217;un cluster MySQL NDB</title>
		<link>http://cx.cx/2011/02/22/installation-dun-cluster-mysql-ndb/</link>
		<comments>http://cx.cx/2011/02/22/installation-dun-cluster-mysql-ndb/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 18:39:14 +0000</pubDate>
		<dc:creator>dbaz</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Générale]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[ndb]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=117</guid>
		<description><![CDATA[1.  Introduction 1.1       MySQL NDB , un cluster de données orienté « mémoire » MySQL Cluster est dit un cluster « in memory », cela signifie que la plupart des éléments sont, pour des raisons de performance, chargés en mémoire et que ceux-ci sont régulièrement écris sur disque selon divers critères. Il est donc très important [...]]]></description>
			<content:encoded><![CDATA[<p><strong>1.  Introduction</strong></p>
<p><strong><br />
1.1       MySQL NDB , un cluster de données orienté « mémoire »</strong></p>
<p>MySQL Cluster est dit un cluster « in memory », cela signifie que la plupart des éléments sont, pour des raisons de performance, chargés en mémoire et que ceux-ci sont régulièrement écris sur disque selon divers critères. Il est donc très important que les nœuds de stockage du cluster soient pourvus de beaucoup de mémoire.</p>
<p>Le cluster MySQL ne dispose pas de système de fichier partagé (via SAN, …) comme un cluster au sens « classique » du terme mais dispose d’éléments de dialogue réseau qui lui permet de synchroniser les données du cluster au sein de tous ses nœuds. Les données d’un cluster MySQL sont stockées sur des disques locaux des différents serveurs du cluster et les données partagées sont « répliquées » par des processus internes entre les différentes composantes du cluster.</p>
<p>L’élément fondamental du cluster MySQL est donc la capacité à traiter rapidement et efficacement des requêtes réseau sous le protocole TCP/IP (cartes Ethernets gigabits requises, sockets SCI recommandés).</p>
<p>La documentation indique des options permettent de faire en sorte que le Cluster mySQL écrive sur disque, mais celle-ci sont très consommatrices en ressources et peuvent dégrader de façon significative les performances.</p>
<p><strong>1.2       Les « nœuds » (ou « nodes ») : composantes de base de MySQL-Cluster</strong></p>
<p>Un élément serveur logiciel élémentaire de mySQL Cluster se nomme un « node » (ou « nœud »). Un node est un élément logique, aussi, il peut exister plusieurs nodes sur une machine physique composante d’un cluster mySQL.</p>
<p>La nature d’un Un node peut être de divers nature :</p>
<p>-          <strong>Node de STOCKAGE (NDB) :</strong></p>
<p>Le node de stockage (ou node NDB du nom du moteur de cluster « NDBENGINE ») est un nœud chargé de gérer, avec l’ensemble des autres nodes de même nature, la répartition des données sur l’ensemble des nodes de stockage du cluster, d’en assurer la réplication inter-nodes afin de garantir la disponibilité des datas et enfin de gérer les demandes d’accès aux données.</p>
<p>Au vue des forts besoins en mémoire du Cluster mySQL, il est recommandé d’installer des versions 64bits des nœuds NDB afin de passer la barrière fatidique des 3096Go de mémoire maximale sur une 32bits linux.</p>
<p>Dans notre exemple (Cluster « CLUSTER») nous utiliserons 2 nœuds NDB situés en</p>
<ul>
<li>10.20.0.29 (SITSQL01) [ machine physique ]</li>
<li>10.20.0.30 (SITSQL02) [ machine physique ]</li>
</ul>
<p>Les nodes NDB sont au minimum de 2 dans un cluster mySQL.</p>
<p>-          <strong>Node MANAGER  (MGM):</strong></p>
<p>Les nodes MGM (ou « Manager) sont les nœuds du cluster chargés en permanence d’informer les autres nœuds de la configuration du cluster (où sont les nœuds et quelles sont leur nature et leur état, …) et de son rythme de vie (quelles sont les demandes de synchronisations, …)</p>
<p>Dans notre exemple (Cluster « CLUSTER») nous utiliserons 2 nœuds MGM situés en</p>
<ul>
<li>10.20.0.27 [ machine Xen ]</li>
<li>10.20.0.28 [ machine Xen ]</li>
</ul>
<p>Les nodes MGM sont au minimum de 1 dans un cluster mySQL (2 recommandés).</p>
<p>-          <strong>Node SQL (SQL):</strong></p>
<p>L’accès aux données stoquées sur les nodes NDB ne se fait pas de façon standard, comme pour un serveur mySQL autonome, il faut utiliser un API spécifique dit « NDB API ».</p>
<p>Dans le but de rendre compatible des applications écrites pour des serveurs autonomnes, il faut alors ajouter au cluster des nodes dits « SQL » qui sont des interfaces entre les API clientes standards et les nodes NDB.</p>
<p>Dans notre exemple (Cluster « XXX ») nous utiliserons 2 nœuds MGM situés en</p>
<ul>
<li>10.20.0.25  [ machine Xen ]</li>
<li>10.20.0.26  [ machine Xen ]</li>
</ul>
<p>Les nodes SQL sont au minimum de 1 dans un cluster mySQL (2 recommandés).</p>
<p>Dans une production, un cluster mySQL est donc composé à minima de 6 nodes (2 SQL, 2 MGM, 2 NDB) répartis sur 6 machines différentes dans un souci de haute disponibilité des données et de leur accès.</p>
<p>Notons que le cluster au sens de mySQL ne garanti pas la répartition de charge au sein des nodes SQL, il faudra se munir d’outils annexes (HAProxy, LVS/KeepAlive, etc.) pour cela.</p>
<p><span style="text-decoration: underline;">Remarque :</span> Dans le cas du cluster XXXX, voici les adresses contactables :</p>
<ul>
<li>Load balance : sql0.site.fr (serveur à utiliser par les applicatifs)</li>
<li>Nœud 1 : sql1.site.fr</li>
</ul>
<ul>
<li>Nœud 2 : sql12.site.fr</li>
</ul>
<p><strong>2.  Installation</strong></p>
<p><strong>2.1 Introduction</strong></p>
<h3><span style="font-size: 13px; line-height: 18px;">Les méthodes d’installation sont basées sur l’exploitation des outils d’installation disponibles sur une <strong>openSuSE 11.3 (x86_64)</strong>.</span></h3>
<p><strong>2.2       Les packages nécessaires</strong></p>
<p><span style="text-decoration: underline;">Sur les nœuds MGM</span> :</p>
<p>-          libmysqlclient16</p>
<p>-          libmysqlclient_r16</p>
<p>-          libmysqlclusterclient16</p>
<p>-          libmysqlclusterclient_r16</p>
<p>-          libmysqld0</p>
<p>-          libqt4-sql-mysql</p>
<p>-          mysql-cluster-client</p>
<p>-          mysql-cluster-ndb-management</p>
<p>-          mysql-cluster-ndb-tools</p>
<p><span style="text-decoration: underline;">Sur les nœuds SQL :</span></p>
<p>-          libmysqlclient-devel</p>
<p>-          libmysqlclient16</p>
<p>-          libmysqlclient_r16</p>
<p>-          libmysqlclusterclient16</p>
<p>-          libmysqlclusterclient_r16</p>
<p>-          libmysqlcppconn-devel</p>
<p>-          libmysqlcppconn1</p>
<p>-          libmysqld-devel</p>
<p>-          libmysqld0</p>
<p>-          libqt4-sql-mysql</p>
<p>-          mysql-cluster</p>
<p>-          mysql-cluster-client</p>
<p><span style="text-decoration: underline;">Sur les nœuds NDB :</span></p>
<p>-          libmysqlclient16</p>
<p>-          libmysqlclient_r16</p>
<p>-          libmysqld0</p>
<p>-          libqt4-sql-mysql</p>
<p>-          mysql-cluster-ndb-storage</p>
<p>-          mysql-cluster-ndb-tools</p>
<p>-          mysql-community-server</p>
<p>-          mysql-community-server-client</p>
<p><strong>2.3       Fonctionnalités hors distribution</strong></p>
<p><strong>2.3.1      Introduction</strong></p>
<p>Pour une correcte gestion de l’annulation d’un post traitement dans une procédure stockée ou un trigger, nous avons besoin d’ajouter une fonctionnalité supplémentaire livrée la librairie « lib_mysqludf_udf.so » téléchargeable ici : <span style="text-decoration: underline;">http://www.mysqludf.org/lib_mysqludf_udf/lib_mysqludf_udf_0.0.3.tar.gz</span>.</p>
<p>-          Cette librairie est écrite en langage C, il convient d’installer gcc ainsi que les headers mySql (package libmysqlcppconn-devel) pour pouvoir la compiler.</p>
<p><strong>2.3.2      Installation et configuration</strong></p>
<p><strong><br />
</strong></p>
<p><strong>1- </strong><strong>Compilation</strong></p>
<p>En supposant que les headers mySQl se trouvent dans le répertoire « <strong>/usr/include/mysql », v</strong>oici la commande à lancer pour compiler la librairie :</p>
<p><strong>gcc -shared lib_mysqludf_udf.c -o lib_mysqludf_udf.so -I /usr/include/mysql</strong><strong> </strong></p>
<p><strong> </strong></p>
<p><strong>2- </strong><strong>Installation</strong><strong> </strong></p>
<p><strong> </strong></p>
<p><strong>Il faut copier la librairie « lib_mysqludf_udf.so » dans le répertoire de partage de mySQL, appelé aussi dossier des « plugins ». Pour connaitre son emplacement, il suffit de se connecter au serveur SQL et de localiser la variable « plugin_dir » en réponse à la commande « show variables ».</strong><strong> </strong></p>
<p><strong> </strong></p>
<p><strong>Il faudra ensuite créer une fonction SQL utilisant les fonctions de cette librairie en se connectant au serveur mySQL et en tapant : </strong><strong> </strong></p>
<p><strong> </strong></p>
<p>USE &lt;MABASE&gt;; ç ATTENTION: la fonction est stockée dans la base de données !</p>
<p>CREATE FUNCTION udf_initid_error RETURNS INTEGER SONAME &#8216;lib_mysqludf_udf.so&#8217;;</p>
<p><strong> </strong></p>
<p>La fonction « udf_initd_error(message   varchar(255)) » est alors disponible dans la database mySQL et permet de provoquer des exceptions afin principalement d’interrompre les traitements des triggers en cas d’erreurs logique.</p>
<p><span style="text-decoration: underline;">Remarque :</span> Attention, il faut reproduire l’installation / configuration sur tous les nœuds SQL.</p>
<p><strong> </strong></p>
<p><strong>3.  Configuration</strong></p>
<p><strong><br />
3.1       Configuration des nœuds SQL</strong></p>
<p>Créer l’arborescence suivante sur chaque nœud SQL :</p>
<p>/data</p>
<p>/data/mysql</p>
<p>/data/mysql/databases</p>
<p>/data/mysql/libs   <em>(&lt;= dossier de sauvegarde de l’UDF mysql définie en </em><em>2.3</em><em>)</em></p>
<p>/data/mysql/run</p>
<p>Indiquer dans le fichier hosts de la machine les mappages nom/adresse des serveurs de managment (2 dans cet exemple) :</p>
<p><span style="text-decoration: underline;">Exemple :</span></p>
<p>10.20.0.27   sql-mgm-01</p>
<p>10.20.0.28   sql-mgm-02</p>
<p>La configuration d’un nœud SQL consiste à renseigner de façon élémentaire /etc/my.cnf comme pour un serveur mySQL autonome, le nœud va charger grâce à cela sa configuration sur l’un des MGM nodes.</p>
<p><span style="text-decoration: underline;">/etc/my.cnf :</span></p>
<p>[client]</p>
<p>port            = 3306</p>
<p>socket          = /data/mysql/run/mysql.sock</p>
<p>[mysqld]</p>
<p>port            = 3306</p>
<p>socket          = /data/mysql/run/mysql.sock</p>
<p>datadir = /data/mysql/databases</p>
<p>skip-locking</p>
<p>key_buffer_size = 16M</p>
<p>max_allowed_packet = 1M</p>
<p>table_open_cache = 64</p>
<p>sort_buffer_size = 512K</p>
<p>net_buffer_length = 8K</p>
<p>read_buffer_size = 256K</p>
<p>read_rnd_buffer_size = 512K</p>
<p>myisam_sort_buffer_size = 8M</p>
<p>ndbcluster</p>
<p>ndb-connectstring=sql-mgm-01sql-mgm-02</p>
<p>default-storage-engine=ndbcluster</p>
<p>default-table-type=ndbcluster</p>
<p>La commande d’administration sera « rcmysql », voir 4.1.2.</p>
<p><strong>3.2       Configuration des nœuds NDB :</strong></p>
<p>Créer l’arborescence suivante sur chaque nœud NDB :</p>
<p>/data</p>
<p>/data/mysql</p>
<p>/data/mysql/backups  (dossier de stockage des backups des réplicas sur ce nœud, voir 5.2)</p>
<p>/data/mysql/datafiles   <em>(dossier de stockage des données des réplicas sur ce noeud)</em></p>
<p>/data/mysql/logs <em>(fichiers de logs pour debugging)</em></p>
<p><em>/data/mysql/undofiles  (fichiers d’annulation des transactions (rollbacks))</em></p>
<p>Le fichier /etc/my.cnf contient la définition d’accès aux serveurs de managment pour le nœud NDB :</p>
<p>[mysqld]</p>
<p>port            = 3306</p>
<p>socket          = /var/run/mysql/mysql.sock</p>
<p>datadir = /data/mysql</p>
<p>skip-locking</p>
<p>key_buffer_size = 16M</p>
<p>max_allowed_packet = 1M</p>
<p>table_open_cache = 64</p>
<p>sort_buffer_size = 512K</p>
<p>net_buffer_length = 8K</p>
<p>read_buffer_size = 256K</p>
<p>read_rnd_buffer_size = 512K</p>
<p>myisam_sort_buffer_size = 8M</p>
<p>[MYSQL_CLUSTER]</p>
<p>ndb-connectstring=sql-mgm-01,sql-mgm-02</p>
<p>La commande d’administration sera « rcndbd », voir 4.1.3.</p>
<p><strong>3.3       Configuration des nœuds MGM</strong></p>
<p>Les nœuds MGM propagent la configuration de tous les nœuds du cluster sur l’ensemble des nœuds (SQL et NDB et MGM). Les fichiers de config de ces nœuds sont donc fondamentaux, sont pris en compte lors du démarrage des nœuds MGM. Il est recommandé d’utiliser une configuration de partage globale (SAN, nfs, …) pour que chaque nœud utilise lors de son démarrage et sans ambigüité la configuration n fixée par l’administrateur.</p>
<p>Créer l’arborescence suivante sur chaque nœud MGM :</p>
<p>/data</p>
<p>/data/mysql</p>
<p>/data/mysql/config</p>
<p>/data/mysql/logs</p>
<p>Le démarrage d’un serveur MGM mySQL se fait par la prise en compte d’un fichier de configuration que l’on stoque dans /data/mysql/config/config.ini :</p>
<p>[TCP DEFAULT]</p>
<p>SendBufferMemory=2M</p>
<p>ReceiveBufferMemory=2M</p>
<p>[NDBD DEFAULT]</p>
<p>NoOfReplicas=2</p>
<p>DataMemory=3072M</p>
<p>IndexMemory=3842M</p>
<p>LockPagesInMainMemory=1</p>
<p>[NDB_MGMD]</p>
<p>ID=27</p>
<p>HostName=10.20.0.27</p>
<p>[NDB_MGMD]</p>
<p>ID=28</p>
<p>HostName=10.20.0.28</p>
<p>DataDir=/data/mysql/logs</p>
<p>[NDBD]</p>
<p>ID=29</p>
<p>HostName=10.20.0.29</p>
<p>DataDir=/data/mysql/logs</p>
<p>FileSystemPath=/data/mysql/datafiles</p>
<p>FileSystemPathUndoFiles=/data/mysql/undofiles</p>
<p>BackupDataDir=/data/mysql/backups</p>
<p>[NDBD]</p>
<p>ID=30</p>
<p>HostName=10.20.0.30</p>
<p>DataDir=/data/mysql/logs</p>
<p>FileSystemPath=/data/mysql/datafiles</p>
<p>FileSystemPathUndoFiles=/data/mysql/undofiles</p>
<p>BackupDataDir=/data/mysql/backups</p>
<p>[MYSQLD]</p>
<p>ID=25</p>
<p>HostName=10.20.0.25</p>
<p>[MYSQLD]</p>
<p>ID=26</p>
<p>HostName=10.20.0.26</p>
<p>[MYSQLD]</p>
<p>ID=50</p>
<p>Cette configuration est évidement à adapter en fonction des besoins. Ici nous utilisons deux nœuds SQL, deux nœuds MGM et deux nœuds NDB.</p>
<p>La commande d’administration sera « rcndb_mgmd », voir  4.1.3.</p>
<p><strong><span style="text-decoration: underline;">Remarque :</span></strong> Une même et seule version du fichier de configuration « <strong>config.ini</strong> » doit être présent sur tous les nœuds MGM lors d’un démarrage, pour cela, on peut utiliser la commande :</p>
<p><strong>rcndb_mgmd propage-config</strong></p>
<p>qui propage le fichier config.ini du node MGM sur lequel on est connecté vers tous les autres.</p>
<p><strong>4. Administration</strong></p>
<p><strong><br />
</strong></p>
<p><strong>4.1 Options de démarrage des nodes</strong></p>
<p><strong>4.1.1 Noeuds MGM</strong></p>
<p>Ces nœuds sont à démarrer en premier dans le cluster. Sans les nœuds de management démarrés, les autres nœuds (SQL et NDB) risquent de rencontrer des problèmes d’annonce au cluster.</p>
<p>Le lancement et l’arrêt d’un nœud SQL se fait de la même manière que pour un serveur mySQL autonome avec</p>
<p><strong>rcndb_mgmd    start : </strong>démarre le nœud<strong> </strong></p>
<p><strong>stop : </strong>stoppe le nœud, arrête tous les nœuds NDB et tous les nœuds MGM</p>
<p><strong>status :</strong> indique l’ensemble des nœuds configurés et annoncés au cluster</p>
<p>init :<strong> </strong>démarre le nœud à l’indentique de « start » mais écrase la configuration binaire pour prendre en compte le fichier /data/mysql/config/config.ini</p>
<p><span style="text-decoration: underline;">Différences sur « init » et « start » :</span></p>
<p>Lors d’un démarrage du nœud en « <strong>init</strong> », le fichier de configuration textuel est parsé et est fabriqué un fichier de configuration binaire à ses cotés. Le fichier de configuration binaire permet de prendre des modifications de la configuration du cluster de façon dynamique alors qu’il faut relancer les nœuds dans le cadre d’e la prise en compte de config.ini.</p>
<p>Le démarrage en mode « <strong>start</strong> » ne prend en compte que le fichier de configuration binaire.</p>
<p><strong>4.1.2      Nœuds SQL</strong></p>
<p>Le lancement et l’arrêt d’un nœud SQL se fait de la même manière que pour un serveur mySQL autonome avec</p>
<p><strong>rcmysql               start : </strong>démarre le nœud<strong> </strong></p>
<p><strong>stop : </strong>stoppe le nœud</p>
<p><strong>4.1.3      Nœuds NDB</strong></p>
<p>Le lancement et l’arrêt d’un nœud NDB se fait par la commande</p>
<p><strong>rcndbd                 start : </strong>démarre le nœud<strong> </strong></p>
<p>stop :<strong> </strong>stoppe le nœud (ne doit jamais être utilisé, les nodes NDB doivent être arrêtés depuis les nodes MGM, comme indiqué en  4.3.4. Cette option est à utiliser en cas d’urgence seulement, des pertes de données sont possibles alors)</p>
<p>format :<strong> </strong>DANGER :<strong> </strong>efface toutes les données du nœud et le démarre (utilisé principalement pour les premiers démarrages et pour certains les recovery)</p>
<h3>4.2       Démarrage / Arrêt du Cluster</h3>
<p>L’opération d’arrêt / marche du cluster n’est pas anodine et <span style="text-decoration: underline;">ne doit pas normalement être utilisée</span>, sauf pour des cas extrêmes (maintenance, …), en effet, tous les nœuds vont être stoppés ou lancés, cette opération peut notamment provoquer des pertes de données si elle est effectuée en activité.</p>
<p>L’arrêt et marche du cluster consiste à arrêter / démarrer les nœuds dans un ordre bien précis :</p>
<h3>4.2.1      Démarrage :</h3>
<p>-          Sur MGM-01</p>
<p>rcndb_mgmd  init</p>
<p>…</p>
<p>Vérifier avec rcndb_mgmd  status (voir 4.3.1)</p>
<p>-          Sur MGM-02</p>
<p>rcndb_mgmd  init</p>
<p>…</p>
<p>Vérifier avec rcndb_mgmd  status (voir 4.3.1)</p>
<p>-          Sur NDB-01</p>
<p>rcndbd   start</p>
<p>…</p>
<p>Vérifier avec ps ax  |  grep ndb que deux process ndbd sont présents</p>
<p>-          Sur NDB-02</p>
<p>rcndbd   start</p>
<p>…</p>
<p>Vérifier avec ps ax  |  grep ndb que deux process ndbd sont présents</p>
<p>-          Sur SQL-01</p>
<p>rcmysql   start</p>
<p>…</p>
<p>-          Sur SQL-02</p>
<p>rcmysql   start</p>
<p>…</p>
<p>Vérifier que tout est OK en se connectant avec un client mySQL sur les frontaux mySQL (password root / mysql) et que, depuis les deux frontaux, on peut accéder aux datas.</p>
<p><strong>4.2.2      Arrêt</strong></p>
<p><strong> </strong></p>
<p>-          Sur MGM-01 ou MGM-02</p>
<p>rcndb_mgmd  stop-all</p>
<p>-          Sur SQL-01</p>
<p>rcmysql   stop</p>
<p>…</p>
<p>-          Sur SQL-02</p>
<p>rcmysql   stop</p>
<p><strong>4.2.3      Urgence</strong></p>
<p>En cas d‘urgence seulement, les scripts suivants peuvent aussi êtres utilisés :</p>
<p>-          Arrêt      : rcndb_mgmd stop-cluster</p>
<p>-          Marche : rcndb_mgmd start-cluster (mode init des nodes MGM)</p>
<p><span style="text-decoration: underline;">Remarque :</span> L’opération de démarrage de tous les nœuds est rapide, en revanche, la synchronisation inter nœuds ne l’est pas forcément, il ne faudra pas hésiter à attendre plusieurs secondes avant de vérifier l’état du cluster comme indiqué en 4.3.1 et de conclure que cela ne fonctionne pas ou que cela fonctionne.</p>
<p><strong> </strong></p>
<p><strong>4.3       Etat du cluster</strong></p>
<p><strong> </strong></p>
<p>L’étatdu cluster est consultable depuis un « client » MGM, celui-ci est installé dans nos exemples sur tous les serveurs MGM, il suffit donc, depuis un serveur MGM démarré de taper la commande : ndb_mgm.</p>
<p>Un « shell » de client mgm permet alors de taper divers commandes :</p>
<p><strong>4.3.1      Nœuds connectés et déconnectés</strong></p>
<p><strong>ndb_mgm &gt; show</strong></p>
<p>Connected to Management Server at: localhost:1186</p>
<p>Cluster Configuration</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>[ndbd(<strong>NDB</strong>)]     2 node(s)</p>
<p>id=29   @10.20.0.29  (mysql-5.1.41 ndb-7.0.13, Nodegroup: 0, Master)</p>
<p>id=30   @10.20.0.30  (mysql-5.1.41 ndb-7.0.13, Nodegroup: 0)</p>
<p>[ndb_mgmd(<strong>MGM</strong>)] 2 node(s)</p>
<p>id=27   @10.20.0.27  (mysql-5.1.41 ndb-7.0.13)</p>
<p>id=28   @10.20.0.28  (mysql-5.1.41 ndb-7.0.13)</p>
<p>[<strong>mysqld</strong>(API)]   3 node(s)</p>
<p>id=25   @10.20.0.25  (mysql-5.1.41 ndb-7.0.13)</p>
<p>id=26   @10.20.0.26  (mysql-5.1.41 ndb-7.0.13)</p>
<p><em>id=50 (not connected, accepting connect from any host)</em></p>
<p>Ici nous pouvons observer que 7 nœuds ont été lus dans le fichier de configuration (textuel ou binaire) du serveur de MGM que l’on interroge.</p>
<p>Le nœud n°50 ne s’est pas quant à lui présenté aux serveurs de managment, n’est pas démarré, ou est tombé pour une raison quelconque.</p>
<p><strong>4.3.2      Etat de la mémoire</strong></p>
<p><strong>ndb_mgm &gt; all report memory</strong></p>
<p>Node 29: Data usage is 0%(24 32K pages of total 2560)</p>
<p>Node 29: Index usage is 0%(21 8K pages of total 2336)</p>
<p>Node 30: Data usage is 0%(24 32K pages of total 2560)</p>
<p>Node 30: Index usage is 0%(21 8K pages of total 2336)</p>
<p>Consommation mémoire des différents nœuds. Cette option permet de savoir s’il faut incrémenter les valeurs dataMemory et IndexMemory du fichier de configuration du cluster.</p>
<p><strong>4.3.3      Etat des backups en cours</strong></p>
<p><strong><br />
</strong></p>
<p><strong>ndb_mgm&gt; all report BackupStatus</strong></p>
<p>Node 29: Backup not started</p>
<p>Node 30: Backup not started</p>
<p>Lorsque des backups sont en cours d’exécution (voir  5.2), cette commande permet d’observer leur état d’avancement. Ici aucun backup n’est en cours d’exécution.</p>
<p><strong>4.3.4      manipulation des nodes NDB</strong></p>
<p><strong>ndb_mgm&gt; &lt;node_id&gt; STOP</strong></p>
<p><strong>ndb_mgm&gt; &lt;node_id&gt; START</strong></p>
<p><strong>ndb_mgm&gt; &lt;node_id&gt; STATUS</strong></p>
<p><strong>ndb_mgm&gt; ALL STOP</strong></p>
<p><strong>ndb_mgm&gt; ALL START</strong></p>
<p><strong>ndb_mgm&gt; ALL STATUS</strong></p>
<p><strong>5. Sauvegarde et Restauration</strong></p>
<p><strong>5.1 Mode &#8220;SINGLE USER&#8221;</strong></p>
<h3><strong><br />
</strong></h3>
<p>Le SINGLE USER MODE est utilisé pour restreindre l’accès au cluster à un nœud SQL unique et généralement accessible uniquement par un administrateur et auxquels les applicatifs et/ou les utilisateurs n’ont pas accès, ceci dans le but de faire des opération administratives sans être gêne par les requêtes clientes (restauration, …).</p>
<p>Il faut se connecter sur un nœud MGM et passer la commande :</p>
<p><strong>ndb_mgm –e ‘’ENTER SINGLE USER MODE &lt;ID&gt;’’</strong></p>
<p>(&lt;ID&gt; est le Node-ID d’un nœud SQL administratif (voir fichier de config en  3.3))</p>
<p>Pour revenir à un état normal du cluster, il faut indiquer au serveur de Managment la commande</p>
<p><strong>ndb_mgm –e ‘’EXIT SINGLE USER MODE’’</strong></p>
<p><strong><br />
</strong></p>
<p><strong> </strong></p>
<p><strong>5.2       Backup base ouverte (« à chaud »)<br />
</strong></p>
<p><strong>5.2.1      Introduction</strong></p>
<p>La sauvegarde d’une base sur un cluster mySQL consiste en une opération de sauvegarde des réplicas (données synchronisées inter-nœuds), donc sur chaque nœud NDB, ceci incluant les transactions de base de données en cours (redologs) afin d’assurer l’intégrité des données en cas de restauration.</p>
<p>Une sauvegarde consiste en la création d’un jeu de données sur chaque nœud de stockage NDB. Nous choissons de les stocker  dans les dossiers <strong>/data/mysql/backups/</strong></p>
<p>La restauration sera une restauration des backups ainsi réalisés sur chaque nœud (un backup d’une database sur n nœuds NDB se restaurera avec une n opérations de restaurations)</p>
<h3>5.2.2      Méthode</h3>
<p>Pour lancer un backup d’une database, il faut se positionner <span style="text-decoration: underline;">sur un nœud MGM</span> et utiliser la commande :</p>
<p><strong>rcndb_mgmd backup</strong></p>
<p><strong> </strong></p>
<p>Ceci aura pour effet de demander la création d’un backup des métadatas des databases pour chaque nœud NDB et de ranger les « fragments » de backup, su chaque nœuds, dans le répertoire <strong>/data/mysql/backups/BACKUP/BACKUP-&lt;Q&gt;&lt;HHMMSS&gt;/</strong> où Q est le quantième de la date de déclanchement du backup et HHMMSS l’heure de ce même déclanchement.</p>
<p>Le dossier de backup ainsi créé sur chaque nœud NDB contient :</p>
<p>-          *.ctl &lt;= Les fichiers de contrôles</p>
<p>-          *.Data &lt;= Les fichiers de données</p>
<p>-          *.log &lt;= Les fichiers de transactions pour le recovery des datas après restauration/</p>
<p><strong>5.3       Restauration</strong></p>
<p><strong><br />
</strong></p>
<p><strong>5.3.1      Introduction</strong></p>
<p>Comme indiqué en introduction du paragraphe de backup, la restauration d’une database consiste en la restauration de n sauvegardes présentes sur les n nœuds NDB.</p>
<p><strong>5.3.2      Méthode<br />
</strong></p>
<p><strong>5.3.2.1         Quelle restauration faut-il effectuer ?</strong></p>
<p>En fonction du type de perte de données et de la volonté de restaurer tout ou partie du cluster ou d ‘une base de données, les « checklist » ne sont pas exactement les mêmes.</p>
<p>Il se distingue globalement trois besoins en matière de restauration de données depuis une sauvegarde :</p>
<p>-          <span style="text-decoration: underline;">CLUSTER</span> (tout est foutu =&gt; restauration générale)</p>
<p>-          <span style="text-decoration: underline;">DATABASE</span> (une base de données est HS [ drop database, erreur FS, …], il faut la restaurer</p>
<p>-          <span style="text-decoration: underline;">TABLE</span> [ erreur logique et demande utilisateur ]</p>
<p>Trois besoins, trois méthodes. Au-delà de cela, il faudra réfléchir avant d’agir !</p>
<h5>a.        Restauration du CLUSTER :  Restauration de la totalité du cluster</h5>
<p><strong> </strong></p>
<ul>
<li>Positionner le cluster en « SINGLE USER MODE » (voir  5.1)</li>
<li>Arrêter le cluster (voir  4.2.2)</li>
<li>Démarrer tous les nœuds NDB en initialisant des espaces de données
<ul>
<li>Sur chaque nœud NDB : <strong>rcndbd  format</strong></li>
</ul>
</li>
<li>Restaurer les métadatas (create table, …)
<ul>
<li>Sur un des nœuds NDB :</li>
</ul>
</li>
</ul>
<p>ndb_restore   –c   &lt;ip MGM&gt; \</p>
<p>–n  &lt;ID NDB&gt;  <strong>–m</strong> –b  &lt;ID backup&gt;   \</p>
<p>–backup_path=/data/mysql/backup/</p>
<ul>
<li>Restaurer les datas
<ul>
<li>Sur tous les nœuds NDB :</li>
</ul>
</li>
</ul>
<p>ndb_restore   –c   &lt;ip MGM&gt; \</p>
<p>–n  &lt;ID NDB&gt;  <strong>–r</strong> –b  &lt;ID backup&gt;   \</p>
<p>–backup_path=/data/mysql/backup/</p>
<ul>
<li>Restaurer les objets de base de données (triggers, procédures stockées, …)
<ul>
<li>Sur tous les nœuds SQL :
<ul>
<li>rcmysql  start</li>
<li>Repérer le dernier dump sql structuel dans le dossier /data/mysql/backup/  et de type « dump_STRUCT_&lt;yyyyy&gt;.sql » puis l’appliquer au serveur  avec :</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>mysql  –uroot  &lt;  /data/mysql/backup/dump_STRUCT_&lt;yyyyy&gt;.sql</p>
<ul>
<li>Sortir le cluster du « SINGLE USER MODE »</li>
</ul>
<h5>b.       Restauration d’une base de données : Restauration partielle d’une database ‘DB’</h5>
<ul>
<li>Positionner le cluster en « SINGLE USER MODE »</li>
<li>Détruire la database ‘DB’ :
<ul>
<li>Sur chaque nœud SQL :
<ul>
<li>mysql  –uroot  -pmysql</li>
<li>mysql&gt;  drop database  db ;</li>
<li>mysql&gt;  exit ;</li>
</ul>
</li>
</ul>
</li>
<li>Restaurer les métadatas de la database (create table, …)
<ul>
<li>Sur un des nœuds NDB :</li>
</ul>
</li>
</ul>
<p>ndb_restore   –c   &lt;ip MGM&gt; \</p>
<p>–n  &lt;ID NDB&gt;  <strong>–m</strong> –b  &lt;ID backup&gt;   \</p>
<p>–backup_path=/data/mysql/backup/ \</p>
<p>&#8211;include-databases=db</p>
<ul>
<li>Restaurer les datas
<ul>
<li>Sur tous les nœuds NDB :</li>
</ul>
</li>
</ul>
<p>ndb_restore   –c   &lt;ip MGM&gt; \</p>
<p>–n  &lt;ID NDB&gt;  <strong>–r</strong> –b  &lt;ID backup&gt;   \</p>
<p>–backup_path=/data/mysql/backup/ \</p>
<p>&#8211;include-databases=db</p>
<ul>
<li>Restaurer les objets de base de données (triggers, procédures stockées, …)
<ul>
<li>Sur tous les nœuds SQL :
<ul>
<li>rcmysql  start</li>
<li>Repérer le dernier dump sql structuel de la database ‘db’ dans le dossier /data/mysql/backup/  et de type « dump_STRUCT_ DATABASE_DB_&lt;yyyyy&gt;.sql » puis l’appliquer au serveur  avec :</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>mysql  –uroot  &lt;  /data/mysql/backup/dump_STRUCT_DATABASE_DB_&lt;yyyyy&gt;.sql</p>
<ul>
<li>Sortir le cluster du « SINGLE USER MODE »</li>
</ul>
<p><strong> </strong></p>
<h5>c.        Restauration d’une table : Restauration d’une table ‘T’ de la database ‘DB’</h5>
<ul>
<li>Positionner le cluster en « SINGLE USER MODE »</li>
<li>Détruire la table ‘T’ de la database ‘DB’ :
<ul>
<li>Sur chaque nœud SQL :
<ul>
<li>mysql  –uroot  -pmysql</li>
<li>mysql&gt;  drop table  db.t ;</li>
<li>mysql&gt;  exit ;</li>
</ul>
</li>
</ul>
</li>
<li>Restaurer les métadatas de la database (create table, …)
<ul>
<li>Sur un des nœuds NDB :</li>
</ul>
</li>
</ul>
<p>ndb_restore   –c   &lt;ip MGM&gt; \</p>
<p>–n  &lt;ID NDB&gt;  <strong>–m</strong> –b  &lt;ID backup&gt;   \</p>
<p>–backup_path=/data/mysql/backup/ \</p>
<p>&#8211;include-databases=db \</p>
<p>&#8211;include-tables=t</p>
<ul>
<li>Restaurer les datas
<ul>
<li>Sur tous les nœuds NDB :</li>
</ul>
</li>
</ul>
<p>ndb_restore   –c   &lt;ip MGM&gt; \</p>
<p>–n  &lt;ID NDB&gt;  <strong>–r</strong> –b  &lt;ID backup&gt;   \</p>
<p>–backup_path=/data/mysql/backup/ \</p>
<p>&#8211;include-databases=db \</p>
<p>&#8211;include-tables=t</p>
<ul>
<li>Sortir le cluster du « SINGLE USER MODE »</li>
</ul>
<p><strong>5.3.2.2         Syntaxe générale de « ndb_restore »</strong></p>
<p><span style="text-decoration: underline;">ATTENTION :</span> Cette commande est à exécuter DEPUIS un nœud de stockage NDB.</p>
<p><strong>ndb_restore </strong></p>
<p>&#8211;connect &lt;ip addr&gt; (ou ‘–c’)                    &lt;= MGM serveur qui pilote la restauration</p>
<p>&#8211;restore_meta (ou ‘- m’)                          &lt;= restaurer les métadatas (DDL)</p>
<p>&#8211;nodeid=&lt;node ID&gt; (ou ‘-n’)                   &lt;= le numéro d’un nœud NDB</p>
<p>&#8211;backupid=&lt; backup ID&gt; (ou ‘-b’)          &lt;= le numéro du backup (voir 5.2.2)</p>
<p>&#8211;rebuild-indexes (ou ‘- r’)                         &lt;= reconstruction des index</p>
<p>&#8211;backup_path=/data/mysql/backup    &lt;= le chemin des backups sur les nœuds NDB</p>
<p>[ --include-databases=ma_database ]                 &lt;= restreindre le backup à cette database</p>
<p>[ --include-tables=table1,table2 ]          &lt;= restreindre le backup à ces tables</p>
<p>[ -- print_log ]</p>
<p><strong>6. Considérations pour les développeurs</strong></p>
<p><strong><br />
</strong></p>
<p><strong>6.1 Limitations classiques du cluster NDB</strong></p>
<p><strong><br />
</strong></p>
<p>Il existe de nombreuses limitations quant à l’utilisation d’un cluster au sens de mySQL, mais la plupart de celles-ci sont exotiques et peuvent être de ce fait contournées facilement.</p>
<p>Les limitations « classiques » sont :</p>
<p>-          Limitation de 128 champs par table</p>
<p>-          Interdiction d’utiliser des clés étrangères</p>
<p>-          Interdiction d’utiliser la création de tables temporaires (temporary tables)</p>
<p>-          Pas d’index sur les champs FULLTEXT ou LOB (BLOB, CLOB, …)</p>
<p>-          Obligation de créer sur tous les nœuds SQL les déclencheurs, fonctions et procédures stockées (métadatas)</p>
<p>-          Interdiction d’utiliser les transactions en SavePoint (plusieurs rollbacks possibles en différents points sur une seule transactions ouverte)</p>
<p><strong>6.2       Problématique liée à l’absence de clés étrangères</strong></p>
<p>L’absence de possibilité d’utiliser les clés étrangères pour une table gérée par le moteur NDBENGINE empêche par définition de s’assurer de l’intégrité référentielle ou de la mise à jour en cascade des données.</p>
<p>Pour pallier à ce manque, il convient d’utiliser des TRIGGERs, principalement AVANT  opération DML dans le but d’effectuer manuellement les vérifications d’intégrité référentielle et de provoquer une erreur (voire les fonctions UDF en  2.3) en cas d’anomalie détectée.</p>
<p><span style="text-decoration: underline;">ATTENTION</span> : les triggers (comme les fonctions et procédures stockées) ne sont pas des objets dépendants des tables mais de la base de données. Ils ne sont donc pas gérés par les nœuds NDB mais par les nœuds SQL. Aucune propagation de configuration d’un nœud SQL sur un autre n’existe dans cette version du cluster (7.x), il faut donc, sur tous les nœuds SQL, définir les mêmes objets.</p>
<p><strong>6.2.1      Des TRIGGERS pour assurer l’intégrité référentielle</strong></p>
<p>Prenons l’exemple une table TABLEFILLE(IDFILLE, NOM, IDPARENT) qui devrait être liée à une table « mère » TABLEPARENT(IDPARENT, NOM) par le champ IDPARENT.</p>
<p>L’absence de clé étrangère sur ces tables ne permet pas d’assurer l’intégrité référentielle, nous allons utiliser un trigger pour pallier à ce manque.</p>
<p>Voici le trigger permettant de respecter l’intégrité référentielle qu’il faut créer <span style="text-decoration: underline;">sur tous les nœuds SQL</span> :</p>
<p>DROP TRIGGER IF EXISTS TG_TABLEFILLE_PARENTKEYOK_BI;</p>
<p>DELIMITER |</p>
<p>CREATE TRIGGER TG_TABLEFILLE_PARENTKEYOK_BI BEFORE INSERT ON TABLEFILLE</p>
<p>FOR EACH ROW BEGIN</p>
<p>DECLARE RESULTAT INT;</p>
<p>IF ((SELECT COUNT(*) FROM TABLEPARENT WHERE TABLEPARENT.IDPARENT=new.IDPARENT)=0) THEN</p>
<p>SET RESULTAT=udf_initid_error(&#8220;Intégrité référentielle violée sur TABLEFILLE &#8211;&gt; TABLEPARENT&#8221;);</p>
<p>END IF;</p>
<p>END;</p>
<p>|</p>
<p>DELIMITER ;</p>
<p><strong>6.2.2      Des TRIGGERS pour assurer les mises à jour en cascade</strong></p>
<p>L’absence de clé étrangère sur ces tables ne permet pas d’assurer la mise à jour en cascade des lignes de tables filles lorsque des lignes dépendantes sur une table mère sont supprimées.  Nous allons encore une fois utiliser un trigger pour pallier à ce manque.</p>
<p>Reprenons l’exemple des tables TABLEFILLE et TABLEPARENT de 6.2.1.</p>
<p>DROP TRIGGER IF EXISTS TG_TABLEPARENT_DELCASCADE_BD;</p>
<p>DELIMITER |</p>
<p>CREATE TRIGGER TG_TABLEPARENT_DELCASCADE_BD BEFORE DELETE ON TABLEPARENT</p>
<p>FOR EACH ROW BEGIN</p>
<p>DELETE FROM TABLEFILLE WHERE TABLEFILLE.IDPARENT=old.IDPARENT ;</p>
<p>END;</p>
<p>|</p>
<p>DELIMITER ;</p>
<p><strong>6.3       Codes d’erreurs rencontrés</strong></p>
<table border="1" cellspacing="0" cellpadding="0" width="756">
<tbody>
<tr>
<td width="104" valign="top"><strong>CODE   ERREUR</strong></td>
<td width="652" valign="top"><strong>Explication   / Solution</strong></td>
</tr>
<tr>
<td width="104" valign="top">157</td>
<td width="652" valign="top">« Could not connect to storage engine »</p>
<p>Les noeuds NDB sont arrêtés ou les nœuds MGM sont arrêtes :   vérifier et les relancer si besoin</td>
</tr>
<tr>
<td width="104" valign="top">1296</td>
<td width="652" valign="top">Impossible de communiquer avec les nœuds NDB</p>
<p>Faire un ndm_mgm –e « show »  pour vérifier leur statuts, les démarrer au   cas ou</td>
</tr>
<tr>
<td width="104" valign="top"><em>1114</em></td>
<td width="652" valign="top">Nombre d’index max. (non PK) atteint</p>
<p>ð    Augmenter la valeur  « MaxNoOfOrderedIndexes »   + start « init » mode</td>
</tr>
<tr>
<td width="104" valign="top">1005</td>
<td width="652" valign="top">Nombre d’attributs max. atteint</p>
<p>ð    Augmenter    la valeur de MaxNoOfAttributes   + start « init » mode</td>
</tr>
<tr>
<td width="104" valign="top">1478</td>
<td width="652" valign="top">Impossible d’indexer un champ CLOB, BLOB, TEXT, FULLTEXT,   LONGTEXT</p>
<p>ð    Supprimer l’index ou changer le typage du   champ</td>
</tr>
<tr>
<td width="104" valign="top">1089</td>
<td width="652" valign="top">Interdiction d’utiliser des préfixes pour les indexes : non   supporté</p>
<p>ð    « UNIQUE KEY » devient   « KEY », …</td>
</tr>
<tr>
<td width="104" valign="top">1297</td>
<td width="652" valign="top">Trop d’opérations simultanées</p>
<p>ð    Augmenter la valeur de   « MaxNoOfConcurrentOperations » + start « init » mode</p>
<p>ð    Augmenter (peut être) la valeur de « MaxNoOfLocalOperations »   + start « init » mode</p>
<p>Cette erreur apparait généralement lors de l’injection de dumps,   …</td>
</tr>
</tbody>
</table>
<p><strong><span style="text-decoration: underline;">CopyLeft: </span></strong></p>
<p>Ces données sont issues d&#8217;un document interne de production provenant d&#8217;un DataCenter français.</p>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/22/installation-dun-cluster-mysql-ndb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vues matérialisées</title>
		<link>http://cx.cx/2011/02/22/vues-materialisees/</link>
		<comments>http://cx.cx/2011/02/22/vues-materialisees/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 16:30:26 +0000</pubDate>
		<dc:creator>golgoth20</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[materialized views]]></category>
		<category><![CDATA[vues]]></category>
		<category><![CDATA[vues matérialisées]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=99</guid>
		<description><![CDATA[Comme une vue au sens classique d&#8217;Oracle, une vue matérialisée (&#8220;MaterializedView&#8221; ou &#8220;MV&#8221;) est une vue basée sur une requête SQL. A l&#8217;instar d&#8217;une vue classique, lorsque l&#8217;on crée une vue matérialisée, Oracle crée alors une table dont la structure correspond exactement à celle induite par le résultat du select associé. Les données de la vue matérialisée [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>Comme une vue au sens classique d&#8217;Oracle, une <span style="text-decoration: underline;">vue matérialisée</span> (&#8220;MaterializedView&#8221; ou &#8220;MV&#8221;) est une vue basée sur une requête SQL. A l&#8217;instar d&#8217;une vue classique, lorsque l&#8217;on crée une vue matérialisée, Oracle crée alors une table dont la structure correspond exactement à celle induite par le résultat du select associé. Les données de la vue matérialisée sont alors issues de la requête SQL et <span style="text-decoration: underline;">recopiées physiquement</span> dans cette table, on dit alors que <span style="text-decoration: underline;">les données sont &#8220;matérialisées&#8221;</span>.</p>
<p><img title="Lire la suite…" src="http://www.startupmount.com/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /></p>
<p><span style="text-decoration: underline;">1 &#8211; Introduction / Rappels :</span></p>
<p>Les avantages d&#8217;une vue matérialisée sont globalement dans la <span style="text-decoration: underline;">rapidité</span> d&#8217;accès aux données, en effet, si les tables dont sont issues les requêtes SQL induisant les vues matérialisées sont complexes, le fait d&#8217;y accéder par l&#8217;intermédiaire d&#8217;une vue matérialisée en rendra l&#8217;accès extrêmement plus rapide puisque celle-ci sont en fait recopiées physiquement dans la table de la dite vue et de nécessite plus l&#8217;interprétation d&#8217;un plan d&#8217;exécution complexe pour les récupérer.</p>
<p>Les vues matérialisées sont globalement utilisées pour accélérer l&#8217;accès à des données dont le quotient de mise à jour demeure faible. En effet, si les données d&#8217;une MV sont matérialisées dans une table, il peut exister à un instant &lt;T&gt; un décalage entre les données réellement présentes dans les tables pointées par la requête SQL et les données physiquement recopiées, une mise à jour de ces données physique est alors nécessaire pour se rapprocher des données réelles.</p>
<p>Dans ce contexte, nous verrons qu&#8217;il existe plusieurs méthodes pour mettre à jour une vue matérialisées, plus ou moins adaptées à l&#8217;utilisation que les utilisateurs en font et permettant aussi de faire au sens d&#8217;Oracle de la <span style="text-decoration: underline;">réplication</span>de données entre hôtes distants.</p>
<p><span style="text-decoration: underline;">2 &#8211; Création/Suppression d&#8217;une Vue Matérialisée :</span></p>
<p>La création d&#8217;une vue matérialisée se fait par l&#8217;instruction :</p>
<pre>create materialized view &lt;nom_vue_materialisée&gt; as &lt;requête_SQL&gt;
                    [ refresh &lt;mode&gt; [ &lt;type&gt; ] [ with &lt;cycle&gt; ]
                      [ FORCE | FAST ] ]</pre>
<p><span style="text-decoration: underline;">Exemple:</span></p>
<pre>SQL&gt; create materialized view mv_personnes</pre>
<pre>2 as select c.nom, c.prenom, v.nomville from clients c,
ville v where c.id_ville=v.id_ville;</pre>
<pre>SQL&gt; select * from mv_personnes;</pre>
<pre>NOM      PRENOM      NOMVILLE</pre>
<pre>------   -------     -------------------------------
NOM_1    PRENOM_1    ANGOULEME
NOM_2    PRENOM_2    BASTIA</pre>
<p>Une vue matérialisée se détruit par un drop au sens classique du terme :</p>
<pre>SQL&gt; drop materialized view mv_personnes;</pre>
<p><span style="text-decoration: underline;">Note:</span> Les vues systèmes USER_MVIEWS et DBA_MVIEWS permettent aux utilisateurs et aux DBAs d&#8217;obtenir toutes les informations sur les vues matérialisées auxquels ils ont accès. Le champ &#8220;query&#8221; permet notament d&#8217;indentifier la requête SQL induisant la vue matérialisée et &#8220;mview_name&#8221; le nom de la table physique créée pour matérialiser les données de cette requête.</p>
<p><span style="text-decoration: underline;">3 &#8211; Modes de rafraichissement des vues matérialisées :</span></p>
<p>Comme nous l&#8217;avons évoqué précédement, la pertinence d&#8217;une vue matérialisée est caractérisée par la fréquence de mise à jour (ou de synchronisation) de ses données par rapport aux données des tables mères sur laquelle porte la requête SQL qui l&#8217;induit. En clair : quelle est la méthode et la fréquence de rafraichissement des données matérialisées de la vue par rapport aux données réélles existant dans les tables pointées par la requête SQL de la vue matérialisée?</p>
<p><span style="text-decoration: underline;">3.1) Rafraichissement synchrone sur validation</span></p>
<p>Le mode de rafraichissement sur validation des vues matérialisation est celui qui vous permet d&#8217;assurer une équivalence parfaite entre les données matérialisées et celles dynamiques issues de la requête SQL caractéristique. Chaque validation transactionelle (commit) aura pour effet de rafraichir les données de la MV, une donnée validée dans une table mère impliquera au préalable une donnée inscrite dans la table de la MV.</p>
<p>L&#8217;équivalence des données de la MV est donc assurée de manière synchrone par rapport aux données situées dans les tables pointées par la requête SQL caractérisant la vue.</p>
<p>C&#8217;est la plus éfficace des mises à jour en terme fonctionel, c&#8217;est la moins efficace en CPU et consomation mémoire. Une telle façon de fonctionner est éfficace si la MV se fait sur la même database contenant les tables mères pointées par la requête SQL. Si la MV est distante, des problèmes de performance apparaissent très vite et cette méthode est déconseillée.</p>
<p>En clair, cette méthode vous permet d&#8217;améliorer des requêtes lourdes sur une instance de base de données.</p>
<p>Syntaxe :</p>
<pre> create ... refresh on commit;</pre>
<p><span style="text-decoration: underline;">3.2) Rafraichissement asynchrone sur demande</span></p>
<p>Une MV en mode de rafraichissement sur demande, comme son nom l&#8217;indique, possède des données matérialisées qui sont mises à jour de façon evènementielle sur demande (administrative, par automatisme PLSQL, &#8230;). La méthode de rafraichissement est donnée par le package DBMS_REFRESH et la procédure REFRESH(&#8216;&lt;nom_MV&gt;&#8217;),</p>
<p>Syntaxe :</p>
<pre> create materialized view MV1 ...;
 ...
 execute DBMS_REFRESH.REFRESH('MV1');</pre>
<p><span style="text-decoration: underline;">Note:</span> Dans le cadre d&#8217;une réplication de tables, le package DBMS_REFRESH possède la méthode REFRESH_ALL_MVIEWS qui permet de rafraichir toutes les MV sans les nommer une à une.</p>
<p><span style="text-decoration: underline;">3.3) Rafraichissement asynchrone différentiel cyclique</span></p>
<p>Ce mode de rafraichissement est bien plus souvent utilisé que ces prédécesseurs car il économise les ressources de la base de donénes maître en réduisant le nombre de mises à jour nécessaires entre les MVs et les tables maitresses.</p>
<p>Le commutateur &#8220;start with&#8221; va permettre de définir une fréquence de mise à jour des données en collaboration avec le commutateur &#8220;next&#8221; qui permettra de définir l&#8217;intervalle de future mise à jour après la première éffectuée.</p>
<p>Syntaxe:</p>
<pre>create materialized view MV1
refresh
start with trunc(sysdate+1)+ 8/24
next trunc(sysdate + 1) + 24/24
as select * from t1, t2;</pre>
<p>Dans cet exemple, MV1 verra ses données matérialisées créées à 8 heures puis rafraichies automatiquement tous les jours à minuit.</p>
<p><span style="text-decoration: underline;">4 &#8211; Type de rafraichissement FORCE ou FAST :</span></p>
<p><span style="text-decoration: underline;">4.1 &#8211; Introduction :<br />
</span></p>
<p>Il existe deux &#8220;types&#8221; de rafraichissement des données matérialisées, le type FORCE ou le type FAST.</p>
<p>Le mode FORCE est le mode par défaut et implique le comportement de tous les exemples décrits dans les paragraphes précédents, il est donc inutile d&#8217;en reparler ici.</p>
<p>Le mode FAST implique une notion de mise à jour RAPIDE en opposition à une mise à jour plus lente qu&#8217;est la mise à jour complète des données d&#8217;une MV. Vous l&#8217;aurez compris (ou intuité), nous parlons ici d&#8217;une mise à jour différentielle des données matérialisées.</p>
<p><span style="text-decoration: underline;">4.2 &#8211; Type de mise à jour Rapide des données matérialisées :</span></p>
<p>Le typde mise à jour &#8220;rapide&#8221; d&#8217;une MV est un type incrémental. Afin de minimiser le temps de comparaison des données présentes dans les tables mères par rapport aux données présentes dans les tables des MV, un fichier de journalisation des données modifiées est créé à cet effet, ou plustot une &#8220;table&#8221; de journalisation des données matérialisées : on parle de MATERIALIZED VIEW LOG (tables &#8220;MLOG$_*&#8221;).</p>
<p>Ces tables de log &#8220;MLOG$_*&#8221; comprennent les modifications éffectuées sur les tables mères d&#8217;une MV (insert, update, delete) et permettent au MV de ne synchroniser que les enregistrements ayant subits des modifications, au contraire du type FORCE qui concerne l&#8217;ensemble des données de la MV (et donc des tables mères).</p>
<p>Ce type de fonctionnalité est donc précédé de la création de ces tables de LOG grâce à la commande :</p>
<pre>SQL&gt; create materialized view log on T;</pre>
<p>Ceci ayant pour effet de créer une table MLOG$_T sur le host courant, une table qui contiendra à dater de cet nstant toutes les modifications des lignes de la table T. Il conviendra par la suite de créer une vue matérialisée sur T pour bénéficier de ce journal.</p>
<p>La problématique de la fréquence des mises à jour ne chande pas (sur demande, on commit, &#8230;) sauf que celle ci se fera à dater de ce moment de manière différentielle et non plus de manière complète, ce qui représentera un gain de temps fondamental.</p>
<p>Il convient ensuite de préciser que l&#8217;on souhaite une vue matérialisée dont le typde mise à jour est basé sur l&#8217;exploitation de ces tables de log Oracle pour éffectuer des mises à jours incrémentales selon une fréquence à définir:</p>
<pre>SQL&gt; create materialized view MV REFRESH FAST on select * from T;</pre>
<p>La fréquence de lecture des journaux (tables) de log seront induites par les sous commutateurs <span style="text-decoration: underline;">start</span> et <span style="text-decoration: underline;">next</span>permettant de définir une condition initiale pour débuter une mise à jour et une récurence.</p>
<p><span style="text-decoration: underline;">5 &#8211; Réplication de données :</span></p>
<p><span style="text-decoration: underline;">5.1 &#8211; Introduction :<br />
</span></p>
<p>La réplication de données selon Oracle est assurée par la mise à jour de données de tables par les méthodes de synchronisations de données éffectuées grâce au concept de vue matérialisée.</p>
<p>Une réplication de données se fera donc à l&#8217;aide de l&#8217;utilisation des vues matérialisées, des notions qui seront accessibles à distance à l&#8217;aide de la notion de DB-LINK (Database Link) / liaison inter-bases de données.</p>
<p>Le principe d&#8217;un DB-LINK est d&#8217;accéder de manière transparente à des tables situées en dehors de l&#8217;instance de base de données principale, généralement située sur un autre hote accessible en TCP/IP. Un DB-LINK Oracle permet donc de lier des schémas de base de données inter instances entre elles.</p>
<p>La création d&#8217;un DB-LINK se réalise par la syntaxe suivante :</p>
<pre>CREATE PUBLIC DATABASE LINK CONNECT TO &lt;user&gt; IDENTIFIED BY &lt;pwd&gt; USING '&lt;tsn_conn&gt;' ;</pre>
<p>Avec les paramètres suivants :</p>
<p>- &lt;user&gt; : nom d&#8217;utilistateur de la DB distante</p>
<p>- &lt;pwd&gt;: le password de &lt;user&gt;</p>
<p>- &lt;tsn_conn&gt; :  la définition d&#8217;accès à la database distance par le TNS_NAME local.</p>
<p>Imaginons maintenant, à travers la définition de DB-LINK, qu&#8217;une table distante soit accessible depuis une instance de base de données locale, si nous créons sur la table distante un journal de log, rien ne nous empêche sur la base locale de créer alors une vue matérialisée en mode FAST, vue induuite par une requête utilisant cette même table distante caractérisée par un journal de log. Nous venons à cet instant précis d&#8217;alimenter une table d&#8217;une instance I1 par une table d&#8217;une instance I2, le tout, quel que soit la distantce, sur un réseau TCP/IP : Autrement dit : nous venons de faire de la réplication de données.</p>
<p><span style="text-decoration: underline;">5.2 &#8211; Mise en place :</span></p>
<p>Un petit peu pressé par le temps, je publie cet article maintenant en l&#8217;absence de rédaction de ce paragraphe. Sous peu, vous aurez sous le 5.2) l&#8217;exacte syntaxe pour mettre en place concrètement et rapidement la réplication de données selon Oracle (i.e. à travers des MV en type FAST).</p>
<p>En attendant, certaines informations vous seront peut être utiles, d&#8217;où la publication rapide !</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/22/vues-materialisees/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installation du moteur Oracle</title>
		<link>http://cx.cx/2011/02/22/installation-du-moteur-oracle/</link>
		<comments>http://cx.cx/2011/02/22/installation-du-moteur-oracle/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 16:27:35 +0000</pubDate>
		<dc:creator>golgoth20</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[moteur]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://cx.cx/?p=96</guid>
		<description><![CDATA[Cette procédure d&#8217;installation est validée sur les distributions 9iR2, 10g et 11g, vous pouvez trouver les éléments à télécharger directement en libre accès sur le site d&#8217;Oracle. Notez que Oracle n&#8217;éxige pas de lisence d&#8217;installation et, même si l&#8217;installeur vous averti que vous êtes hors lisence, le produit fonctionnera tout de même, ce qui vous permet [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>Cette procédure d&#8217;installation est validée sur les distributions 9iR2, 10g et 11g, vous pouvez trouver les éléments à télécharger directement en libre accès sur le site d&#8217;<a href="http://www.oracle.com/products/index.html#database" target="_blank">Oracle</a>. Notez que Oracle n&#8217;éxige pas de lisence d&#8217;installation et, même si l&#8217;installeur vous averti que vous êtes hors lisence, le produit fonctionnera tout de même, ce qui vous permet de l&#8217;évaluer rapidement, et ceci pour toutes ses fonctionalités.</p>
<p>1- Architechture OFA</p>
<p>Oracle recommande aux administrateurs systèmes d&#8217;installer leur produits selon une définition particulière des filesystem nommée <span style="text-decoration: underline;">Oracle Flexible Architecture</span> (OFA), mais ceci n&#8217;est que recommandation, libre à vous de procéder différemment.</p>
<p>Vous devez, à minima, créer un répertoire u01 à la racine de votre disque pour identifier un utilisateur n°1 d&#8217;une gamme de produit Oracle sur votre serveur. Le répertoire utilisateur Oracle contiendra à minima les sous répertoires app/products dans lequel sera déployé les différents produits d&#8217;Oracle (10g, 11g, &#8230;)</p>
<p>Deux variables d&#8217;environnement Oracle sont alors nécessaires car seront utilisées par les moteurs ainsi que par les instances des bases de données :</p>
<p>Exemples:</p>
<pre>export ORACLE_BASE = /u01/app/oracle</pre>
<pre>export ORACLE_HOME = $ORACLE_BASE/10.2/db_1</pre>
<p>Le module d&#8217;installation du moteur de bases de données Oracle OUI (Oracle Universal Installer) a besoin de l&#8217;existence de ces répertoires et de la déclarations de ces variables d&#8217;environnement pour fonctionner, le reste de l&#8217;arborescence OFA sera automatiquement généré.</p>
<p>2 -  Groupes Oracle et utilisateur</p>
<p>Oracle a besoin à minima de deux groupes systèmes dont les noms vous seront demandés à l&#8217;installation, il faut donc au préalablement les créer :</p>
<p>oinstall: groupe nécessaire à OUI</p>
<p>dba: les utilisateurs OS de ce groupes seront automatiquement considérés comme utilisateurs DBA par Oracle</p>
<p>oper: les utilisateurs OS de ce groupes seront automatiquement considérés comme utilisateurs OPERATEURS par Oracle</p>
<p>Vous devrez égallement créer un utilisateur &#8220;oracle&#8221; que vous associerez à chaque de ces trois groupes car, celui &#8211; ci pourra ainsi procéder à l&#8217;installation du logiciel puis, sera considéré par Oracle comme DBA et pourra poursuivre sur la création d&#8217;une première database.</p>
<p>Nous verrons dans d&#8217;autres articles l&#8217;intérêt de l&#8217;appartenance d&#8217;un user OS à ces groupes pour la manipulation des databases Oracle.</p>
<p>3 &#8211; Installation</p>
<p>Connectez vous avec l&#8217;utilisateur &#8220;oracle&#8221; et ouvrez (si ce n&#8217;est pas déjà fait), une session graphique. Le script de lancement de l&#8217;OUI se nomme runInstaller.sh, lancez-le et suivez pas à pas la procédure, elle est très simple.</p>
<p><span style="text-decoration: underline;">Remarque:</span> Si vous ne possédez pas de distribution &#8220;qualifiée&#8221; par Oracle, il vous faudra ajouter le commutateur &#8220;&#8211;ignoresysprereqs&#8221; au script pour acquiescer le fait que vous prenez un risque et que vous ne pouvez pas dans ce cas bénéficier du support Oracle.</p>
<p>Même si cette installation doit se faire sous l&#8217;autorité du user oracle, il vous faudra à la fin exécuter des scripts en tant que root. Le chemin de ces scripts vous sera indiqué par l&#8217;OUI et ne demandent aucun paramètre, ils configureront votre produit pour les options de licence que vous aurez spécifié au début de l&#8217;installation.</p>
<p>Une fois le moteur de base de données Oracle installé, OUI permet, si vous le souhaitez, de lancer automatiquement d&#8217;autres assistants de configuration réseau (&#8220;netca&#8221;) et de configuration de databases (&#8220;dbca&#8221;), mais ces deux modules font partie d&#8217;un article supplémentaire sur ce site.</p>
<p><span style="text-decoration: underline;">Note: </span>N&#8217;oubliez pas d&#8217;aller modifier le fichier /etc/profile.d/oracle.sh pour aller y insérer les bonnes valeurs des variables d&#8217;environnement Oracle car c&#8217;est ici qu&#8217;elles seront initialisées par les scripts de démarrage de init.d.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://cx.cx/2011/02/22/installation-du-moteur-oracle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

