<?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>Startupmount</title>
	<atom:link href="http://www.startupmount.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.startupmount.com</link>
	<description>Databases and Operating Systems</description>
	<lastBuildDate>Wed, 18 Jan 2012 19:30:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>RMAN : Configuration élémentaire</title>
		<link>http://www.startupmount.com/articles/rman-configuration-elementaire/</link>
		<comments>http://www.startupmount.com/articles/rman-configuration-elementaire/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 14:32:22 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Sauvegardes]]></category>
		<category><![CDATA[archives]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[redo]]></category>
		<category><![CDATA[restaurations]]></category>
		<category><![CDATA[rman]]></category>
		<category><![CDATA[sauvegardes]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=187</guid>
		<description><![CDATA[RMAN est l&#8217;outil de sauvegarde des bases Oracle (fourni par Oracle), il est à même de discuter avec le moteur de base de données pour les opérations de recovery. Même s&#8217;il existe de nombreux outils de sauvegarde sur le marché,  il apparait que RMAN est le meilleur outil pour être certain de sauvegarder correctement. De [...]]]></description>
			<content:encoded><![CDATA[<div>
<p><strong>RMAN</strong> est l&#8217;outil de sauvegarde des bases <strong>Oracle</strong> (fourni par Oracle), il est à même de discuter avec le moteur de base de données pour les opérations de <strong>recovery</strong>. Même s&#8217;il existe de nombreux outils de sauvegarde sur le marché,  il apparait que RMAN est <em>le meilleur outil</em> pour être certain de sauvegarder correctement.</p>
<p>De plus, l&#8217;interface utilisateur de RMAN est d&#8217;une simplicité affligente pour 90% des cas de sauvegardes / restaurations, les 10% restants nécessitant il est vrai une certaine connaissance du produit, mais, n&#8217;est-ce pas le cas pour tous les outils de sauvegarde ?</p>
<p><span style="text-decoration: underline;">Cet  article permet au DBA d&#8217;appréhender 80% du périmètre d&#8217;utilisation de RMAN dans de bonnes conditions.</span><span id="more-187"></span></p>
<p><strong><span style="text-decoration: underline;">1 &#8211; Introduction</span></strong></p>
<p><strong>RMAN</strong> peut utiliser <span style="text-decoration: underline;">différent référentiels</span> de sauvegardes dont vous devez <a href="http://cx.cx/2009/05/17/rman-presentation-et-referentiel/">prendre connaissance </a>avant même de consulter cet article. En effet, il est possible d&#8217;utiliser les <span style="text-decoration: underline;">fichiers de controles</span> d&#8217;une instance de base de données comme référentiel (ce qui n&#8217;est pas recommandé, en effet, une perte du fichier empecherait un recovery), ou une<span style="text-decoration: underline;"> instance de base de données spécialisée</span> à cet effet.</p>
<p>La connection au référentiel de sauvegarde s&#8217;éffectue de la manière suivante  dans le cadre de l&#8217;utilisation d&#8217;un catalogue de récupération :</p>
<pre><span style="color: #339966;">rman target &lt;chaine_de_connexion_vers_la_database&gt; catalog &lt;chaine_de_connexion_au_catalogue&gt;</span></pre>
<p>La connection au référentiel de sauvegarde s&#8217;éffectue de la manière suivante  dans le cadre de l&#8217;utilisation de l&#8217;utilisation des fichiers de controles comme référentiel de sauvegarde :</p>
<pre><span style="color: #339966;">rman target / (en tant que sysdba sur le host local)</span></pre>
<p>OU</p>
<pre><span style="color: #339966;">rman &lt;chaine_de_connexion_vers_la_database&gt;</span></pre>
<p>Tout ajout / modification d&#8217;une configuration par rman se fera avec l&#8217;attribut <em>CONFIGURE</em>.</p>
<p><strong><span style="text-decoration: underline;">2 &#8211; Nomenclature de RMAN</span></strong></p>
<p>RMAN, comme tous les outils de sauvegarde, utilise une nomenclature de nommage des objets qu&#8217;il convient de connaitre afin de bien comprendre les manipulations que l&#8217;on entreprend avec ce type d&#8217;outil.</p>
<p>En voici une liste (non exhaustive) :</p>
<p><strong><span style="text-decoration: underline;">2.1 &#8211; CANAL ET PERIPHERIQUE RMAN</span></strong></p>
<p><strong><span style="text-decoration: underline;">2.1.1 &#8211; Introduction </span></strong><span style="text-decoration: underline;"><br />
</span></p>
<p>Une sauvegarde par RMAN doit avoir (au moins) un <span style="text-decoration: underline;">chemin de destination</span> ou &laquo;&nbsp;channel&nbsp;&raquo; sur (au moins) un<span style="text-decoration: underline;">périphérique physique</span> ou &laquo;&nbsp;device type&nbsp;&raquo;. Les notions rman sont alors celles de CHANNEL ou de DEVICE TYPE.</p>
<p>Un <span style="text-decoration: underline;">CHANNEL</span> rman représente la possibilité de sauvegarder et de paralléliser éventuellement des opérations à travers différents chemins sur différents périphériques en médias. Un channel possède <span style="text-decoration: underline;">DEVICE TYPE</span> qui peut représenter un disque dur (local / distant) ou un périphérique externe (Lecteur LTO, &#8230;).</p>
<p>Dans la plupart des configurations &laquo;&nbsp;modernes&nbsp;&raquo; des serveurs de sauvegardes rman, les canaux de sauvegardes de celles-ci seront associés à de périphériques de type disque (généralement des volumes de baies de disques) qui seront parallèlement sauvegardés par des programmes de sauvegardes de fichiers indépendant des bases de données (TINA, TSM, etc  &#8230;).</p>
<p><span style="text-decoration: underline;">Syntaxe:</span></p>
<pre>CONFIGURE CHANNEL DEVICE TYPE [ DISK | TAPE] [ &lt; option &gt; ]</pre>
<p><span style="text-decoration: underline;">Note: </span>Le channel par défaut de rman est associé à un device type DISK (stokage sur disque dur).</p>
<p><span style="text-decoration: underline;">2.1.2 &#8211; Options de stokage</span></p>
<p>En fonction du type de stockage et du média utilisé, le DBA peut être amenné à découper un jeu de sauvegarde (BACKUP SET) en plusieurs parties (BACKUP PIECE) afin de les segmenter et d&#8217;adapter leur taille à la taille maximale que peut supporter le média associé au DEVICE TYPE (par exemple une K7 LTO3). Cette possibilité est offerte à travers le commutateur <span style="text-decoration: underline;">FORMAT</span>.</p>
<p>Les options de format sont nombreuses, consultez la doc de rman pour en obtenir la liste.</p>
<p>De plus, il est possible de suffixer, à l&#8217;aide du commutateur <span style="text-decoration: underline;">MAXPIECESIZE</span>, le fichier de sauvegarde (backup set / piece) à l&#8217;aide de variables permettant d&#8217;en défini&#8217; l&#8217;unicité, de l&#8217;associer au nom d&#8217;une database ou à son dbid, à un nom de tablesapce, etc.</p>
<p><span style="text-decoration: underline;">Exemple:</span></p>
<pre>CONFIGURE CHANNEL
          DEVICE TYPE DISK
          FORMAT '/data/mabase/sav/%U'
          MAXPIECESIZE 2G;</pre>
<p><span style="text-decoration: underline;">Remarque </span>: Effacer toutes vos commandes de configuration pour revenir à la configuration par défaut est possible avec &#8216;CONFIGURE CHANNEL DEVICE TYPE CLEAR&#8217;</p>
<p><span style="text-decoration: underline;">2.3 &#8211; Politique de conservation des données</span></p>
<p>Il existe deux types de politique de conservation des données sous rman par database à sauvegarder :</p>
<p>a) Redondance de sauvegardes (REDUNDANCY)</p>
<p>b) Nombre de jours de restaurations (WINDOW)</p>
<p>L&#8217;option a) permet de s&#8217;assurer via rman qu&#8217;à une database correspondra toujours un certain <span style="text-decoration: underline;">nombre fixe</span> de sauvegardes <span style="text-decoration: underline;">au minimum. </span>Par exemple, certaines production exige de pouvoir revenir, quel que soit le moment, à deux niveaux de versions antérieur, pour des sauvegardes régulières journalières, ce qui porterait le nombre de redondance de sauvegarde à 3 (versions).</p>
<p>L&#8217;option b) permet de s&#8217;assurer via rman qu&#8217;il sera toujours possible de remonter à j-n, n étant à fixer. Dans cet exemple, le nombre de redondance de sauvegarder n&#8217;a pas d&#8217;interet pourvu que l&#8217;on puisse revenir à la dernière sauvegarde du mois dernier par exemple, ce qui porterait ce paramètre à 30 (jours) environ.</p>
<p>Syntaxe:</p>
<pre>CONFIGURE RETENTION POLICY
[ TO [ RECOVERY OF &lt;n&gt; DAYS | REDUNDANCY &lt;n&gt; ]
| CLEAR ];</pre>
<p><span style="text-decoration: underline;">2.4 &#8211; Sauvegarde automatique des fichiers de contrôles</span></p>
<p>Lorsque vous sauvegardez une database, il est indispensable, hormis les fichiers de données, de sauvegarder un certain nombre d&#8217;éléments dont les fichiers de controles et les fichier d&#8217;initialisation. Cette opération est éffectuée, si vous le souhaitez, automatiquement par rman qui les intégrera aux backup set.</p>
<p>Syntaxe:</p>
<pre>CONFIGURE CONTROLFILE AUTOBACKUP ON;</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmount.com/articles/rman-configuration-elementaire/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installation MySQL Cluster NDB</title>
		<link>http://www.startupmount.com/articles/installation-dun-cluster-mysql-ndb/</link>
		<comments>http://www.startupmount.com/articles/installation-dun-cluster-mysql-ndb/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 14:08:31 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Continuité de service]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[haute disponibilité]]></category>
		<category><![CDATA[ndb]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=177</guid>
		<description><![CDATA[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. Le cluster [...]]]></description>
			<content:encoded><![CDATA[<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.<span id="more-177"></span></p>
<p><strong>1.  Introduction</strong></p>
<p><strong>1.1       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>
<pre>10.20.0.29 (SITSQL01) [ machine physique ]</pre>
</li>
<li>
<pre>10.20.0.30 (SITSQL02) [ machine physique ]</pre>
</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>
<pre>10.20.0.27 [ machine Xen ]</pre>
</li>
<li>
<pre>10.20.0.28 [ machine Xen ]</pre>
</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>
<pre>10.20.0.25  [ machine Xen ]</pre>
</li>
<li>
<pre>10.20.0.26  [ machine Xen ]</pre>
</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>
<pre>Load balance : sql0.site.fr (serveur à utiliser par les applicatifs)</pre>
</li>
<li>
<pre>Nœud 1 : sql1.site.fr</pre>
</li>
</ul>
<ul>
<li>
<pre>Nœud 2 : sql12.site.fr</pre>
</li>
</ul>
<p><a href="http://www.startupmount.com/wp-content/uploads/2011/09/ndb1.jpg" rel="lightbox[177]"><img class="size-full wp-image-184 aligncenter" title="ndb1" src="http://www.startupmount.com/wp-content/uploads/2011/09/ndb1.jpg" alt="" width="442" height="284" /></a></p>
<p><strong>2.  Installation</strong></p>
<p><strong>2.1 Introduction</strong></p>
<p><strong>Les méthodes d’installation sont basées sur l’exploitation des outils d’installation disponibles sur une openSuSE 11.3 (x86_64).</strong></p>
<p><strong>2.2       Les packages nécessaires</strong></p>
<p><span style="text-decoration: underline;">Sur les nœuds MGM</span> :</p>
<p style="padding-left: 30px;">-          libmysqlclient16</p>
<p style="padding-left: 30px;">-          libmysqlclient_r16</p>
<p style="padding-left: 30px;">-          libmysqlclusterclient16</p>
<p style="padding-left: 30px;">-          libmysqlclusterclient_r16</p>
<p style="padding-left: 30px;">-          libmysqld0</p>
<p style="padding-left: 30px;">-          libqt4-sql-mysql</p>
<p style="padding-left: 30px;">-          mysql-cluster-client</p>
<p style="padding-left: 30px;">-          mysql-cluster-ndb-management</p>
<p style="padding-left: 30px;">-          mysql-cluster-ndb-tools</p>
<p><span style="text-decoration: underline;">Sur les nœuds SQL :</span></p>
<p style="padding-left: 30px;">-          libmysqlclient-devel</p>
<p style="padding-left: 30px;">-          libmysqlclient16</p>
<p style="padding-left: 30px;">-          libmysqlclient_r16</p>
<p style="padding-left: 30px;">-          libmysqlclusterclient16</p>
<p style="padding-left: 30px;">-          libmysqlclusterclient_r16</p>
<p style="padding-left: 30px;">-          libmysqlcppconn-devel</p>
<p style="padding-left: 30px;">-          libmysqlcppconn1</p>
<p style="padding-left: 30px;">-          libmysqld-devel</p>
<p style="padding-left: 30px;">-          libmysqld0</p>
<p style="padding-left: 30px;">-          libqt4-sql-mysql</p>
<p style="padding-left: 30px;">-          mysql-cluster</p>
<p style="padding-left: 30px;">-          mysql-cluster-client</p>
<p><span style="text-decoration: underline;">Sur les nœuds NDB :</span></p>
<p style="padding-left: 30px;">-          libmysqlclient16</p>
<p style="padding-left: 30px;">-          libmysqlclient_r16</p>
<p style="padding-left: 30px;">-          libmysqld0</p>
<p style="padding-left: 30px;">-          libqt4-sql-mysql</p>
<p style="padding-left: 30px;">-          mysql-cluster-ndb-storage</p>
<p style="padding-left: 30px;">-          mysql-cluster-ndb-tools</p>
<p style="padding-left: 30px;">-          mysql-community-server</p>
<p style="padding-left: 30px;">-          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><em>-          Cette librairie est écrite en langage C, il convient d’installer gcc ainsi que les headers mySql (package libmysqlcppconn-devel) pour pouvoir la compiler.</em></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><span style="color: #008000;"><strong>gcc -shared lib_mysqludf_udf.c -o lib_mysqludf_udf.so -I /usr/include/mysql</strong></span><strong> </strong></p>
<p>&nbsp;</p>
<p><strong>2- </strong><strong>Installation</strong><strong> </strong></p>
<p>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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 style="padding-left: 30px;">/data</p>
<p style="padding-left: 30px;">/data/mysql</p>
<p style="padding-left: 30px;">/data/mysql/databases</p>
<p style="padding-left: 30px;">/data/mysql/libs   <em>(&lt;= dossier de sauvegarde de l’UDF mysql définie en </em><em>2.3</em><em>)</em></p>
<p style="padding-left: 30px;">/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 style="padding-left: 30px;">10.20.0.27   sql-mgm-01</p>
<p style="padding-left: 30px;">10.20.0.28   sql-mgm-02</p>
<p style="padding-left: 30px;">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>
<pre style="padding-left: 30px;">[client]</pre>
<pre style="padding-left: 30px;">port            = 3306</pre>
<pre style="padding-left: 30px;">socket          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">[mysqld]</pre>
<pre style="padding-left: 30px;">port            = 3306</pre>
<pre style="padding-left: 30px;">socket          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">datadir = /data/mysql/databases</pre>
<pre style="padding-left: 30px;">skip-locking</pre>
<pre style="padding-left: 30px;">key_buffer_size = 16M</pre>
<pre style="padding-left: 30px;">max_allowed_packet = 1M</pre>
<pre style="padding-left: 30px;">table_open_cache = 64</pre>
<pre style="padding-left: 30px;">sort_buffer_size = 512K</pre>
<pre style="padding-left: 30px;">net_buffer_length = 8K</pre>
<pre style="padding-left: 30px;">read_buffer_size = 256K</pre>
<pre style="padding-left: 30px;">read_rnd_buffer_size = 512K</pre>
<pre style="padding-left: 30px;">myisam_sort_buffer_size = 8M</pre>
<pre style="padding-left: 30px;">ndbcluster</pre>
<pre style="padding-left: 30px;">ndb-connectstring=sql-mgm-01sql-mgm-02</pre>
<pre style="padding-left: 30px;">default-storage-engine=ndbcluster</pre>
<pre style="padding-left: 30px;">default-table-type=ndbcluster</pre>
<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 style="padding-left: 30px;">/data</p>
<p style="padding-left: 30px;">/data/mysql</p>
<p style="padding-left: 30px;">/data/mysql/backups  (dossier de stockage des backups des réplicas sur ce nœud, voir 5.2)</p>
<p style="padding-left: 30px;">/data/mysql/datafiles   <em>(dossier de stockage des données des réplicas sur ce noeud)</em></p>
<p style="padding-left: 30px;">/data/mysql/logs <em>(fichiers de logs pour debugging)</em></p>
<p style="padding-left: 30px;"><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>
<pre style="padding-left: 30px;">[mysqld]</pre>
<pre style="padding-left: 30px;">port            = 3306</pre>
<pre style="padding-left: 30px;">socket          = /var/run/mysql/mysql.sock</pre>
<pre style="padding-left: 30px;">datadir = /data/mysql</pre>
<pre style="padding-left: 30px;">skip-locking</pre>
<pre style="padding-left: 30px;">key_buffer_size = 16M</pre>
<pre style="padding-left: 30px;">max_allowed_packet = 1M</pre>
<pre style="padding-left: 30px;">table_open_cache = 64</pre>
<pre style="padding-left: 30px;">sort_buffer_size = 512K</pre>
<pre style="padding-left: 30px;">net_buffer_length = 8K</pre>
<pre style="padding-left: 30px;">read_buffer_size = 256K</pre>
<pre style="padding-left: 30px;">read_rnd_buffer_size = 512K</pre>
<pre style="padding-left: 30px;">myisam_sort_buffer_size = 8M</pre>
<pre style="padding-left: 30px;">[MYSQL_CLUSTER]</pre>
<pre style="padding-left: 30px;">ndb-connectstring=sql-mgm-01,sql-mgm-02</pre>
<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 style="padding-left: 30px;">/data</p>
<p style="padding-left: 30px;">/data/mysql</p>
<p style="padding-left: 30px;">/data/mysql/config</p>
<p style="padding-left: 30px;">/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>
<pre style="padding-left: 30px;">[TCP DEFAULT]</pre>
<pre style="padding-left: 30px;">SendBufferMemory=2M</pre>
<pre style="padding-left: 30px;">ReceiveBufferMemory=2M</pre>
<pre style="padding-left: 30px;">[NDBD DEFAULT]</pre>
<pre style="padding-left: 30px;">NoOfReplicas=2</pre>
<pre style="padding-left: 30px;">DataMemory=3072M</pre>
<pre style="padding-left: 30px;">IndexMemory=3842M</pre>
<pre style="padding-left: 30px;">LockPagesInMainMemory=1</pre>
<pre style="padding-left: 30px;">[NDB_MGMD]</pre>
<pre style="padding-left: 30px;">ID=27</pre>
<pre style="padding-left: 30px;">HostName=10.20.0.27</pre>
<pre style="padding-left: 30px;">[NDB_MGMD]</pre>
<pre style="padding-left: 30px;">ID=28</pre>
<pre style="padding-left: 30px;">HostName=10.20.0.28</pre>
<pre style="padding-left: 30px;">DataDir=/data/mysql/logs</pre>
<pre style="padding-left: 30px;">[NDBD]</pre>
<pre style="padding-left: 30px;">ID=29</pre>
<pre style="padding-left: 30px;">HostName=10.20.0.29</pre>
<pre style="padding-left: 30px;">DataDir=/data/mysql/logs</pre>
<pre style="padding-left: 30px;">FileSystemPath=/data/mysql/datafiles</pre>
<pre style="padding-left: 30px;">FileSystemPathUndoFiles=/data/mysql/undofiles</pre>
<pre style="padding-left: 30px;">BackupDataDir=/data/mysql/backups</pre>
<pre style="padding-left: 30px;">[NDBD]</pre>
<pre style="padding-left: 30px;">ID=30</pre>
<pre style="padding-left: 30px;">HostName=10.20.0.30</pre>
<pre style="padding-left: 30px;">DataDir=/data/mysql/logs</pre>
<pre style="padding-left: 30px;">FileSystemPath=/data/mysql/datafiles</pre>
<pre style="padding-left: 30px;">FileSystemPathUndoFiles=/data/mysql/undofiles</pre>
<pre style="padding-left: 30px;">BackupDataDir=/data/mysql/backups</pre>
<pre style="padding-left: 30px;">[MYSQLD]</pre>
<pre style="padding-left: 30px;">ID=25</pre>
<pre style="padding-left: 30px;">HostName=10.20.0.25</pre>
<pre style="padding-left: 30px;">[MYSQLD]</pre>
<pre style="padding-left: 30px;">ID=26</pre>
<pre style="padding-left: 30px;">HostName=10.20.0.26</pre>
<pre style="padding-left: 30px;">[MYSQLD]</pre>
<pre style="padding-left: 30px;">ID=50</pre>
<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 style="padding-left: 30px;">rcndb_mgmd  init</p>
<p>…</p>
<p>Vérifier avec rcndb_mgmd  status (voir 4.3.1)</p>
<p>-          Sur MGM-02</p>
<p style="padding-left: 30px;">rcndb_mgmd  init</p>
<p>…</p>
<p>Vérifier avec rcndb_mgmd  status (voir 4.3.1)</p>
<p>-          Sur NDB-01</p>
<p style="padding-left: 30px;">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 style="padding-left: 30px;">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 style="padding-left: 30px;">rcmysql   start</p>
<p>…</p>
<p>-          Sur SQL-02</p>
<p style="padding-left: 30px;">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>&nbsp;</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>&nbsp;</p>
<p><strong>4.3       Etat du cluster</strong></p>
<p>&nbsp;</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>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm &gt; show</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Connected to Management Server at: localhost:1186</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Cluster Configuration</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">---------------------</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">[ndbd(<strong>NDB</strong>)]     2 node(s)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">id=29   @10.20.0.29  (mysql-5.1.41 ndb-7.0.13, Nodegroup: 0, Master)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">id=30   @10.20.0.30  (mysql-5.1.41 ndb-7.0.13, Nodegroup: 0)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">[ndb_mgmd(<strong>MGM</strong>)] 2 node(s)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">id=27   @10.20.0.27  (mysql-5.1.41 ndb-7.0.13)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">id=28   @10.20.0.28  (mysql-5.1.41 ndb-7.0.13)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">[<strong>mysqld</strong>(API)]   3 node(s)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">id=25   @10.20.0.25  (mysql-5.1.41 ndb-7.0.13)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">id=26   @10.20.0.26  (mysql-5.1.41 ndb-7.0.13)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;"><em>id=50 (not connected, accepting connect from any host)</em></span></pre>
<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>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm &gt; all report memory</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Node 29: Data usage is 0%(24 32K pages of total 2560)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Node 29: Index usage is 0%(21 8K pages of total 2336)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Node 30: Data usage is 0%(24 32K pages of total 2560)</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Node 30: Index usage is 0%(21 8K pages of total 2336)</span></pre>
<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>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm&gt; all report BackupStatus</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Node 29: Backup not started</span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;">Node 30: Backup not started</span></pre>
<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>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm&gt; &lt;node_id&gt; STOP</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm&gt; &lt;node_id&gt; START</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm&gt; &lt;node_id&gt; STATUS</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm&gt; ALL STOP</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm&gt; ALL START</strong></span></pre>
<pre style="padding-left: 30px;"><span style="color: #008000;"><strong>ndb_mgm&gt; ALL STATUS</strong></span></pre>
<p><strong>5. Sauvegarde et Restauration</strong></p>
<p><strong>5.1 Mode &laquo;&nbsp;SINGLE USER&nbsp;&raquo;</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><span style="color: #008000;"><strong>ndb_mgm –e ‘’ENTER SINGLE USER MODE &lt;ID&gt;’’</strong></span></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><span style="color: #008000;"><strong>ndb_mgm –e ‘’EXIT SINGLE USER MODE’’</strong></span></p>
<p><strong><br />
</strong></p>
<p>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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(&laquo;&nbsp;Intégrité référentielle violée sur TABLEFILLE &#8211;&gt; TABLEPARENT&nbsp;&raquo;);</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 width="756" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="104"><strong>CODE ERREUR</strong></td>
<td valign="top" width="652"><strong>Explication / Solution</strong></td>
</tr>
<tr>
<td valign="top" width="104">157</td>
<td valign="top" width="652">« Could not connect to storage engine »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 valign="top" width="104">1296</td>
<td valign="top" width="652">Impossible de communiquer avec les nœuds NDBFaire un ndm_mgm –e « show »  pour vérifier leur statuts, les démarrer au cas ou</td>
</tr>
<tr>
<td valign="top" width="104"><em>1114</em></td>
<td valign="top" width="652">Nombre d’index max. (non PK) atteintð  Augmenter la valeur  « MaxNoOfOrderedIndexes » + start « init » mode</td>
</tr>
<tr>
<td valign="top" width="104">1005</td>
<td valign="top" width="652">Nombre d’attributs max. atteintð  Augmenter  la valeur de MaxNoOfAttributes + start « init » mode</td>
</tr>
<tr>
<td valign="top" width="104">1478</td>
<td valign="top" width="652">Impossible d’indexer un champ CLOB, BLOB, TEXT, FULLTEXT, LONGTEXTð  Supprimer l’index ou changer le typage du champ</td>
</tr>
<tr>
<td valign="top" width="104">1089</td>
<td valign="top" width="652">Interdiction d’utiliser des préfixes pour les indexes : non supportéð  « UNIQUE KEY » devient « KEY », …</td>
</tr>
<tr>
<td valign="top" width="104">1297</td>
<td valign="top" width="652">Trop d’opérations simultanéesð  Augmenter la valeur de « MaxNoOfConcurrentOperations » + start « init » modeð  Augmenter (peut être) la valeur de « MaxNoOfLocalOperations » + start « init » modeCette 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://www.startupmount.com/articles/installation-dun-cluster-mysql-ndb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fail2Ban : Install et config</title>
		<link>http://www.startupmount.com/articles/fail2ban-install-et-config/</link>
		<comments>http://www.startupmount.com/articles/fail2ban-install-et-config/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 13:40:33 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Systèmes et Applicatifs]]></category>
		<category><![CDATA[fail2ban]]></category>
		<category><![CDATA[flood]]></category>
		<category><![CDATA[imap4]]></category>
		<category><![CDATA[jail2ban]]></category>
		<category><![CDATA[pop3]]></category>
		<category><![CDATA[sécurité]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=172</guid>
		<description><![CDATA[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, …), d’automatiser un ban [...]]]></description>
			<content:encoded><![CDATA[<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><span id="more-172"></span></p>
<h1><strong>1.  Présentation</strong></h1>
<h2><strong>1.1       Introduction</strong></h2>
<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>
<h2><strong>1.2       Prérequis</strong></h2>
<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>
<h1><strong>2.  Installation</strong></h1>
<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>
<pre style="padding-left: 30px;">#! /bin/sh</pre>
<pre style="padding-left: 30px;"># Copyright (c) XXX.</pre>
<pre style="padding-left: 30px;"># All rights reserved.</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;"># Author:XXX</pre>
<pre style="padding-left: 30px;"># Please send feedback to http://sss/</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;"># /etc/init.d/fail2ban</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;">### BEGIN INIT INFO</pre>
<pre style="padding-left: 30px;"># Provides:          fail2ban</pre>
<pre style="padding-left: 30px;"># Required-Start:    $syslog $network $dovecot</pre>
<pre style="padding-left: 30px;"># Required-Stop:</pre>
<pre style="padding-left: 30px;"># Default-Start:     3 5</pre>
<pre style="padding-left: 30px;"># Default-Stop:      0 1 2 6</pre>
<pre style="padding-left: 30px;"># Description:       Fail2Ban Server</pre>
<pre style="padding-left: 30px;">### END INIT INFO</pre>
<pre style="padding-left: 30px;">. /etc/rc.status</pre>
<pre style="padding-left: 30px;"># Reset status of this service</pre>
<pre style="padding-left: 30px;">rc_reset</pre>
<pre style="padding-left: 30px;">case "$1" in</pre>
<pre style="padding-left: 30px;">start)</pre>
<pre style="padding-left: 30px;">echo -n "Starting FAIL2BAN "</pre>
<pre style="padding-left: 30px;">/usr/local/bin/fail2ban-client -v -c /etc/fail2ban start</pre>
<pre style="padding-left: 30px;">echo "Etat des tables "</pre>
<pre style="padding-left: 30px;">/usr/sbin/iptables --list</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">stop)</pre>
<pre style="padding-left: 30px;">echo -n "Stopping FAIL2BAN "</pre>
<pre style="padding-left: 30px;">/usr/local/bin/fail2ban-client -v -c /etc/fail2ban stop</pre>
<pre style="padding-left: 30px;">echo "Etat des iptables "</pre>
<pre style="padding-left: 30px;">/usr/sbin/iptables --list</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">restart)</pre>
<pre style="padding-left: 30px;">$0 stop</pre>
<pre style="padding-left: 30px;">$0 start</pre>
<pre style="padding-left: 30px;">rc_status</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">status)</pre>
<pre style="padding-left: 30px;">echo -n "Statut FAIL2BAN "</pre>
<pre style="padding-left: 30px;">/usr/local/bin/fail2ban-client -v -c /etc/fail2ban status</pre>
<pre style="padding-left: 30px;">echo "Etat des tables "</pre>
<pre style="padding-left: 30px;">/usr/sbin/iptables --list</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">*)</pre>
<pre style="padding-left: 30px;">echo "Usage: $0 {start|stop|restart|status}"</pre>
<pre style="padding-left: 30px;">exit 1</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">esac</pre>
<pre style="padding-left: 30px;">rc_exit</pre>
<p>-          Taper les commandes :</p>
<ul>
<li>
<pre><strong>chmod +x /etc/init.d/fail2ban</strong></pre>
</li>
<li>
<pre><strong>chkconfig    -- add   fail2ban   35 </strong></pre>
</li>
<li>
<pre><strong>ln   –s   /etc.init.f/fail2ban   /usr/sbin/fail2ban</strong></pre>
</li>
</ul>
<p>&nbsp;</p>
<h1><strong>3.  Configuration</strong></h1>
<h2><strong>3.1       Configuration de base</strong></h2>
<h3><strong>3.1.1      Fichier « /etc/fail2ban/fail2ban.conf »</strong></h3>
<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 valign="top" width="255">loglevel = 4</td>
<td valign="top" width="402">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 valign="top" width="255">logtarget = /var/log/fail2ban.log</td>
<td valign="top" width="402">Emplacement du fichier de log de fail2ban</td>
</tr>
<tr>
<td valign="top" width="255">socket = /var/run/fail2ban/fail2ban.sock</td>
<td valign="top" width="402">Emplacement du fichier de socket unix de fail2ban (il faudra créér ce répertoire + chown –R root:root )</td>
</tr>
</tbody>
</table>
<h3><strong>3.1.2      Fichier « /etc/fail2ban/jail.conf »</strong></h3>
<h4><strong>3.1.2.1         Configuration générale</strong></h4>
<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 valign="top" width="262">bantime  = 3600</td>
<td valign="top" width="397">Si on doit bannir une IP, combien de temps reste-t-elle bannie ? (ici 1 heure)</td>
</tr>
<tr>
<td valign="top" width="262">findtime  = 600</td>
<td valign="top" width="397">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 valign="top" width="262">maxretry = 3</td>
<td valign="top" width="397">Maximum de tentatives infructueuses tolérée</td>
</tr>
<tr>
<td valign="top" width="262">backend = auto</td>
<td valign="top" width="397"></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>
<h4><strong>3.1.2.2         Configuration des « JAILS »</strong></h4>
<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 valign="top" width="286"><strong>[ssh-iptables]</strong></td>
<td valign="top" width="355">Nom de la JAIL</td>
</tr>
<tr>
<td valign="top" width="286"><strong>enabled  = true</strong></td>
<td valign="top" width="355">Est-elle pris en compte au démarrage de fail2ban ?</td>
</tr>
<tr>
<td valign="top" width="286"><strong>filter   = sshd</strong></td>
<td valign="top" width="355">Nom du filtre à utiliser pour parser le fichier de log concerné par cette JAIL (voir 3.1.2.3)</td>
</tr>
<tr>
<td valign="top" width="286"><strong>action=</strong><strong>iptables[name=SSH, port=ssh, protocol=tcp]</strong></td>
<td valign="top" width="355">Quelle action doit-on entreprendre en cas de tentative de hack avérée ? (voir 3.1.2.4)</td>
</tr>
<tr>
<td valign="top" width="286"><strong>logpath     = /var/log/auth_sshd.log</strong></td>
<td valign="top" width="355">Fichier de log dans lequel l’authentification sur le serveur sshd doit être tracée pour traquer les failures.</td>
</tr>
<tr>
<td valign="top" width="286"><strong>maxretry = 3</strong></td>
<td valign="top" width="355">Nombre de tentative maximum tolérée sur un intervalle glissant de &lt;findtime&gt; secondes</td>
</tr>
<tr>
<td valign="top" width="286"><em>bantime  = 3600</em></td>
<td valign="top" width="355"><em>Optionnel </em>: Combien de temps en secondes un user banni le restera avant dé-banissement ?</td>
</tr>
<tr>
<td valign="top" width="286"><em>findtime  = 600</em></td>
<td valign="top" width="355"><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>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 valign="top" width="262"><strong>[dovecot]</strong></td>
<td valign="top" width="355">Nom de la jail</td>
</tr>
<tr>
<td valign="top" width="262"><strong>enabled = true</strong></td>
<td valign="top" width="355">Celle-ci doit être active</td>
</tr>
<tr>
<td valign="top" width="262"><strong>filter = dovecot</strong></td>
<td valign="top" width="355">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 valign="top" width="262"><strong>action=iptables[name=dovecot, port=pop3, protocol=tcp]</strong></td>
<td valign="top" width="355">Quelle action doit-on entreprendre en cas de tentative de hack avérée ? (voir 3.1.2.4)</td>
</tr>
<tr>
<td valign="top" width="262"><strong>logpath = /var/log/dovecot.log</strong></td>
<td valign="top" width="355">Fichier de log d’authentification de dovecot</td>
</tr>
<tr>
<td valign="top" width="262"><strong>maxretry = 5</strong></td>
<td valign="top" width="355">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>
<h4><strong>3.1.2.3         Configuration d’un filtre</strong></h4>
<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>-</p>
<pre style="padding-left: 30px;">failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from &lt;HOST&gt;\s*$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from &lt;HOST&gt;\s*$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)sFailed (?:password|publickey) for .* from &lt;HOST&gt;(?: port \d*)?(?: ssh\d*)?$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)sROOT LOGIN REFUSED.* FROM &lt;HOST&gt;\s*$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from &lt;HOST&gt;\s*$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)sUser \S+ from &lt;HOST&gt; not allowed because not listed in AllowUsers$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)sauthentication failure; logname=\S* uid=\S* euid=\S* tty=\S* ruser=\S* rhost=&lt;HOST&gt;(?:\s+user=.*)?\s*$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)srefused connect from \S+ \(&lt;HOST&gt;\)\s*$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)sAddress &lt;HOST&gt; .* POSSIBLE BREAK-IN ATTEMPT!*\s*$</pre>
<pre style="padding-left: 30px;">^%(__prefix_line)sUser \S+ from &lt;HOST&gt; not allowed because none of user's groups are listed in AllowGroups$</pre>
<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>
<pre style="padding-left: 30px;"># Fail2Ban configuration file</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;"># Author: XXX</pre>
<pre style="padding-left: 30px;"># Modified by: XXX</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;"># $Revision: 1 $</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;">[Definition]</pre>
<pre style="padding-left: 30px;"># Option:  failregex</pre>
<pre style="padding-left: 30px;"># Notes.:  regex to match the password failures messages in the logfile. The</pre>
<pre style="padding-left: 30px;">#          host must be matched by a group named "host". The tag "&lt;HOST&gt;" can</pre>
<pre style="padding-left: 30px;">#          be used for standard IP/hostname matching and is only an alias for</pre>
<pre style="padding-left: 30px;">#          (?:::f{4,6}:)?(?P&lt;host&gt;[\w\-.^_]+)</pre>
<pre style="padding-left: 30px;"># Values:  TEXT</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;">#failregex = LOGIN FAILED, .*, ip=\[&lt;HOST&gt;\]$</pre>
<pre style="padding-left: 30px;"># exemple:</pre>
<pre style="padding-left: 30px;"># dovecot: Oct 04 17:59:00 Info: auth(default): pam(contact@hotel-lesvoyageurs.com,86.193.160.20): pam_authenticate() failed: Authentication failure</pre>
<pre style="padding-left: 30px;">#failregex  = pam.*,&lt;HOST&gt;\).*failure</pre>
<pre style="padding-left: 30px;"># exemple:</pre>
<pre style="padding-left: 30px;"># dovecot: Oct 05 15:21:13 Info: auth-worker(default): sql(xaxaxa,192.168.10.19): unknown user</pre>
<pre style="padding-left: 30px;">failregex  = sql.*,&lt;HOST&gt;\).*unknown user</pre>
<pre style="padding-left: 30px;">ignoreregex =</pre>
<pre style="padding-left: 30px;"># Option:  ignoreregex</pre>
<pre style="padding-left: 30px;"># Notes.:  regex to ignore. If this regex matches, the line is ignored.</pre>
<pre style="padding-left: 30px;"># Values:  TEXT</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;">ignoreregex =</pre>
<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>&nbsp;</p>
<h4><strong>3.1.2.4         Configuration d’une action</strong></h4>
<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>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmount.com/articles/fail2ban-install-et-config/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RMAN : Sauvegardes à chaud</title>
		<link>http://www.startupmount.com/articles/rman-sauvegardes-a-chaud/</link>
		<comments>http://www.startupmount.com/articles/rman-sauvegardes-a-chaud/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 13:29:38 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Sauvegardes]]></category>
		<category><![CDATA[archivelog]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[block recover]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[incrémentale]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[rman]]></category>
		<category><![CDATA[sauvegarde]]></category>
		<category><![CDATA[sauvegardes à chaud]]></category>
		<category><![CDATA[until time]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=160</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="../wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /><span id="more-160"></span></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 &laquo;&nbsp;IMAGE COPY&nbsp;&raquo;, ou de gérer l&#8217;ensemble des copies qu&#8217;il éffectue pour vous dans un format propriétaire nommé &laquo;&nbsp;BACKUP SET&nbsp;&raquo;.</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 &laquo;&nbsp;BACKUP PIECES&nbsp;&raquo; 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 &laquo;&nbsp;à chaud&nbsp;&raquo;, 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 &laquo;&nbsp;cohérente&nbsp;&raquo;.</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><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 ? (&laquo;&nbsp;backup set&nbsp;&raquo; 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><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 &laquo;&nbsp;vie&nbsp;&raquo; 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 &laquo;&nbsp;cohérente&nbsp;&raquo; (cad toutes les en-têtes des fichiers sont de même SCN).</p>
<p>Les commutateurs &laquo;&nbsp;PLUS ARCHIVELOG&nbsp;&raquo; 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 &laquo;&nbsp;BACKUP ARCHIVELOG ALL&#8217;&nbsp;&raquo;.</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 &laquo;&nbsp;Enterprise&nbsp;&raquo;.</p>
<p><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><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><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 &laquo;&nbsp;delta&nbsp;&raquo; 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><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://www.startupmount.com/articles/rman-sauvegardes-a-chaud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cluster MySQL HA</title>
		<link>http://www.startupmount.com/articles/cluster-mysql-ha/</link>
		<comments>http://www.startupmount.com/articles/cluster-mysql-ha/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 09:57:54 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Continuité de service]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[drbd]]></category>
		<category><![CDATA[HA]]></category>
		<category><![CDATA[heartbeat]]></category>
		<category><![CDATA[réplication]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=135</guid>
		<description><![CDATA[MySQL propose dans sa suite logicielle, un moteur de Cluster (NDB), mais 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 non clusterisables), on peut même affirmer sans trop mentir que son périmètre fonctionnel est très réduit tant les restrictions sont importantes. Le [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL propose dans sa suite logicielle, un moteur de Cluster (NDB), mais 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 non clusterisables), on peut même affirmer sans trop mentir que son périmètre fonctionnel est très réduit tant les restrictions sont importantes. Le cluster MySQL NDB ne fait donc pas l&#8217;objet de cet article et est présenté dans un autre article.<span id="more-135"></span></p>
<p>Nous avons choisi une deuxième méthode de clusterisation, une solution dite de Haute Disponibilité (Hight Avaliability ou HA) basée sur plusieurs briques applicatives :</p>
<p style="padding-left: 30px;">- Deux serveurs MySQL actif / passif</p>
<p style="padding-left: 30px;">- Réplication de block de disque DRBD</p>
<p style="padding-left: 30px;">- Automatisation de la surveillance et du démarrage auto des processus par HeartBeat</p>
<p style="padding-left: 30px;">- Un serveur MySQL en réplication Master/Slave en secours en cas de corruption de blocks disque</p>
<p>&nbsp;</p>
<h1>1.  Introduction</h1>
<h2>1.1 Quatuor MySQL + DrBD + HeartBeat + Master/Slave</h2>
<h3>1.1.1      Pourquoi un cluster HA au lieu d’un cluster NDB ?</h3>
<h3>1.1.2      Les différentes briques du cluster MySQL HA</h3>
<h4>1.1.2.1         Réplication des données avec « DRBD »</h4>
<p><strong>DRBD</strong> (Data Replication Block Device) est un programme qui permet de faire de la <em>réplication de données au sens « block » d’unité de stockage</em> (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>
<h4>1.1.2.2         Bascule d’un nœud mort vers un nœud vivant avec « HeartBeat »</h4>
<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>
<h4>1.1.2.3         Réplication MySQL native « Master / Slave »</h4>
<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>
<h2>1.2       Le cluster « exemple » :</h2>
<p>Dans ce document, nous allons nous baser sur la configuration du cluster &laquo;&nbsp;XXX&nbsp;&raquo; (Cluster MySQL pour le client &laquo;&nbsp;XXX&nbsp;&raquo; 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 valign="top" width="64">SQL1</td>
<td valign="top" width="115">Primary DRBD</td>
<td valign="top" width="217">192.168.13.98 (bond eth0+eth1)192.168.168.1 (réseau DRBD)192.168.194.55 (réseau backup)</td>
<td valign="top" width="242">login / pass = root / toto</td>
</tr>
<tr>
<td valign="top" width="64">SQL2</td>
<td valign="top" width="115">Secondary DRBD</td>
<td valign="top" width="217">192.168.13.99 (bond eth0+eth1)192.168.168.2 (réseau DRBD)192.168.194.56 (réseau backup)</td>
<td valign="top" width="242">login / pass = root / toto</td>
</tr>
<tr>
<td valign="top" width="64">SQL3</td>
<td valign="top" width="115">Slave MySQL</td>
<td valign="top" width="217">10.20.0.36</td>
<td valign="top" width="242">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>
<h1>2.  Installations et Configurations</h1>
<h2>2.1       Normalisation des filesystems</h2>
<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 valign="top" width="245">/data</td>
<td valign="top" width="393"></td>
</tr>
<tr>
<td valign="top" width="245">/data/downloads</td>
<td valign="top" width="393">Divers objets hors distrib</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql</td>
<td valign="top" width="393"></td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/conf</td>
<td valign="top" width="393">Le fichier de config de MySQL « my.cnf »Un lien sera fait de /etc/my.cnf vers ce fichier.</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/backups</td>
<td valign="top" width="393">Les backups des databases</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/run</td>
<td valign="top" width="393">Le fichier de socket de MySQL</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/datafiles</td>
<td valign="top" width="393"></td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/datafiles/databases</td>
<td valign="top" width="393">Les données des bases de données (MyIsam et InnoDB)</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/datafiles/innodb_default</td>
<td valign="top" width="393">Le tablespace par défaut du moteur InnoDB</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/logs</td>
<td valign="top" width="393"></td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/logs/text</td>
<td valign="top" width="393">Les logs applicatives (pour le debug)</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/logs/binnary</td>
<td valign="top" width="393">Les logs binaires (Redologs)</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/logs/undo</td>
<td valign="top" width="393">Les logs transactionnels (Undologs)</td>
</tr>
<tr>
<td valign="top" width="245">/data/mysql/scripts</td>
<td valign="top" width="393">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>
<h2>2.2       Installation du cluster DRBD</h2>
<h3>2.2.1      Les packages</h3>
<p>Cette installation est basée sur une <strong>openSuSE 11.3 64bits</strong>. Les packages <strong>DRBD</strong> sont présents dans la distrib et installable par YAST:</p>
<p style="padding-left: 30px;">-          drbd-8.3.7-2.5.x86_64</p>
<p style="padding-left: 30px;">-          yast2-drbd-2.13.1-221.2.noarch               (managment par Yast : optionnel)</p>
<p>&nbsp;</p>
<h3>2.2.2      Configuration</h3>
<h4>2.2.2.1         Fichier de configuration principal</h4>
<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>
<h5>A.       DÉTAILS DU FICHIER /ETC/DRBD.CONF :</h5>
<pre style="padding-left: 60px;">global {   usage-count yes;    }</pre>
<pre style="padding-left: 60px;">common {</pre>
<pre style="padding-left: 60px;">protocol C;</pre>
<pre style="padding-left: 60px;">handlers {</pre>
<pre style="padding-left: 60px;">pri-on-incon-degr     "/usr/lib/drbd/notify-pri-on-incon-degr.sh;</pre>
<pre style="padding-left: 60px;">/usr/lib/drbd/notify-emergency-reboot.sh;</pre>
<pre style="padding-left: 60px;">echo b &gt; /proc/sysrq-trigger ;</pre>
<pre style="padding-left: 60px;">reboot -f";</pre>
<pre style="padding-left: 60px;">pri-lost-after-sb     "/usr/lib/drbd/notify-pri-lost-after-sb.sh;</pre>
<pre style="padding-left: 60px;">/usr/lib/drbd/notify-emergency-reboot.sh;</pre>
<pre style="padding-left: 60px;">echo b &gt; /proc/sysrq-trigger ;</pre>
<pre style="padding-left: 60px;">reboot -f";</pre>
<pre style="padding-left: 60px;">local-io-error         "/usr/lib/drbd/notify-io-error.sh;</pre>
<pre style="padding-left: 60px;">/usr/lib/drbd/notify-emergency-shutdown.sh;</pre>
<pre style="padding-left: 60px;">echo o &gt; /proc/sysrq-trigger ;</pre>
<pre style="padding-left: 60px;">halt -f";</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">startup {    }</pre>
<pre style="padding-left: 60px;">disk {</pre>
<pre style="padding-left: 60px;">on-io-error detach; ó Sur une I/O error, on arrête de répliquer !</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">net {</pre>
<pre style="padding-left: 60px;">cram-hmac-alg "sha1";</pre>
<pre style="padding-left: 60px;">shared-secret "drbd-sql";       ó clé de hashage pour la communication</pre>
<pre style="padding-left: 60px;">entre les noeuds</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">syncer {</pre>
<pre style="padding-left: 60px;">rate 800M;                 ó Taux de transfert voulu sur le lien de réplication</pre>
<pre style="padding-left: 60px;">al-extents 257;</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">resource cluster0{                                ó NOM DE NOTRE CLUSTER DRBD</pre>
<pre style="padding-left: 60px;">protocol C;    <span style="text-decoration: underline;">TYPE DE REPLICATION :</span> C ó synchrone</pre>
<pre style="padding-left: 60px;">A ó Asynchrone</pre>
<pre style="padding-left: 60px;">B ó semi synchrone (en mémoire)</pre>
<pre style="padding-left: 60px;">net {</pre>
<pre style="padding-left: 60px;">cram-hmac-alg "sha1";</pre>
<pre style="padding-left: 60px;">shared-secret "drbd-sql"; ó mot de passe sha1</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">on sql-primaire {          ó nom DNS du primary DRBD</pre>
<pre style="padding-left: 60px;">device /dev/drbd0;   ó nom de la partition virtuelle</pre>
<pre style="padding-left: 60px;">disk /dev/sda4;                   ó nom de la partition réelle</pre>
<pre style="padding-left: 60px;">address 192.168.168.1:8888; ó IP et port TCP de réplication DRBD</pre>
<pre style="padding-left: 60px;">meta-disk internal;</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">on sql-secondaire {              ó Pareil sur le secondaire</pre>
<pre style="padding-left: 60px;">device /dev/drbd0;</pre>
<pre style="padding-left: 60px;">disk /dev/sda4;</pre>
<pre style="padding-left: 60px;">address 192.168.168.2:8888;</pre>
<pre style="padding-left: 60px;">meta-disk internal;</pre>
<pre style="padding-left: 60px;">}</pre>
<pre style="padding-left: 60px;">}</pre>
<h6>B.       IMPORTANCE DU FICHIERS /ETC/HOSTS</h6>
<p style="padding-left: 30px;">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 style="padding-left: 30px;">-          Sur le PRIMARY <span style="text-decoration: underline;">comme sur</span> le SECONDARY</p>
<p style="padding-left: 30px;">…</p>
<p style="padding-left: 30px;">192.168.13.98   sql-primaire</p>
<p style="padding-left: 30px;">192.168.13.99   sql-secondaire</p>
<p style="padding-left: 30px;">…</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>&nbsp;</p>
<p><strong><span style="text-decoration: underline;">Méthode à appliquer sur le PRIMARY (uniquement) :</span></strong></p>
<p>&nbsp;</p>
<p style="padding-left: 30px;">1)       fdisk /dev/sda                                                                       on crée la partion de 100Go /dev/sda1</p>
<p style="padding-left: 30px;">2)      drbdadm create-md all                                                       création des metadatas dans la partinion</p>
<p style="padding-left: 30px;">3)      rcdrbd start                                                                              démarrage du démon drbd</p>
<p style="padding-left: 30px;">4)      drbdadm &#8212; &#8211;overwrite-data-of-peer primary all    ceci est le nœud primaire DRBD</p>
<p style="padding-left: 30px;">5)      mkfs.ext3 /dev/drbd0                                                         formatage en préservant les métadonnées</p>
<p><span style="text-decoration: underline;">Remarque :</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>&nbsp;</p>
<p><strong><span style="text-decoration: underline;">Méthode à appliquer sur le SECONDARY (uniquement) :</span></strong></p>
<p>&nbsp;</p>
<p>&nbsp;</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 style="padding-left: 30px;">1)      fdisk /dev/sda                                                                               on crée la partion de 100Go /dev/sda1</p>
<p style="padding-left: 30px;">2)      drbdadm create-md all                                                                              création des metadatas dans la partition</p>
<p style="padding-left: 30px;">3)      rcdrbd start                                                                                     démarrage du démon drbd</p>
<p style="padding-left: 30px;">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>
<pre style="padding-left: 30px;">&gt; cat /proc/drbd</pre>
<pre style="padding-left: 30px;">version: 8.3.7 (api:88/proto:86-92)</pre>
<pre style="padding-left: 30px;">srcversion: 04F43AA72D62F7D4F0CB048</pre>
<pre style="padding-left: 30px;">0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----</pre>
<pre style="padding-left: 30px;">ns:13985900 nr:0 dw:1947208 dr:12043684 al:930 bm:752 lo:1 pe:115</pre>
<pre style="padding-left: 30px;">ua:142 ap:0 ep:1 wo:b oos:101513508</pre>
<pre style="padding-left: 30px;">[=&gt;..................] sync'ed: 12.1% (99132/112756)M</pre>
<pre style="padding-left: 30px;">finish: 0:13:22 speed: 126,520 (108,976) K/sec</pre>
<pre style="padding-left: 30px;">Lorsque la synchronisation sera achevée la commande donnera un message ressemblant à :</pre>
<pre style="padding-left: 30px;">&gt; cat /proc/drbd</pre>
<pre style="padding-left: 30px;">version: 8.3.7 (api:88/proto:86-92)</pre>
<pre style="padding-left: 30px;">srcversion: 04F43AA72D62F7D4F0CB048</pre>
<pre style="padding-left: 30px;">0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----</pre>
<pre style="padding-left: 30px;">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</pre>
<h3>2.2.3      Arrêt / Marche du Cluster DRBD</h3>
<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>
<h4>2.2.3.1         Démararge du CLUSTER DRBD :</h4>
<p>Deux opérations sont à éffectuer :</p>
<p>-          Sur le PRIMARY  (en premier):</p>
<p style="padding-left: 30px;">rcdrbd start</p>
<p style="padding-left: 30px;">mount /dev/drdb0   /data</p>
<p>-          Sur le SECONDARY :</p>
<p style="padding-left: 30px;">rcdrbd  start</p>
<p style="padding-left: 30px;">(pas de montage de /data évidement…)</p>
<p>Arrêt du cluster DRDB :</p>
<p>-          Sur le PRIMARY  (en premier)</p>
<p style="padding-left: 30px;">rcdrbd stop</p>
<p style="padding-left: 30px;">umount /data</p>
<p>-          Sur le SECONDARY</p>
<p style="padding-left: 30px;">rcdrbd stop</p>
<h3>2.2.4      Supervision du cluster DRBD</h3>
<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>
<pre style="padding-left: 30px;">&gt; cat /proc/drbd</pre>
<pre style="padding-left: 30px;">&gt; version: 8.3.7 (api:88/proto:86-92)</pre>
<pre style="padding-left: 30px;">&gt; srcversion: 04F43AA72D62F7D4F0CB048</pre>
<pre style="padding-left: 30px;">&gt; 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----</pre>
<pre style="padding-left: 30px;">&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</pre>
<p>Sur le secondary :</p>
<pre style="padding-left: 30px;">&gt; cat /proc/drbd</pre>
<pre style="padding-left: 30px;">&gt; version: 8.3.7 (api:88/proto:86-92)</pre>
<pre style="padding-left: 30px;">&gt; srcversion: 04F43AA72D62F7D4F0CB048</pre>
<pre style="padding-left: 30px;">&gt; 0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----</pre>
<pre style="padding-left: 30px;">&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</pre>
<p>Avec :</p>
<p style="padding-left: 30px;">RO=Primary/X sur le primaire, Secondary/X sur le secondaire</p>
<p style="padding-left: 30px;">avec X={ Primary | Secondary | DUnknown &lt;= problème ! }</p>
<p style="padding-left: 30px;">CS=état de la connexion réseau de réplication</p>
<p style="padding-left: 30px;">NS=bytes émis</p>
<p style="padding-left: 30px;">NR=bytes reçus</p>
<p style="padding-left: 30px;">DW=données écrites physiquement sur le disque</p>
<p style="padding-left: 30px;">DR=Données lues sur le disque</p>
<h2>2.3       Installation de la réplication MySQL Maitre / Esclave</h2>
<h3>2.3.1      Configuration du maitre</h3>
<p>Activer la journalisation des logs binaires dans /etc/my.cnf :</p>
<pre style="padding-left: 30px;">log-bin</pre>
<pre style="padding-left: 30px;">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 :</pre>
<pre style="padding-left: 30px;">mysql&gt; create user replic identified by replic ;</pre>
<pre style="padding-left: 30px;">mysql&gt; GRANT REPLICATION SLAVE ON *.* TO 'replic'@'%' IDENTIFIED BY 'replic';</pre>
<pre style="padding-left: 30px;">mysql&gt; GRANT SELECT, PROCESS, FILE, SUPER, RELOAD ON *.* TO 'replic'@'%' IDENTIFIED BY 'replic';</pre>
<pre style="padding-left: 30px;">Modifier le fichier de conf global du maitre (/etc/my.cnf)  pour lui indiquer les bases qu’il ne doit pas répliquer :</pre>
<pre style="padding-left: 30px;">…</pre>
<pre style="padding-left: 30px;">binlog-ignore-db = mysql</pre>
<pre style="padding-left: 30px;">binlog-ignore-db = base_a_exclure</pre>
<pre style="padding-left: 30px;">…</pre>
<h3>2.3.2      Configuration de l’esclave</h3>
<h4>2.3.2.1         Modification du fichier de conf global</h4>
<p>Modifier le fichier /etc/my.cnf du SLAVE et ajouter :</p>
<pre style="padding-left: 30px;">server-id           = 10  ó identifiant différent de celui du maitre</pre>
<pre style="padding-left: 30px;">relay-log           =/data/mysql/logs/binary/relaybinlog.rotation</pre>
<pre style="padding-left: 30px;">relay-log-index     =/data/mysql/logs/binary/relaybinlog.index</pre>
<pre style="padding-left: 30px;">relay-log-info-file =/data/mysql/conf/relay-log.info</pre>
<pre style="padding-left: 30px;">master-info-file    =/data/mysql/conf/master.info</pre>
<pre style="padding-left: 30px;">Redémarrer MySQL pour le prendre en compte (« rcmysql restart »)</pre>
<h4>2.3.2.2         Initiation du processus de réplication</h4>
<p>a)      Arreter (éventuellement) le processus ESCLAVE :</p>
<pre style="padding-left: 30px;">Mysql&gt; stop slave ;</pre>
<p>b)      Faire un dump SUR LE MAITRE des bases à restaurer SUR L’ESCLAVE pour initier le processus :</p>
<pre style="padding-left: 30px;">Maitre&gt; mysqldump           -h localhost</pre>
<pre style="padding-left: 30px;">-uroot</pre>
<pre style="padding-left: 30px;">--lock-all-tables</pre>
<pre style="padding-left: 30px;">--master-data óContient les SCN des binarylogs pour l’esclave</pre>
<pre style="padding-left: 30px;">--databases mabase</pre>
<pre style="padding-left: 30px;">--flush-logs</pre>
<pre style="padding-left: 30px;">--add-drop-database --allow-keywords</pre>
<pre style="padding-left: 30px;">--quick</pre>
<pre style="padding-left: 30px;">--complete-insert</pre>
<pre style="padding-left: 30px;">--add-drop-table</pre>
<pre style="padding-left: 30px;">--create-options</pre>
<pre style="padding-left: 30px;">--dump-date</pre>
<pre style="padding-left: 30px;">--triggers --routines --events</pre>
<pre style="padding-left: 30px;">--debug-info</pre>
<pre style="padding-left: 30px;">--verbose</pre>
<pre style="padding-left: 30px;">--comments</pre>
<pre style="padding-left: 30px;">--result-file=mondump.sql</pre>
<p>c) restaurer le dump précédent sur l’esclave</p>
<pre style="padding-left: 30px;">esclave&gt; mysql –uroot –D mabase &lt; mondump.sql</pre>
<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>(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;)</p>
<p>Il faut ensuite informer l’esclave de ces données en tapant :</p>
<pre style="padding-left: 30px;">mysql&gt; change master to</pre>
<pre style="padding-left: 30px;">master_host=    '192.168.13.98',</pre>
<pre style="padding-left: 30px;">master_user=    'replic',</pre>
<pre style="padding-left: 30px;">master_password='replic',</pre>
<pre style="padding-left: 30px;">master_log_file='binarylog.000062',</pre>
<pre style="padding-left: 30px;">master_log_pos= 106;</pre>
<p>Il faut ensuite démarrer le processus de récplication sur l’esclave :</p>
<pre style="padding-left: 30px;">mysql&gt; start slave ;</pre>
<pre style="padding-left: 30px;">mysql&gt; show slave status\G ;</pre>
<h2>2.4       Installation de HeartBeat</h2>
<h3>2.4.1      Présentation</h3>
<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>
<h3>2.4.2      Configuration de /etc/ha.d/ha.cf</h3>
<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>
<pre style="padding-left: 30px;">logfile /var/log/ha.log              fichier de log standard</pre>
<pre style="padding-left: 30px;">debugfile /var/log/ha-debug.log      fichier de log supplémentaire (debug)</pre>
<pre style="padding-left: 30px;">logfacility     local0               facility de syslogd</pre>
<pre style="padding-left: 30px;">keepalive 2                          On teste toutes les 2 secondes l’état des nœuds.</pre>
<pre style="padding-left: 30px;">warntime 8                           On alerte si un nœud ne répond pas durant 8 secondes.</pre>
<pre style="padding-left: 30px;">deadtime 15                          A 15 secondes, on considère que le nœud est mort.</pre>
<pre style="padding-left: 30px;">initdead 30                          Temps de démarrage max toléré avant de diagnostiquer que le nœud est mort.</pre>
<pre style="padding-left: 30px;">mcast bond0 225.0.0.1 694 1 0        cartes réseaux (mcast ou bcast) pour atteindre les HeartBeats</pre>
<pre style="padding-left: 30px;">mcast eth2  225.0.0.1 694 1 0        cartes réseaux (mcast ou bcast) pour atteindre les HeartBeats</pre>
<pre style="padding-left: 30px;">auto_failback off                    Pas de retour arrière automatique, trop dangereux</pre>
<pre style="padding-left: 30px;">node sql-primaire                 quels sont les nœuds composant la ferme HeartBeat ?</pre>
<pre style="padding-left: 30px;">node sql-secondaire               quels sont les nœuds composant la ferme HeartBeat ?</pre>
<pre style="padding-left: 30px;">ping 192.168.13.253                  Chaque nœud doit également pouvoir accèder à la gateway</pre>
<pre style="padding-left: 30px;">pour être caractérisé de « vivant ».</pre>
<pre style="padding-left: 30px;">deadping 5                           si le ping ne répond pas pendant 5 secondes, la cible est considérée comme morte.</pre>
<pre style="padding-left: 30px;">respawn hacluster /usr/lib64/heartbeat/ipfail</pre>
<pre style="padding-left: 30px;">apiauth ipfail gid=haclient uid=hacluster</pre>
<h3>2.4.3      Configuration des resources HA</h3>
<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 /etc/ha.d/haresources.</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>
<pre style="padding-left: 30px;"> …</pre>
<pre style="padding-left: 30px;">otsql-primaire   192.168.13.100    drbddisk::cluster0    Filesystem::/dev/drbd0::/data::ext3    mysql</pre>
<pre style="padding-left: 30px;">…</pre>
<pre style="padding-left: 30px;"><span style="text-decoration: underline;">Découpage :</span></pre>
<pre style="padding-left: 30px;">hostname du primaire actif : otsql-primaire       (ne pas oublier de renseigner les fichiers hosts)</pre>
<pre style="padding-left: 30px;">Action 1 : drbddisk::cluster0</pre>
<pre style="padding-left: 30px;">Action 2 : Filesystem::/dev/drbd0::/data::ext3</pre>
<pre style="padding-left: 30px;">Action 3 : 192.168.13.100</pre>
<pre style="padding-left: 30px;">Action 4 : mysql</pre>
<p><span style="text-decoration: underline;">Explications :</span></p>
<ul>
<li>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)</li>
<li>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.</li>
<li>Action3 : assigne l’adresse IP 192.168.13.100 à une de ses interfaces présente sur ce réseau</li>
<li>Action4 : déclenche le programme /etc/ha.d/resources.d/mysql qui démarre le serveur MySQL sur le nœud nouvellement actif.</li>
</ul>
<h2>2.5       Bascule du cluster : FAIL-OVER / FAIL-BACK</h2>
<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>
<h3>2.5.1      FAIL OVER :</h3>
<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>PRIMARY&gt; rchertbeat stop</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>
<h3>2.5.2      FAIL BACK :</h3>
<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>PRIMARY&gt; rcheartbeat start</p>
<p>(attendre quelques instants par sécurité que heatbeat soit ok)</p>
<p>SECONDARY&gt; rcheartbeat stop</p>
<p>(attendre quelques instants par sécurité pour être sur que le nœud PRIMAIRE a bien pris la main)</p>
<p>SECONDARY&gt; rcheartbeat start ß 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>
<h1>3. Sauvegarde et restauration des données MySQL du CLUSTER</h1>
<h2>3.1       Introduction</h2>
<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>
<h2>3.2       Sauvegarde</h2>
<p>Le script /data/mysql/scripts/sauvegarde_full.sh 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 /data/mysql/backups/</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>
<h2>3.3       Restauration de données</h2>
<h3>3.3.1      Introduction</h3>
<p><span style="text-decoration: underline;">Définition :</span></p>
<p>Une restauration (ou « RESTORE ») 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 « RECOVER ») 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 « skip-networking » 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>-          Restauration totale : 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>-          Restauration partielle sur erreur : (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>-          Restauration partielle après un crash : 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 « partielle » consiste en la restauration totale d’un fichier de sauvegarde (RESTORE) et l’application d’un journal de transactions DDL et DML (RECOVER) jusqu’à un certain point (un numéro de transaction ou une date &amp; heure).</p>
<h3>3.3.2      Restauration totale</h3>
<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>Imaginons dans ce cas que le dump ainsi pointé par l’utilisateur est /data/backups/mondump.sql.</p>
<p>-          Restauration d’une database « MABASE » sauvegarde par le dump « dump_de_ma_base.sql » :</p>
<p>&gt; cd /data/backups/</p>
<p>&gt; mysql  -uroot  &lt;  dump_de_ma_base.sql</p>
<h3>3.3.3      Restauration partielle</h3>
<h4>3.3.3.1         Introduction</h4>
<p>Une restauration « partielle » ou « PITR (PointInTimeRecovery)» consiste en une restauration FULL (RESTORE) et en l’application des instructions DDL et DML (RECOVER) 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 « binary logs ».</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>mysqlbinlog 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>
<h4>3.3.3.2         Restauration totale au plus près d’avant un crash</h4>
<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 style="padding-left: 30px;">- 1-         Fermer l’accès du serveur aux utilisateurs (Ajouter « skip-networking » dans /etc/my.cnf + rcmysql restart)</p>
<p style="padding-left: 30px;">- 2-         Détruire la database (&gt; mysql –uroot   -e ‘drop database dbname ; ’)</p>
<p style="padding-left: 30px;"> - 3-        Restaurer le dump SQL (au sens de mysqldump) le plus récent possible. (&gt; mysql  –uroot   &lt;  /data/mysql/backups/dump_dbname_YYYYMMDD_HHIISS.sql)</p>
<p style="padding-left: 30px;">- 4-         Appliquer les ordres DDL et DML des journaux binaires à partir de la date de génération du dump</p>
<pre style="padding-left: 60px;">&gt; mysqlbinlog  /data/mysql/logs/binary/binarylog.*</pre>
<pre style="padding-left: 60px;">--database=dbname ß recover restreint à la database « dbname »</pre>
<pre style="padding-left: 60px;">--start-datetime="2010-12-29 09:57:23" ß date de fin du dump</pre>
<pre style="padding-left: 60px;">--to-last-log ß jusqu’à la fin du dernier log binaire disponible</pre>
<pre style="padding-left: 60px;">--result-file=/tmp/ordres_a_rejouer.sql</pre>
<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>&gt; mysql  -uroot   &lt;   /tmp/ordres_a_rejouer.sql</p>
<p>-          Ouvrir l’accès du serveur aux utilisateurs</p>
<p>Commenter « skip-networking » dans /etc/my.cnf + rcmysql restart</p>
<p>&nbsp;</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>
<pre style="padding-left: 30px;"><strong>-- CHANGE MASTER TO MASTER_LOG_FILE='binarylog.000547', MASTER_LOG_POS=106;</strong></pre>
<p>Ici, l’ordre de recover serait :</p>
<pre style="padding-left: 30px;">mysqlbinlog  /data/mysql/logs/binary/binarylog.*</pre>
<pre style="padding-left: 30px;">--database=dbname</pre>
<pre style="padding-left: 30px;">--start-position  ="107"</pre>
<pre style="padding-left: 30px;">--to-last-log</pre>
<pre style="padding-left: 30px;">--result-file=/tmp/ordres_a_rejouer.sql</pre>
<p>&nbsp;</p>
<h4>3.3.3.3         Restauration totale, Recouvrement partiel (PITR)</h4>
<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 style="padding-left: 30px;"> 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 style="padding-left: 30px;">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=&nbsp;&raquo;2010-12-29 11:59:00&#8243; »</p>
<p style="padding-left: 30px;">mysqlbinlog</p>
<p style="padding-left: 30px;">/data/mysql/logs/binary/binarylog.*</p>
<p style="padding-left: 30px;">&#8211;database=dbname</p>
<p style="padding-left: 30px;">&#8211;start-position  =&nbsp;&raquo;107&#8243;</p>
<p style="padding-left: 30px;">&#8211;end-datetime=&nbsp;&raquo;2010-12-29 11:59:00&#8243;</p>
<p style="padding-left: 30px;">&#8211;result-file=/tmp/ordres_a_rejouer.sql</p>
<p style="padding-left: 30px;">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 style="padding-left: 30px;">L’utilisateur vous indique que un ordre « drop table ma_table » a été passé par erreur, provoquant la catastrophe qui a suivi.</p>
<p style="padding-left: 30px;">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 style="padding-left: 30px;">mysqlbinlog binarylog.* | grep -B 5 -i &laquo;&nbsp;DROP TABLE MA_TABLE&nbsp;&raquo;</p>
<p style="padding-left: 30px;">&#8230; (5 lignes &#8216;B&#8217;efore)</p>
<p style="padding-left: 30px;">&gt; at 2627</p>
<p style="padding-left: 30px;">&gt; 101228 16:39:09 server id 1  end_log_pos 2654</p>
<p style="padding-left: 30px;">&gt; drop table matable</p>
<p style="padding-left: 30px;">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 style="padding-left: 30px;">mysqlbinlog</p>
<p style="padding-left: 30px;">/data/mysql/logs/binary/binarylog.*</p>
<p style="padding-left: 30px;">&#8211;database=dbname</p>
<p style="padding-left: 30px;">&#8211;start-position  =&nbsp;&raquo;107&#8243;</p>
<p style="padding-left: 30px;">&#8211;stop-position=&nbsp;&raquo;2654&#8243;</p>
<p style="padding-left: 30px;">&#8211;result-file=/tmp/ordres_a_rejouer.sql</p>
<p style="padding-left: 30px;">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>
<h1></h1>
<h1>4.  Annexes</h1>
<h2>4.1       Fichiers de configuration MySQL</h2>
<h3>4.1.1      Configuration sur les nœuds du cluster DRBD</h3>
<p><strong>/etc/my.cnf</strong></p>
<pre style="padding-left: 30px;">[client]</pre>
<pre style="padding-left: 30px;">port                            = 3306</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">[mysqld]</pre>
<pre style="padding-left: 30px;">port                            = 3306</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">server-id                       =1</pre>
<pre style="padding-left: 30px;">skip-external-locking</pre>
<pre style="padding-left: 30px;">skip-ndbcluster</pre>
<pre style="padding-left: 30px;">default-storage-engine=INNODB</pre>
<pre style="padding-left: 30px;"># LOGGING #</pre>
<pre style="padding-left: 30px;">log_error                       = /data/mysql/logs/text/error.log</pre>
<pre style="padding-left: 30px;">general_log                     = ON</pre>
<pre style="padding-left: 30px;">general_log_file                = /data/mysql/logs/text/general_log_file.log</pre>
<pre style="padding-left: 30px;">log_slow_queries                = ON</pre>
<pre style="padding-left: 30px;">slow_query_log_file             = /data/mysql/logs/text/slow_queries.log</pre>
<pre style="padding-left: 30px;">long_query_time                 = 4</pre>
<pre style="padding-left: 30px;">binlog_format                   = ROW</pre>
<pre style="padding-left: 30px;">max_binlog_size                 = 100M</pre>
<pre style="padding-left: 30px;">log_bin_index                   = /data/mysql/logs/binary/index.log</pre>
<pre style="padding-left: 30px;">log-bin                         = /data/mysql/logs/binary/binarylog.rotation</pre>
<pre style="padding-left: 30px;">expire_logs_days                = 15</pre>
<pre style="padding-left: 30px;">binlog-ignore-db                = mysql</pre>
<pre style="padding-left: 30px;">binlog-ignore-db                = test</pre>
<pre style="padding-left: 30px;"># Parametrages myISAM #</pre>
<pre style="padding-left: 30px;">datadir                         = /data/mysql/datafiles/databases</pre>
<pre style="padding-left: 30px;">key_buffer_size                 = 16M</pre>
<pre style="padding-left: 30px;">max_allowed_packet              = 1M</pre>
<pre style="padding-left: 30px;">table_open_cache                = 64</pre>
<pre style="padding-left: 30px;">sort_buffer_size                = 512K</pre>
<pre style="padding-left: 30px;">net_buffer_length               = 8K</pre>
<pre style="padding-left: 30px;">read_buffer_size                = 256K</pre>
<pre style="padding-left: 30px;">read_rnd_buffer_size            = 512K</pre>
<pre style="padding-left: 30px;">myisam_sort_buffer_size         = 8M</pre>
<pre style="padding-left: 30px;"># Parametrage InnoDB #</pre>
<pre style="padding-left: 30px;">innodb_data_home_dir            = /data/mysql/datafiles/innodb_default</pre>
<pre style="padding-left: 30px;">innodb_data_file_path           = ibdata01:50M:autoextend</pre>
<pre style="padding-left: 30px;">innodb_file_per_table           = 1</pre>
<pre style="padding-left: 30px;">innodb_log_group_home_dir       = /data/mysql/logs/undo</pre>
<pre style="padding-left: 30px;">innodb_buffer_pool_size        = 8192M</pre>
<pre style="padding-left: 30px;">innodb_additional_mem_pool_size= 2M</pre>
<pre style="padding-left: 30px;">[safe_mysqld]</pre>
<pre style="padding-left: 30px;">log-error                       = /data/mysql/logs/text/mysqld.log</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">[mysqldump]</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">quick</pre>
<pre style="padding-left: 30px;">max_allowed_packet              = 16M</pre>
<pre style="padding-left: 30px;">[mysql]</pre>
<pre style="padding-left: 30px;">no-auto-rehash</pre>
<pre style="padding-left: 30px;">[myisamchk]</pre>
<pre style="padding-left: 30px;">key_buffer_size                 = 20M</pre>
<pre style="padding-left: 30px;">sort_buffer_size                = 20M</pre>
<pre style="padding-left: 30px;">read_buffer                     = 2M</pre>
<pre style="padding-left: 30px;">write_buffer                    = 2M</pre>
<pre style="padding-left: 30px;">[mysqlhotcopy]</pre>
<pre style="padding-left: 30px;">interactive-timeout</pre>
<pre style="padding-left: 30px;">[mysqld_multi]</pre>
<pre style="padding-left: 30px;">mysqld                          = /usr/bin/mysqld_safe</pre>
<pre style="padding-left: 30px;">mysqladmin                      = /usr/bin/mysqladmin</pre>
<pre style="padding-left: 30px;">log                             = /data/mysql/logs/text/mysqld_multi.log</pre>
<h4>4.1.2      Sur le serveur MySQL SLAVE</h4>
<p><strong>/etc/my.cnf</strong></p>
<pre style="padding-left: 30px;">[client]</pre>
<pre style="padding-left: 30px;">port                            = 3306</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">[mysqld]</pre>
<pre style="padding-left: 30px;">port                            = 3306</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">server-id                       = 10</pre>
<pre style="padding-left: 30px;">skip-external-locking</pre>
<pre style="padding-left: 30px;">default-storage-engine=INNODB</pre>
<pre style="padding-left: 30px;">log_error                       = /data/mysql/logs/text/error.log</pre>
<pre style="padding-left: 30px;">general_log                     = ON</pre>
<pre style="padding-left: 30px;">general_log_file                = /data/mysql/logs/text/general_log_file.log</pre>
<pre style="padding-left: 30px;">slow_query_log                  = ON</pre>
<pre style="padding-left: 30px;">slow_query_log_file             = /data/mysql/logs/text/slow_queries.log</pre>
<pre style="padding-left: 30px;">long-query-time                 = 1</pre>
<pre style="padding-left: 30px;">relay-log                       =/data/mysql/logs/binary/relaybinlog.rotation</pre>
<pre style="padding-left: 30px;">relay-log-index                 =/data/mysql/logs/binary/relaybinlog.index</pre>
<pre style="padding-left: 30px;">relay-log-info-file             =/data/mysql/conf/relay-log.info</pre>
<pre style="padding-left: 30px;">master-info-file                =/data/mysql/conf/master.info</pre>
<pre style="padding-left: 30px;">datadir                         = /data/mysql/datafiles/databases</pre>
<pre style="padding-left: 30px;">key_buffer_size                 = 16M</pre>
<pre style="padding-left: 30px;">max_allowed_packet              = 1M</pre>
<pre style="padding-left: 30px;">table_open_cache                = 64</pre>
<pre style="padding-left: 30px;">sort_buffer_size                = 512K</pre>
<pre style="padding-left: 30px;">net_buffer_length               = 8K</pre>
<pre style="padding-left: 30px;">read_buffer_size                = 256K</pre>
<pre style="padding-left: 30px;">read_rnd_buffer_size            = 512K</pre>
<pre style="padding-left: 30px;">myisam_sort_buffer_size         = 8M</pre>
<pre style="padding-left: 30px;">innodb_data_home_dir            = /data/mysql/datafiles/innodb_default</pre>
<pre style="padding-left: 30px;">innodb_data_file_path           = ibdata01:50M:autoextend</pre>
<pre style="padding-left: 30px;">innodb_file_per_table           = 1</pre>
<pre style="padding-left: 30px;">innodb_log_group_home_dir       = /data/mysql/logs/undo</pre>
<pre style="padding-left: 30px;">[safe_mysqld]</pre>
<pre style="padding-left: 30px;">log-error                       = /data/mysql/logs/text/mysqld.log</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">[mysqldump]</pre>
<pre style="padding-left: 30px;">socket                          = /data/mysql/run/mysql.sock</pre>
<pre style="padding-left: 30px;">quick</pre>
<pre style="padding-left: 30px;">max_allowed_packet              = 16M</pre>
<pre style="padding-left: 30px;">[mysql]</pre>
<pre style="padding-left: 30px;">no-auto-rehash</pre>
<pre style="padding-left: 30px;">[myisamchk]</pre>
<pre style="padding-left: 30px;">key_buffer_size                 = 20M</pre>
<pre style="padding-left: 30px;">sort_buffer_size                = 20M</pre>
<pre style="padding-left: 30px;">read_buffer                     = 2M</pre>
<pre style="padding-left: 30px;">write_buffer                    = 2M</pre>
<pre style="padding-left: 30px;">[mysqlhotcopy]</pre>
<pre style="padding-left: 30px;">interactive-timeout</pre>
<pre style="padding-left: 30px;">[mysqld_multi]</pre>
<pre style="padding-left: 30px;">mysqld                          = /usr/bin/mysqld_safe</pre>
<pre style="padding-left: 30px;">mysqladmin                      = /usr/bin/mysqladmin</pre>
<pre style="padding-left: 30px;">log                             = /data/mysql/logs/text/mysqld_multi.log</pre>
<h3>4.2       Fichiers de configuration DRBD</h3>
<p><strong>/etc/drbd.conf</strong></p>
<pre style="padding-left: 30px;">global {</pre>
<pre style="padding-left: 30px;">usage-count yes;</pre>
<pre style="padding-left: 30px;"># minor-count dialog-refresh disable-ip-verification</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">common {</pre>
<pre style="padding-left: 30px;">protocol C;</pre>
<pre style="padding-left: 30px;">handlers {</pre>
<pre style="padding-left: 30px;">pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b &gt; /proc/sysrq-trigger ; reboot -f";</pre>
<pre style="padding-left: 30px;">pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b &gt; /proc/sysrq-trigger ; reboot -f";</pre>
<pre style="padding-left: 30px;">local-io-error "/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o &gt; /proc/sysrq-trigger ; halt -f"; # fence-peer "/usr/lib/drbd/crm-fence-peer.sh";</pre>
<pre style="padding-left: 30px;"># split-brain "/usr/lib/drbd/notify-split-brain.sh root";</pre>
<pre style="padding-left: 30px;"># out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root";</pre>
<pre style="padding-left: 30px;"># before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k";</pre>
<pre style="padding-left: 30px;"># after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">startup {</pre>
<pre style="padding-left: 30px;"># wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb;</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">disk {</pre>
<pre style="padding-left: 30px;"># on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes</pre>
<pre style="padding-left: 30px;"># no-disk-drain no-md-flushes max-bio-bvecs</pre>
<pre style="padding-left: 30px;">on-io-error detach;</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">net {</pre>
<pre style="padding-left: 30px;"># sndÃ¢f-size rcvbuf-size timeout connect-int ping-int ping-timeout max-buffers</pre>
<pre style="padding-left: 30px;"># max-epoch-size ko-count allow-two-primaries cram-hmac-alg shared-secret</pre>
<pre style="padding-left: 30px;">cram-hmac-alg "sha1";</pre>
<pre style="padding-left: 30px;">shared-secret "drbd-sql";</pre>
<pre style="padding-left: 30px;"># after-sb-0pri after-sb-1pri after-sb-2pri data-integrity-alg no-tcp-cork</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">syncer {</pre>
<pre style="padding-left: 30px;"># rate after al-extents use-rle cpu-mask verify-alg csums-alg</pre>
<pre style="padding-left: 30px;">rate 800M;</pre>
<pre style="padding-left: 30px;">al-extents 257;</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">resource cluster0{</pre>
<pre style="padding-left: 30px;">protocol C;</pre>
<pre style="padding-left: 30px;">net {</pre>
<pre style="padding-left: 30px;">cram-hmac-alg "sha1";</pre>
<pre style="padding-left: 30px;">shared-secret "drbd-sql";</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">on sql-primaire {</pre>
<pre style="padding-left: 30px;">device /dev/drbd0;</pre>
<pre style="padding-left: 30px;">disk /dev/sda4;</pre>
<pre style="padding-left: 30px;">address 192.168.168.1:8888;</pre>
<pre style="padding-left: 30px;">meta-disk internal;</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">on sql-secondaire {</pre>
<pre style="padding-left: 30px;">device /dev/drbd0;</pre>
<pre style="padding-left: 30px;">disk /dev/sda4;</pre>
<pre style="padding-left: 30px;">address 192.168.168.2:8888;</pre>
<pre style="padding-left: 30px;">meta-disk internal;</pre>
<pre style="padding-left: 30px;">}</pre>
<pre style="padding-left: 30px;">}</pre>
<h2>4.3       Fichiers de configuration de HeartBeat</h2>
<p><strong>/etc/ha.d/ha.cf</strong></p>
<pre style="padding-left: 30px;">debugfile /var/log/ha-debug.log</pre>
<pre style="padding-left: 30px;">logfile /var/log/ha.log</pre>
<pre style="padding-left: 30px;">logfacility     local0</pre>
<pre style="padding-left: 30px;">keepalive 2</pre>
<pre style="padding-left: 30px;">deadtime 15</pre>
<pre style="padding-left: 30px;">warntime 8</pre>
<pre style="padding-left: 30px;">initdead 30</pre>
<pre style="padding-left: 30px;"># interfaces reseaux en multicast pour envoyer les battements de coeur</pre>
<pre style="padding-left: 30px;">mcast bond0 225.0.0.1 694 1 0</pre>
<pre style="padding-left: 30px;">mcast eth2  225.0.0.1 694 1 0</pre>
<pre style="padding-left: 30px;"># pas de retour-arriere automatique en cas de panne, trop dangereux</pre>
<pre style="padding-left: 30px;">auto_failback off</pre>
<pre style="padding-left: 30px;"># quels sont les noeuds concernes par le cluster heartbeat</pre>
<pre style="padding-left: 30px;">node sql-primaire</pre>
<pre style="padding-left: 30px;">node sql-secondaire</pre>
<pre style="padding-left: 30px;"># on verifie que le host peut joindre l'interface publique</pre>
<pre style="padding-left: 30px;">ping 192.168.13.253</pre>
<pre style="padding-left: 30px;">deadping 5</pre>
<pre style="padding-left: 30px;">respawn hacluster /usr/lib64/heartbeat/ipfail</pre>
<pre style="padding-left: 30px;">apiauth ipfail gid=haclient uid=hacluster</pre>
<p><strong>/etc/ha.d/haresources.cf</strong></p>
<pre style="padding-left: 30px;"> otsql-primaire drbddisk::cluster0 Filesystem::/dev/drbd0::/data::ext3 192.168.13.100 mysql</pre>
<pre style="padding-left: 30px;"> /etc/ha.d/resource.d/mysql (non présent après l’installation)</pre>
<pre style="padding-left: 30px;"></pre>
<pre style="padding-left: 30px;">#!/bin/bash</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;"># This script is inteded to be used as resource script by heartbeat</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;"># Mar 2006 by Monty Taylor</pre>
<pre style="padding-left: 30px;">#</pre>
<pre style="padding-left: 30px;">###</pre>
<pre style="padding-left: 30px;">. /etc/ha.d/shellfuncs</pre>
<pre style="padding-left: 30px;">case "$1" in</pre>
<pre style="padding-left: 30px;">start)</pre>
<pre style="padding-left: 30px;">res=`/etc/init.d/mysql start`</pre>
<pre style="padding-left: 30px;">ret=$?</pre>
<pre style="padding-left: 30px;">ha_log $res</pre>
<pre style="padding-left: 30px;">exit $ret</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">stop)</pre>
<pre style="padding-left: 30px;">res=`/etc/init.d/mysql stop`</pre>
<pre style="padding-left: 30px;">ret=$?</pre>
<pre style="padding-left: 30px;">ha_log $res</pre>
<pre style="padding-left: 30px;">exit $ret</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">status)</pre>
<pre style="padding-left: 30px;">if [[ `ps -ef | grep '[m]ysqld'` &gt; 1 ]] ; then</pre>
<pre style="padding-left: 30px;">echo "running"</pre>
<pre style="padding-left: 30px;">else</pre>
<pre style="padding-left: 30px;">echo "stopped"</pre>
<pre style="padding-left: 30px;">fi</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">*)</pre>
<pre style="padding-left: 30px;">echo "Usage: mysql {start|stop|status}"</pre>
<pre style="padding-left: 30px;">exit 1</pre>
<pre style="padding-left: 30px;">;;</pre>
<pre style="padding-left: 30px;">esac</pre>
<pre style="padding-left: 30px;">exit 0</pre>
<p>&nbsp;</p>
<p><strong><span style="text-decoration: underline;">CopyLeft:</span></strong></p>
<p><strong>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.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmount.com/articles/cluster-mysql-ha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Partitions Multipath</title>
		<link>http://www.startupmount.com/articles/redimensionner-une-partition-multipath/</link>
		<comments>http://www.startupmount.com/articles/redimensionner-une-partition-multipath/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 09:44:29 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Systèmes et Applicatifs]]></category>
		<category><![CDATA[baie de disque]]></category>
		<category><![CDATA[eva]]></category>
		<category><![CDATA[fdisk]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[multipath]]></category>
		<category><![CDATA[parted]]></category>
		<category><![CDATA[partition]]></category>
		<category><![CDATA[qparted]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=129</guid>
		<description><![CDATA[Le partitionnement est une chose délicate et l&#8217;erreur de manipulation ou de compréhension ne pardonne pas. Il est fréquent d&#8217;avoir à redimensionner une partition dont la taille s&#8217;avère insuffisante au fil du temps, ou au contraire dont celle ci a été surdimensionnée. Si la manipulation peut s&#8217;avérer classique, elle représente un danger dans un environnement HA Multipath, et [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Le partitionnement est une chose délicate et l&#8217;erreur de manipulation ou de compréhension ne pardonne pas.</p>
<p style="text-align: justify;">Il est fréquent d&#8217;avoir à redimensionner une partition dont la taille s&#8217;avère insuffisante au fil du temps, ou au contraire dont celle ci a été surdimensionnée. Si la manipulation peut s&#8217;avérer classique, elle représente un danger dans un environnement HA Multipath, et tous les outils classiques ne sont pas utilisables (fdisk, diskdruid, etc).</p>
<p style="text-align: justify;"><span id="more-129"></span></p>
<p style="text-align: justify;"><span style="text-decoration: underline;">1. Redimensionnement d’une partition MULTIPATH sur LINUX</span></p>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste" style="text-align: justify;"><span style="text-decoration: underline;">1.1 Introduction</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste" style="text-align: justify;">Dans cet exemple, nous partons sur une base Linux REDHAT.</div>
<div style="text-align: justify;">La baie de disque utilisée est une HP EVA 5000</div>
<div id="_mcePaste" style="text-align: justify;">Une partition existante doit être redimensionnée, le principe est simple :</div>
<div id="_mcePaste" style="text-align: justify;">- Redimensionnement de la structure du disque de la baie</div>
<div id="_mcePaste" style="text-align: justify;">- Destruction de la partition OS</div>
<div id="_mcePaste" style="text-align: justify;">- Re-Création de la partition OS (avec les nouvelles valeurs)</div>
<div id="_mcePaste" style="text-align: justify;">- Redimensionement OS du FileSystem au x dimensions de la nouvelle partition</div>
<div id="_mcePaste" style="text-align: justify;">Tout ceci se fait offline.</div>
<div id="_mcePaste" style="text-align: justify;"><span style="text-decoration: underline;">1.2 Méthodologie</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;">1.2.1 repérer le nom de partition a agrandir</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste" style="text-align: justify;">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" style="text-align: justify;"><span style="text-decoration: underline;">1.2.2 Reperer le UUID du nom de partition (au sens baie de disque) :</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste" style="text-align: justify;">multipathd -k</div>
<div id="_mcePaste" style="text-align: justify;">multipathd&gt; show multipaths</div>
<div id="_mcePaste" style="text-align: justify;">multipathd&gt; mpath7 dm-0  3600508b4000aef990000a00000110000</div>
<div id="_mcePaste" style="text-align: justify;">multipathd&gt; mpath8 dm-1  3600508b4000aef990000a00000150000 &lt;== UUID</div>
<div id="_mcePaste" style="text-align: justify;">multipathd&gt; mpath3 dm-2  3600508b4000aef990000a00000190000</div>
<div id="_mcePaste" style="text-align: justify;">multipathd&gt; mpath9 dm-3  3600508b4000aef990000a00000230000</div>
<div id="_mcePaste" style="text-align: justify;">&#8230;</div>
<div id="_mcePaste" style="text-align: justify;">multipathd&gt; mpath1 dm-5  3600508b4000aef990000800000300000</div>
<div id="_mcePaste" style="text-align: justify;">multipathd&gt; mpath2 dm-6  3600508b4000aef990000800000350000</div>
<div style="text-align: justify;"><span style="text-decoration: underline;">1.2.3 Agrandir la LUN avec le CommandView EVA (baie HP nuiquement)</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste" style="text-align: justify;">Se connecter en RDP sur le superviseur de la baie.</div>
<div id="_mcePaste" style="text-align: justify;">Lancer une console Internet Explorer sur https://localhost:2372/Login</div>
<div id="_mcePaste" style="text-align: justify;">Se connecter avec les login/password de la machine  locale (généralement Administrator /</div>
<div id="_mcePaste" style="text-align: justify;">password).</div>
<div id="_mcePaste" style="text-align: justify;">Cliquer dans le TreeView de gauche jusqu’à « Virtual Disk \ &lt; dimension folder&gt; \ VirtalDiskName&gt; »</div>
<div id="_mcePaste" style="text-align: justify;">Sous l’onglet « Capacity », modifier en l’augmentant, la valeur « Requested », et cliquer sur « Apply »</div>
<div style="text-align: justify;"><span style="text-decoration: underline;">1.2.4 demonter la partition</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div style="text-align: justify;">umount /dev/mapper/mpath8p1</div>
<div style="text-align: justify;"><span style="text-decoration: underline;">1.2.5 Reparer le fs</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div style="text-align: justify;">e2fsck -f /dev/mapper/mpath8p1</div>
<div style="text-align: justify;"><span style="text-decoration: underline;">1.2.6 Détruire la partition et la recreer aux maximum avec &laquo;&nbsp;parted&nbsp;&raquo; (car multipath)</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<pre>parted /dev/mapper/mpath8
(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://www.startupmount.com/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 style="text-align: justify;"><span style="text-decoration: underline;">Remarque</span>: Vous ne devez surtout pas utiliser fdisk (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.</p>
<div style="text-align: justify;"><span style="text-decoration: underline;">1.2.7 Etendre le filesystem au maximum de la partition</span></div>
<div style="text-align: justify;"><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 style="text-align: justify;"><span style="text-decoration: underline;">1.2.8 Monter la partition et verifier l&#8217;espace utilisable</span></div>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div id="_mcePaste" style="text-align: justify;">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 &lt;== ok !! On ne démissionne pas aujourd'hui!
/dev/mapper/mpath9p1   50G  533M   47G   2% /DATA/ctltemp
/dev/mapper/mpath12p1</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmount.com/articles/redimensionner-une-partition-multipath/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serveur de logs central</title>
		<link>http://www.startupmount.com/articles/serveur-de-logs-central/</link>
		<comments>http://www.startupmount.com/articles/serveur-de-logs-central/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 09:36:46 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Systèmes et Applicatifs]]></category>
		<category><![CDATA[centralisation]]></category>
		<category><![CDATA[event id]]></category>
		<category><![CDATA[event manager]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[rsyslog]]></category>
		<category><![CDATA[serveur de logs]]></category>
		<category><![CDATA[syslog]]></category>
		<category><![CDATA[syslog-ng]]></category>
		<category><![CDATA[windows event]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=124</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 console unique 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 superviseur Nagios pour une vue parfaite des resources de l&#8217;entreprise.</p>
<p><span id="more-124"></span></p>
<p><span style="text-decoration: underline;">1) Introduction</span></p>
<p><span style="text-decoration: underline;"><br />
</span></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 SYSLOG (qui se décline en plusieurs normes) et WindowsEvent. 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>Exemple de réalisation web pour l&#8217;entreprise XXX :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/log.jpg" rel="lightbox[124]"><img title="log" src="http://cx.cx/wp-content/uploads/2011/02/log-300x178.jpg" alt="" width="300" height="178" /></a></p>
<p>&nbsp;</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>- RSYSLOG</p>
<p>- MYSQL community edition</p>
<p>- php 5.x + module php_mysql</p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;">2) Les serveurs au format SYSLOG</span></p>
<p><span style="text-decoration: underline;"><br />
</span></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 /etc/rsyslog.conf.</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>mail.info               /var/log/mail.info
mail.warning            @@logserver:514
mail.err                @@logserver:514</pre>
<pre> if      ($programname != 'postfix') \
then    @@logserver:514
&amp;       ~</pre>
<p>Dans cet exemple, le serveur &laquo;&nbsp;logserver&nbsp;&raquo; 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 UDP (port 514 standard) de tous les messages syslog que reçoit le serveur Rsyslog local de ce serveur, ceci pour tous les messages de la facility &laquo;&nbsp;mail&nbsp;&raquo; et la criticité &laquo;&nbsp;warning&nbsp;&raquo; ou &laquo;&nbsp;err&nbsp;&raquo;. Cela signifie tous les messages de logs envoyés par les programmes qui se signent en &laquo;&nbsp;mail&nbsp;&raquo; et qui précisent que les messages sont de type warning ou error.</p>
<p>Les message de type &laquo;&nbsp;info&nbsp;&raquo; 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 &laquo;&nbsp;info&nbsp;&raquo; =&gt; inutile de les faire remonter inutilement&#8230;)</p>
<p>Notons aussi la directive &laquo;&nbsp;workdirectory&nbsp;&raquo;, 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 &laquo;&nbsp;postfix&nbsp;&raquo; mais que nous souhaitons recevoir tous les autres (messages systèmes, etc).</p>
<p>Généralement nous ne nous attarderons pas à &laquo;&nbsp;éliminer&nbsp;&raquo; 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 &laquo;&nbsp;mail&nbsp;&raquo;, &laquo;&nbsp;cron&nbsp;&raquo;, &#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>local7.*                                                 @@serveur.de.logs:544</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>- &laquo;&nbsp;options&nbsp;&raquo; : le réglagage général du démon syslog-ng</p>
<p>- &laquo;&nbsp;source&nbsp;&raquo; : identification d&#8217;une source de message (facility, level, &#8230;)</p>
<p>- &laquo;&nbsp;destination&nbsp;&raquo; : 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

};

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

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 - </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 SNARE développé par la société INTERSECTALLIANCE et qui est télévhargeable ici dans une version libre : <a href="http://sourceforge.net/projects/snare/">http://sourceforge.net/projects/snare/</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>2.2.4.1 &#8211; Installation de l&#8217;Agent SNARE</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 &laquo;&nbsp;Next&nbsp;&raquo;, 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 http://localhost:6161 vous verrez alors apparaitre l&#8217;écran suivant :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_1.png" rel="lightbox[124]"><img 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>A) NETWORK CONFIGURATION:</p>
<p>&nbsp;</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 &laquo;&nbsp;SYSLOG Priority&nbsp;&raquo; ne vaut pas &laquo;&nbsp;DYNAMIC&nbsp;&raquo;, alors tous vos messages auront tous la même priorité (bof)</p>
<p><span style="text-decoration: underline;">Rem: </span>&laquo;&nbsp;Syslog Facility&nbsp;&raquo; 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 &laquo;&nbsp;CHANGE CONFIGURATION&nbsp;&raquo; pour que les paramètres soient enregistrés (mais pas encore pris en compte)</p>
<p>B) REMOTE CONTROL CONFIGURATION</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" rel="lightbox[124]"><img 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 &laquo;&nbsp;Restrict remote control of SNARE agent to certain hosts&nbsp;&raquo; et indiquez &laquo;&nbsp;127.0.0.1&#8243; (ou &laquo;&nbsp;localhost&nbsp;&raquo;) dans le champ &laquo;&nbsp;IP Address allowed to remote control SNARE&nbsp;&raquo;, 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 &laquo;&nbsp;DELETE&nbsp;&raquo; pour chaque ligne.</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_7.png" rel="lightbox[124]"><img 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 &laquo;&nbsp;ADD&nbsp;&raquo;, la fenêtre suivante apparaît alors :</p>
<p><a href="http://cx.cx/wp-content/uploads/2011/02/snare_4.png" rel="lightbox[124]"><img 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 &laquo;&nbsp;utiles&nbsp;&raquo; et les &laquo;&nbsp;best pratice&nbsp;&raquo; à 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 &laquo;&nbsp;CHANGE CONFIGURATION&nbsp;&raquo; 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>C) APPLY THE LATEST CONFIGURATION</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 &laquo;&nbsp;Apply the latest configuration&nbsp;&raquo; et cliquer sur &laquo;&nbsp;RELOAD SETTINGS&nbsp;&raquo;.</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 &laquo;&nbsp;LATEST EVENTS&nbsp;&raquo; 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" rel="lightbox[124]"><img 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>3) Configuration du serveur SYSLOG central</p>
<p>&nbsp;</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 &laquo;&nbsp;syslog_arch&nbsp;&raquo;. Cette base &nbsp;&raquo;syslog_arch&nbsp;&raquo; est un lien NFS vers un réseau de moindre performance (NAS) que la base de production &laquo;&nbsp;syslog&nbsp;&raquo; qui elle est présente sur des disques locaux de haute capacité. A vous de voir!</div>
<div>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.</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 &laquo;&nbsp;syslog&nbsp;&raquo; précédement créée.</div>
<pre>$Modload ommysql
$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
$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
$UDPServerRun 514
$UDPServerAddress 192.168.12.5
$InputTCPServerRun 514</pre>
<div>De couleur VERTE, 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>De couleur ROUGE, 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é &laquo;&nbsp;syslog&nbsp;&raquo; 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 &laquo;&nbsp;syslog&nbsp;&raquo; avec l&#8217;authentification syslogLogin/syslogPassword, le template à utiliser sera &laquo;&nbsp;syslogTpl&nbsp;&raquo;;</div>
<div>Et voilà, bonne utilisation!</div>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmount.com/articles/serveur-de-logs-central/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alternative à la DBConsole</title>
		<link>http://www.startupmount.com/articles/ignite-une-alternative-a-la-dbconsole/</link>
		<comments>http://www.startupmount.com/articles/ignite-une-alternative-a-la-dbconsole/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 09:17:56 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[11G]]></category>
		<category><![CDATA[confio]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[db control]]></category>
		<category><![CDATA[dbconsole]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[ignite]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle tunning pack]]></category>
		<category><![CDATA[performances]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=107</guid>
		<description><![CDATA[Dans de nombreux cas, les entreprises ne peuvent pas se &#171;&#160;payer&#160;&#187; la version Enterprise d&#8217;Oracle et sont réduites à utiliser une version &#171;&#160;Standard&#160;&#187;. Non seulement la version &#171;&#160;Standard&#160;&#187; vous bride en matière de puissance CPU mais elle vous empêche catégoriquement d&#8217;utiliser certaines fonctionnalité du moteur de base de données. Outre les importantes limitations physiques et logiques imposées [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Dans de nombreux cas, les entreprises ne peuvent pas se &laquo;&nbsp;payer&nbsp;&raquo; la version Enterprise d&#8217;Oracle et sont réduites à utiliser une version &laquo;&nbsp;Standard&nbsp;&raquo;.</p>
<p style="text-align: justify;">Non seulement la version &laquo;&nbsp;Standard&nbsp;&raquo; vous bride en matière de puissance CPU mais elle vous empêche catégoriquement d&#8217;utiliser certaines fonctionnalité du moteur de base de données.</p>
<p style="text-align: justify;">Outre les importantes limitations physiques et logiques imposées telles :</p>
<ul style="text-align: justify;">
<li>Deux sockets maximum par serveur</li>
<li>Pas de DataGuard autorisé</li>
<li>Pas d&#8217;Oracle Streams autorisé (même si ce n&#8217;est pas vraiment un cadeau&#8230;)</li>
<li>Pas de sauvegarde incrémentales Rman possibles</li>
<li>Pas de flashback database possible</li>
<li>Pas de partitionnement autorisé</li>
<li>Onglets de la DBConsole restreints</li>
<li>Pas de &#8230; pas de &#8230; etc  (et il en reste &#8230;)</li>
</ul>
<p>Autrement dit, la pluspart des innovations apportées en 10g sont interdites en version &laquo;&nbsp;standard&nbsp;&raquo;. 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 &laquo;&nbsp;standard&nbsp;&raquo; ce qui est limite illégal de la part d&#8217;Oracle) , à savoir :</p>
<ul style="text-align: justify;">
<li>Diagnostick Pack</li>
<li>Tunnig Pack</li>
<li>Configuration Pak</li>
</ul>
<p style="text-align: justify;">Autrement dit, la DBConsole ne vous sert à quasiment à  &nbsp;&raquo;<span style="text-decoration: underline;">rien</span>&laquo;&nbsp;, l&#8217;onglet &laquo;&nbsp;Performances&nbsp;&raquo; est grisé, et vous devez, comme toute version antérieure à 10g, confectionner vous même tous les outils de surveillance&#8230;</p>
<p style="text-align: justify;"><span id="more-107"></span></p>
<p style="text-align: justify;">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 &laquo;&nbsp;Diagnostic&nbsp;&raquo; et &laquo;&nbsp;Tunning&nbsp;&raquo; pour lesquels d&#8217;exellentes alternatives existent, notamment &laquo;&nbsp;<a href="http://www.confio.com/English/Products/Ignite_for_Oracle.php" target="_blank">IGNITE for Oracle</a>&nbsp;&raquo; de la société <a href="http://www.confio.com/" target="_blank">Confio</a>.</p>
<p style="text-align: justify;"><img title="More..." src="http://cx.cx/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /></p>
<p style="text-align: justify;">1) Introduction:</p>
<p style="text-align: justify;">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 style="text-align: justify;">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 style="text-align: justify;"><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 style="text-align: justify;">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 style="text-align: justify;">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 style="text-align: justify;"><span style="text-decoration: underline;">2) Périmètre</span></p>
<p style="text-align: justify;"><span style="text-decoration: underline;">2.1) Introduction:</span></p>
<p style="text-align: justify;">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 &laquo;&nbsp;puissance&nbsp;&raquo; que vous paierez plus ou moins cher votre licence Ignite, un peu à la sauce Oracle, mais en moins cher évidement&#8230;</p>
<p style="text-align: justify;">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 style="text-align: justify;"><span style="text-decoration: underline;">2.2) Téléchargements:</span></p>
<ul style="text-align: justify;">
<li>openSuSE 11.3 / 32b: <a href="http://software.opensuse.org/113/fr" target="_blank">http://software.opensuse.org/113/fr</a></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>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</li>
</ul>
<p style="text-align: justify;">Donc : l&#8217;OS + Oracle Express + le produit, c&#8217;est tout !</p>
<p style="text-align: justify;"><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 style="text-align: justify;"><span style="text-decoration: underline;">3) Installation &amp; configuration</span></p>
<p style="text-align: justify;"><span style="text-decoration: underline;">3.1) Installation de OpenSuSE 11.3 32b</span></p>
<p style="text-align: justify;">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 style="text-align: justify;">Une petite recommandation sur le partitionnement cependant:</p>
<ul style="text-align: justify;">
<li>/ &lt;= 6Gb: largement suffisant pour la racine (n&#8217;installez rien de superflu)</li>
<li>/var/log &lt;= 2Gb: pour ne pas géner les applications en cas de logging excessif</li>
<li>/usr/lib/oracle &lt;= 3Gb: par défaut le répertoire d&#8217;install de Oracle XE</li>
<li>/datas &lt;= 5Gb: vos archives (max 1gb) et votre database (max 4gb en XE)</li>
</ul>
<p style="text-align: justify;"><span style="text-decoration: underline;">3.2) Installation de &laquo;&nbsp;OraRUN&nbsp;&raquo;</span></p>
<p style="text-align: justify;">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.</p>
<p style="text-align: justify;">Vous pouvez ne pas l&#8217;installer et configurer vous mêmes les prérequis, à vous de voir.</p>
<pre>&gt; rpm -ivh /datas/downloads/orarun.rpm
&gt; chkconfig 35 oracle
&gt; rcoracle start</pre>
<p style="text-align: justify;"><span style="text-decoration: underline;">3.3) Installation de Oracle XE</span></p>
<p style="text-align: justify;">Si vous n&#8217;avez pas installé OraRun comme indiqué précédement:</p>
<p style="text-align: justify;">a - Créez un user &laquo;&nbsp;oracle&nbsp;&raquo; ayant pour home dir &laquo;&nbsp;/home/oracle&nbsp;&raquo; et appartenant aux deux groupes à créer également que sont &laquo;&nbsp;dba&nbsp;&raquo; et &laquo;&nbsp;oinstall&nbsp;&raquo;.</p>
<p style="text-align: justify;">b - Affectez le user oracle et le groupe dba à /home/oracle.</p>
<p style="text-align: justify;">c - editez le fichier /etc/profile et ajoutez à la fin les lignes suivantes:</p>
<pre>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>export PATH=$PATH://usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin</pre>
<p style="text-align: justify;">Installez la version téléchargée de XE telle avec :</p>
<pre>&gt; rpm -ivh /datas/downloads/oracle-xe-10.2.0.1-1.0.i386.rpm
&gt; ...
&gt; /etc/init.d/oracle-xe  configure
&gt; ... (laissez toutes les options par défaut)
&gt; /etc/init.d/oracle-xe  start</pre>
<p style="text-align: justify;">Vérifiez que votre database est correctement installée et que votre instance est disponible :</p>
<pre>&gt; su  -  oracle
&gt; [oracle] : sqlplus  /  as sysdba
&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;
&gt;
&gt; INSTANCE_NAME    DATABASE_STATUS
&gt; ---------------- -----------------
&gt; XE               ACTIVE</pre>
<div style="text-align: justify;">Tout va alors bien, on peut continuer  !</div>
<p style="text-align: justify;"><span style="text-decoration: underline;">3.4) Installation de Ignite</span></p>
<p style="text-align: justify;">3.4.1) Installation du web server IGNITE</p>
<p style="text-align: justify;">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
./ignite_pi_tf_8_1_118_installer.sh

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 style="text-align: justify;">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 style="text-align: justify;">Vérifiez que le fichier /data/ignite/pi_8_0_110/nohup.out se termine bien par la phrase &laquo;&nbsp;Exiting script after webserver launched&nbsp;&raquo;, 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 style="text-align: justify;">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 &laquo;&nbsp;http://&lt;ip_du_serveur_ignite&gt;:8123&#8243;, vous verrez alors les écrans suivants apparaitres et à valider :</p>
<p style="text-align: justify;">a) Veuillez &laquo;&nbsp;valider&nbsp;&raquo; votre intention de créer un repository pour les futures mesures:</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/17.jpg" rel="lightbox[107]"><img title="17" src="http://cx.cx/wp-content/uploads/2011/03/17.jpg" alt="" width="609" height="409" /></a></p>
<p style="text-align: justify;">b) Validez vous vous désirez créer ce repository dans une base Oracle:</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/16.jpg" rel="lightbox[107]"><img title="16" src="http://cx.cx/wp-content/uploads/2011/03/16.jpg" alt="" width="609" height="396" /></a></p>
<p style="text-align: justify;">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 &laquo;&nbsp;system&nbsp;&raquo; de cette database (et pas le pass du users &laquo;&nbsp;sys&nbsp;&raquo;!) :</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/15.jpg" rel="lightbox[107]"><img title="15" src="http://cx.cx/wp-content/uploads/2011/03/15.jpg" alt="" width="609" height="407" /></a></p>
<p style="text-align: justify;">d) Entrez un USERNAME / password  pour le schéma du repository :</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/14.jpg" rel="lightbox[107]"><img title="14" src="http://cx.cx/wp-content/uploads/2011/03/14.jpg" alt="" width="609" height="410" /></a></p>
<p style="text-align: justify;">e) Dans quel TableSpace le repository doit-il être stoqué ? (et quel est son tbs temporaire?) :</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/13.jpg" rel="lightbox[107]"><img title="13" src="http://cx.cx/wp-content/uploads/2011/03/13.jpg" alt="" width="609" height="401" /></a></p>
<p style="text-align: justify;">f) Voici un récapitulatif de vos choix, lise le avec soin et validez pour passer à la suite :</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/12.jpg" rel="lightbox[107]"><img title="12" src="http://cx.cx/wp-content/uploads/2011/03/12.jpg" alt="" width="609" height="404" /></a></p>
<p style="text-align: justify;">g) Vérifiez que tout s&#8217;est bien passé en parcourant la log et en validant que &laquo;&nbsp;Respository has been created&nbsp;&raquo;, sinon, inutile d&#8217;aller plus loin et trouvez le problème (et la solution <img src='http://www.startupmount.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> )</p>
<p style="text-align: justify;">Cliquez ensuite sur &laquo;&nbsp;Register database to monitor&nbsp;&raquo; pour configurer la database à surveiller.</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/11.jpg" rel="lightbox[107]"><img title="11" src="http://cx.cx/wp-content/uploads/2011/03/11.jpg" alt="" width="609" height="402" /></a></p>
<p style="text-align: justify;">h) Dans notre cas, évidement, sélectionnez &laquo;&nbsp;Oracle&nbsp;&raquo; comme type de database, puis continuez :</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/10.jpg" rel="lightbox[107]"><img title="10" src="http://cx.cx/wp-content/uploads/2011/03/10.jpg" alt="" width="609" height="398" /></a></p>
<p style="text-align: justify;">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 &laquo;&nbsp;sys&nbsp;&raquo; par sécurité) :</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/9.jpg" rel="lightbox[107]"><img title="9" src="http://cx.cx/wp-content/uploads/2011/03/9.jpg" alt="" width="609" height="404" /></a>Puis cliquez sur &laquo;&nbsp;Next&nbsp;&raquo;&#8230;</p>
<p style="text-align: justify;">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 style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/8.jpg" rel="lightbox[107]"><img title="8" src="http://cx.cx/wp-content/uploads/2011/03/8.jpg" alt="" width="609" height="407" /></a></p>
<p style="text-align: justify;">Cliquez sur &laquo;&nbsp;Next&nbsp;&raquo; !!</p>
<p style="text-align: justify;">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: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/7.jpg" rel="lightbox[107]"><img title="7" src="http://cx.cx/wp-content/uploads/2011/03/7.jpg" alt="" width="609" height="405" /></a></p>
<p style="text-align: justify;">Et Next encore une fois!</p>
<p style="text-align: justify;">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 style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/6.jpg" rel="lightbox[107]"><img title="6" src="http://cx.cx/wp-content/uploads/2011/03/6.jpg" alt="" width="609" height="409" /></a></p>
<p style="text-align: justify;">m) Vérifiez que tout est ok avant de cliquer définitivement sur &laquo;&nbsp;Register Database Instance&nbsp;&raquo; :</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/5.jpg" rel="lightbox[107]"><img title="5" src="http://cx.cx/wp-content/uploads/2011/03/5.jpg" alt="" width="609" height="408" /></a></p>
<p style="text-align: justify;">n) Si vous voyez apparaitre à la fin de la log écran &laquo;&nbsp;The database instance has been registrer and is now beeing monitored&nbsp;&raquo; c&#8217;est que tout est ok, sinon &#8230; cherchez l&#8217;erreur <img src='http://www.startupmount.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/4.jpg" rel="lightbox[107]"><img title="4" src="http://cx.cx/wp-content/uploads/2011/03/4.jpg" alt="" width="609" height="404" /></a></p>
<p style="text-align: justify;">o) Cliquez sur le bouton &laquo;&nbsp;Licence Managmnent&nbsp;&raquo; 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 style="text-align: justify;">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 style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/3.jpg" rel="lightbox[107]"><img title="3" src="http://cx.cx/wp-content/uploads/2011/03/3.jpg" alt="" width="609" height="156" /></a></p>
<p style="text-align: justify;">p) Renseigner votre clé, et cliquez sur &laquo;&nbsp;Add Licence&nbsp;&raquo;</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/03/2.jpg" rel="lightbox[107]"><img title="2" src="http://cx.cx/wp-content/uploads/2011/03/2.jpg" alt="" width="609" height="168" /></a></p>
<p style="text-align: justify;"><span style="text-decoration: underline;">4) Utilisation</span></p>
<p style="text-align: justify;">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 style="text-align: justify;">Vous pouvez consulter la partie &laquo;&nbsp;CURRENT&nbsp;&raquo; qui est le temps réel pour la partie &laquo;&nbsp;TREND&nbsp;&raquo; qui est l&#8217;archivage, pour regarder à postérieure le comportement de votre database.</p>
<p style="text-align: justify;">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 style="text-align: justify;">A vous de découvrir le produit !</p>
<p style="text-align: justify;"><a href="http://cx.cx/wp-content/uploads/2011/02/ignite.jpg" rel="lightbox[107]"><img 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://www.startupmount.com/articles/ignite-une-alternative-a-la-dbconsole/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Répartiteur de charge LVS</title>
		<link>http://www.startupmount.com/articles/repartiteur-de-charge-lvs/</link>
		<comments>http://www.startupmount.com/articles/repartiteur-de-charge-lvs/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 08:28:38 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[A la Une]]></category>
		<category><![CDATA[Continuité de service]]></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://www.startupmount.com/?p=77</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 de [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">LVS aka <a href="http://www.linuxvirtualserver.org/" target="_blank">Linux Virtual Servers</a> est la solution par défaut offerte par les distributions Linux en matière de Load Balancing.</p>
<p style="text-align: justify;">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 style="text-align: justify;">Nous verrons dans cet article que le choix des outils permettant d&#8217;automatiser la surveillance et le déclanchement des divers process permettant d&#8217;assurer le HA est celui de Keep-Alived, même si l&#8217;objet n&#8217;est pas ici d&#8217;expliquer le fonctionnement de cet outil.<span id="more-77"></span></p>
<p style="text-align: justify;"><img title="More..." src="http://cx.cx/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /><span style="text-decoration: underline;">1) Préconisations</span></p>
<p style="text-align: justify;"><span style="text-decoration: underline;">1.1) Système</span></p>
<p style="text-align: justify;">Les noyaux linux postérieurs à la version 2.2.14 intègrent les fonctionnalités LVS, si vous n&#8217;êtes pas à ce niveau, vous devrez patcher le kernel avec le module &laquo;&nbsp;IPVS&nbsp;&raquo; prévu pour votre distribition.</p>
<p style="text-align: justify;">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 KeepAlived.</p>
<p style="text-align: justify;">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 style="text-align: justify;">Téléchargements :</p>
<p style="padding-left: 30px; text-align: justify;">- OpenSuSE : <a href="http://software.opensuse.org/114/fr">http://software.opensuse.org/114/fr</a></p>
<p style="padding-left: 30px; text-align: justify;">- Doc LVS : <a href="http://www.linuxvirtualserver.org/Documents.html">http://www.linuxvirtualserver.org/Documents.html</a></p>
<p style="padding-left: 30px; text-align: justify;">- 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; text-align: justify;">- 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 style="text-align: justify;"><span style="text-decoration: underline;">1.2) Matériel</span></p>
<p style="text-align: justify;">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 &laquo;&nbsp;patchs&nbsp;&raquo; 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 style="text-align: justify;">Le premier travail d&#8217;un serveur LVS va consister en un routage, d&#8217;une adresse IP (adresse virtuelle, ou &laquo;&nbsp;IPV&nbsp;&raquo;) et un port connu du grand public et la redirection d&#8217;un flux réseau qui sera transmis, en fonction de la &laquo;&nbsp;charge&nbsp;&raquo; estimée sur les serveurs de la ferme et de sa disponibilité, vers le serveur le plus &laquo;&nbsp;disponible&nbsp;&raquo; (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 style="text-align: justify;">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 style="text-align: justify;">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://www.startupmount.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p style="text-align: justify;"><span style="text-decoration: underline;">2) Configuration de LVS</span></p>
<p style="text-align: justify;"><span style="text-decoration: underline;">2.1) LVS : un &laquo;&nbsp;switch&nbsp;&raquo; intelligent</span></p>
<p style="text-align: justify;">Les fonctionalités de base de LVS sont de répondre à un client IP qui cherche à joindre un serveur sur une IP &laquo;&nbsp;&lt;ip&gt;&nbsp;&raquo; 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 style="text-align: justify;">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 &laquo;&nbsp;estimer&nbsp;&raquo; la charge d&#8217;un serveur.</p>
<p style="text-align: justify;">Le serveur LVS &laquo;&nbsp;primaire&nbsp;&raquo; de notre cluster de LVS en FailOver se nomme un DIRECTOR.</p>
<p style="text-align: justify;"><span style="text-decoration: underline;">2.2) Indiquer l&#8217;IPV de votre ferme à votre serveur LVS</span></p>
<p style="text-align: justify;">Prenons le cas d&#8217;une ferme Web Classique basée sur 2 LVS en FailOver et 3 serveurs réels.</p>
<p style="text-align: justify;">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 style="text-align: justify;">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" rel="lightbox[77]"><img class="aligncenter" title="schema_global" src="http://cx.cx/wp-content/uploads/2011/03/schema_global.jpg" alt="" width="279" height="382" /></a></p>
<p style="text-align: justify;">Si l&#8217;adresse IP &laquo;&nbsp;virtuelle&nbsp;&raquo; 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 style="text-align: justify;">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 style="text-align: justify;">Voici le contenu de /etc/sysctl.conf (à minima, à adapter selon votre configuration) :</p>
<pre>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</pre>
<p style="text-align: justify;"><span style="text-decoration: underline;">2.2) ipvsadm</span></p>
<p style="text-align: justify;">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="text-align: justify;">2.2.1) Indiquer la présence d&#8217;une IPV à votre serveur LVS:</p>
<pre>shell&gt; ipvsadm --add-service --tcp-service 192.168.1.10:80 --scheduler rr</pre>
<p style="text-align: justify;">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="text-align: justify;">L&#8217;algorithme de répartition de charge ici est &laquo;&nbsp;&#8211;scheduler rr&nbsp;&raquo;, c&#8217;est à dire du Round Robin (Un pour Un). Nous verrons en 2.4 les différents algorithmes disponibles.</p>
<p style="text-align: justify;">2.2.2) Indiquer la présence des 3 serveurs réels à LVS :</p>
<pre>shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 --real-server 192.168.1.1:80 --masquerading --weight 10
shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 --real-server 192.168.1.2:80 --masquerading --weight 10
shell&gt; ipvsadm --add-server --tcp-service  192.168.1.10:80 --real-server 192.168.1.3:80 --masquerading --weight 10</pre>
<p style="text-align: justify;"><span style="text-decoration: underline;">Explications:</span></p>
<ul style="text-align: justify;">
<li>&#8211;tcp-service: 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</li>
<li>&#8211;real-server: 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</li>
<li>&#8211;masquerading: le Director va utiliser le protocole NAT pour faire transiter les flux TCP avec les serveurs réels (voir 2.3.1)</li>
<li>&#8211;weight: notion de poids (de priorité pour le LoadBalancing)</li>
</ul>
<p style="text-align: justify;">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="text-align: justify;">2.2.3) Vérifier la prise en compte des ordres tables ipvs</p>
<pre>shell&gt; ipvsadm --list

  IP Virtual Server version 1.2.1 (size=4096)

  Prot LocalAddress:Port Scheduler Flags

    -&gt; RemoteAddress:Port           Forward Weight ActiveConn InActConn

  TCP  192.168.1.10:http rr persistent 360

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

    -&gt; 192.168.1.2:http              Route   1      0          0

    -&gt; 192.168.1.3:http              Route   1      0          0

  TCP  192.168.1.10:https rr persistent 360

    -&gt; 192.168.1.1:https              Route   1      0          0

    -&gt; 192.168.1.2:https              Route   1      0          0

    -&gt; 192.168.1.3:https              Route   1      0          0</pre>
<p style="text-align: justify;">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 style="text-align: justify;"><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 style="text-align: justify;"><span style="text-decoration: underline;">Remarque:</span> A l&#8217;instant où nous passons la commande &laquo;&nbsp;ipvsadm -l&nbsp;&raquo; sur notre Director, nous constatons que 2 sessions sont établies vers le serveur physique 192.168.1.1.</p>
<p style="text-align: justify;"><span style="text-decoration: underline;">2.3) Routage direct (DR) ou Translations d&#8217;adresses (NAT)</span></p>
<p style="text-align: justify;">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 style="text-align: justify;">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 style="text-align: justify;">2.3.1) NAT (Network Address Translation)</p>
<p style="text-align: justify;">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 style="text-align: justify;">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><a href="http://cx.cx/wp-content/uploads/2011/03/flux_nat1.jpg" rel="lightbox[77]"><img class="aligncenter" title="flux_nat" src="http://cx.cx/wp-content/uploads/2011/03/flux_nat1.jpg" alt="" width="568" height="346" /></a></p>
<p style="text-align: justify;">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 style="text-align: justify;"><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 style="text-align: justify;"><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 style="text-align: justify;">2.3.2) DR (Direct Routing)</p>
<p style="text-align: justify;">2.3.2.a) Présentation</p>
<p style="text-align: justify;">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><a href="http://cx.cx/wp-content/uploads/2011/03/flux_dr.jpg" rel="lightbox[77]"><img class="aligncenter" title="flux_dr" src="http://cx.cx/wp-content/uploads/2011/03/flux_dr.jpg" alt="" width="533" height="341" /></a></p>
<p style="text-align: justify;">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 style="text-align: justify;">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>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</pre>
<p style="text-align: justify;">2.2.2.b) Problématique du routage</p>
<p style="text-align: justify;">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 style="text-align: justify;">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 style="text-align: justify;">Généralement, il suffit d&#8217;aller modifier le fichier /etc/sysconfig/network/ifcfg-lo tel que :</p>
<pre id="_mcePaste" style="text-align: justify;">#DESC de l'IPV de votre ferme :</pre>
<pre id="_mcePaste" style="text-align: justify;">IPADDR_0=192.168.1.10</pre>
<pre id="_mcePaste" style="text-align: justify;">NETMASK_0=255.255.255.255 NETWORK_0=192.168.1.0 BROADCAST_0=192.168.1.255</pre>
<pre id="_mcePaste" style="text-align: justify;">#---------------------------------- 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</pre>
<p style="text-align: justify;"><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 style="text-align: justify;"><span style="text-decoration: underline;">2.3) Algorithmes d&#8217;analyse de charge (RR, WRR, &#8230;)</span></p>
<p style="text-align: justify;">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 style="text-align: justify;">Les algorithmes d&#8217;analyse de répartition de charge des IPVS sont larges, en voici un bref descriptif des plus usités:</p>
<ul style="text-align: justify;">
<li>rr (Round-Robin): 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.</li>
<li>wrr (Weighted Round-Robin): Même répartition que &laquo;&nbsp;rr&nbsp;&raquo; mais en donnant plus de charge aux serveurs affectés de poids supérieurs.</li>
<li>lc (Least Connected): 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 &laquo;&nbsp;t&nbsp;&raquo;.</li>
<li>wlc (Weighted Least Connected): Même répartition que &laquo;&nbsp;lc&nbsp;&raquo; mais en donnant plus de charge aux serveurs affectés de poids supérieurs.</li>
</ul>
<p style="text-align: justify;">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://www.startupmount.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p style="text-align: justify;"><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 style="text-align: justify;"><span style="text-decoration: underline;">2.4) LVS /FailOver :</span></p>
<p style="text-align: justify;">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 <span style="text-decoration: underline;">KeepAlived</span> alors que HeartBeart rempli strictement le même rôle&#8230; Il fallait bien en choisir un <img src='http://www.startupmount.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p style="text-align: justify;">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://www.startupmount.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  (envoyer les insultes à contact@edfgdf.fr svp, c&#8217;est très tendance).</p>
<p style="text-align: justify;">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 style="text-align: justify;">2.4.1) Téléchargement</p>
<ul style="text-align: justify;">
<li>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></li>
</ul>
<p style="text-align: justify;">2.4.2) Installation</p>
<p style="text-align: justify;">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 style="text-align: justify;">Compilez les fichiers objets en indiquant le repertoire d&#8217;installation avec</p>
<pre>shell&gt; ./configure --prefix=/data/keepAlived/</pre>
<p style="text-align: justify;">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 style="text-align: justify;">Linkez et terminez votre installation par</p>
<pre>shell&gt; make

...

shell&gt; make install

...</pre>
<p style="text-align: justify;">Voilà, KeepAlived est installé &#8230;</p>
<p style="text-align: justify;">L&#8217;install vous amène les fichiers suivants:</p>
<ul style="text-align: justify;">
<li>keepalived et son fichier de conf keepalived.conf (placez le de preference dans /etc/keepalived/)</li>
<li>./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)</li>
<li>genhash (un utilitaire md5 pour keepalived afin de vérifier le contenu de certains flux retournés)</li>
</ul>
<p style="text-align: justify;">A vous de disposer ces fichiers dans vos répertoires préférés pour que tout fonctionne bien.</p>
<p style="text-align: justify;">2.4.3) Utilisation</p>
<p style="text-align: justify;">Tout se trouve dans la configuration (élémentaire) de /etc/keepalived/keepalived.conf.</p>
<p style="text-align: justify;">2.4.3.a) Configuration globales</p>
<p style="text-align: justify;">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 style="text-align: justify;">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 style="text-align: justify;">2.4.3.b) Configuration du protocole de surveillance du FailOver (VRRP)</p>
<pre>vrrp_instance VRRP1 {
    state MASTER
    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 style="text-align: justify;">Voici un bref descriptif de ces paramètres:</div>
<ul style="text-align: justify;">
<li>state: 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.</li>
<li>interface: quelle est l&#8217;interface réseau <span style="text-decoration: underline;">dédiée </span>à 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.</li>
<li>virtual_router_id: un numéro <span style="text-decoration: underline;">UNIQUE</span> pour l&#8217;ensemble de vos serveurs LVS</li>
<li>priority: 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.</li>
<li>authentication: 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;)</li>
<li>virtual_ipadress: le nom est assez parlant, l&#8217;IPV ou les IPV de votre serveur LVS</li>
</ul>
<div style="text-align: justify;">2.4.3.c) Configuration d&#8217;un serveur virtuel et de ses serveurs rééls associés</div>
<div style="text-align: justify;">Nous allons prendre comme exemple un serveur virtuel répondant sur l&#8217;IPV 192.168.10.10 et qui fait du load balancing en Round Robin sur 3 serveurs physiques,</div>
<div style="text-align: justify;">
<ul>
<li>192.168.1.1</li>
<li>192.168.1.2</li>
<li>192.168.1.3</li>
</ul>
</div>
<div style="text-align: justify;">Le service est celui d&#8217;une ferme Web, il faut donc laisser passer les protocoles HTTP (port 80) et HTTPS (port 443).</div>
<div style="text-align: justify;">Dans cette première version, nous allons considérer que un serveur réel est &laquo;&nbsp;up&nbsp;&raquo; 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 192.168.1.10 80 {

        delay_loop 10
        lb_algo RR
        lb_kind DR
        persistence_timeout 360
        protocol TCP

        real_server 192.168.1.1 80 {
                weight 1
		TCP_CHECK {
			connect_port    80
			connect_timeout 3
		}
        }

        real_server 192.168.1.2 80 {
                weight 1
		TCP_CHECK {
			connect_port    80
			connect_timeout 3
		}
        }

        real_server 192.168.1.3 80 {
                weight 1
		TCP_CHECK {
			connect_port    80
			connect_timeout 3
		}
        }
}</pre>
<p style="text-align: justify;">Voici un bref descriptif de ces paramètres:</p>
<ul style="text-align: justify;">
<li>virtual_server: l&#8217;adresse IP Virtuelle de votre serveur virtuel et son port d&#8217;écoute
<ul>
<li>delay loop: intervalle en secondes entre les différents tests de présence des serveurs réels</li>
<li>protocol: ici on utilise TCP (on peut aussi utiliser UDP dans certains cas)</li>
<li>lb_algo: algorithme de LoadBalancing (rr, wrr, dr, wdrr, &#8230; : voir 2.4))</li>
<li>lb_kind: méthode de routage (NAT ou DR, voir 2.3))</li>
<li>real_server: définition d&#8217;un serveur réél dans cette ferme, adresse réelle et port d&#8217;écoute
<ul>
<li>weight: poids du serveur pour load balancing</li>
<li>tcp_check: 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.</li>
</ul>
</li>
</ul>
</li>
</ul>
<div style="text-align: justify;">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;</div>
<div style="text-align: justify;">2.4.3.d) Comment vérifier qu&#8217;un serveur réel répond toujours ?</div>
<div style="text-align: justify;">Comme nous l&#8217;avons vu en 2.4.3.c) dans chaque real_server nous avons la possibilité d&#8217;utiliser la config &laquo;&nbsp;TCP_CHECK&nbsp;&raquo; 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;</div>
<div style="text-align: justify;">Voici d&#8217;autres méthodes plus pertinentes:</div>
<div style="text-align: justify;">
<ul>
<li>HTTP_GET: 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</li>
<li>SSL_GET:Même chose que HTTP_GET mais pour le protocole HTTPS</li>
<li>MISC_CHECK: Vous permet de définir des tests personalisés</li>
</ul>
</div>
<p style="text-align: justify;"><span style="text-decoration: underline;">Exemple HTTP_GET:</span></p>
<p style="text-align: justify;">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 &laquo;&nbsp;TRUE&nbsp;&raquo; en cas de réussite ou &laquo;&nbsp;FALSE&nbsp;&raquo; en cas d&#8217;echec.</p>
<p style="text-align: justify;">Utilisez l&#8217;utilitaire genhash pour calculer le hash MD5 de ce retour http avec la commande suivante :</p>
<pre>shell&gt; genhash -s 192.168.1.1 -p 80 -u /test.php shell&gt; 53f43f0f4f1c99c10230f5f0758915f1</pre>
<p style="text-align: justify;">Ici, la clé MD5 du résultat de cette page test est donc &laquo;&nbsp;53f43f0f4f1c99c10230f5f0758915f1&#8243;. Il faut que ce fichier soit évidement sur chaque serveur réel de votre ferme.</p>
<p style="text-align: justify;">Vous devez donc simplement remplacer la clause TCP_CHECK (voir 2.4.3.c)) par celle-ci:</p>
<pre>HTTP_GET {

		url {

		     path /test.php

		     digest 53f43f0f4f1c99c10230f5f0758915f1

	}

        connect_timeout 3

        nb_get_retry 3

        delay_before_retry 2

}</pre>
<p style="text-align: justify;">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 &laquo;&nbsp;digest&nbsp;&raquo;.</p>
<p style="text-align: justify;">Le test GET_HTTPS se configure de la même façon.</p>
<p style="text-align: justify;">Exemple MISC_CHECK:</p>
<p style="text-align: justify;">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>MISC_CHECK { 	misc_path /data/scripts/mon_script.sh param1 param2 }</pre>
<p style="text-align: justify;">Assez simple à priori <img src='http://www.startupmount.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align: justify;">2.4.4) Gestion d&#8217;un serveur LVS secondaire (&laquo;&nbsp;backup&nbsp;&raquo;) :</p>
<p style="text-align: justify;">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 style="text-align: justify;">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 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 6841665145
    }
    virtual_ipaddress {
        192.168.1.10
    }
}</pre>
<div style="text-align: justify;">Le mot clé &laquo;&nbsp;BACKUP&nbsp;&raquo; 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>
<p style="text-align: justify;"><span style="text-decoration: underline;">3) Utilisation de LVS et monitoring</span></p>
<div style="text-align: justify;"><span style="text-decoration: underline;"><br />
</span></div>
<div style="text-align: justify;">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 style="text-align: justify;">Vérifiez que tout va bien avec &laquo;&nbsp;ipvsadm &#8211;list&nbsp;&raquo;, vous devriez voir apparaître un écran qui ressemble à celui montré en 2.2.3) et indiquant que tout va bien.</div>
<div style="text-align: justify;">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 style="text-align: justify;">Vous disposez maintenant d&#8217;une FermeWeb Load Balancée!</div>
<div style="text-align: justify;">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/">http://www.linuxvirtualserver.org</a> et <a href="http://www.keepalived.org/">http://www.keepalived.org</a> !</div>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmount.com/articles/repartiteur-de-charge-lvs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RMAN : Présentation et référentiel</title>
		<link>http://www.startupmount.com/articles/rman-presentation-et-referentiel/</link>
		<comments>http://www.startupmount.com/articles/rman-presentation-et-referentiel/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 14:40:36 +0000</pubDate>
		<dc:creator>xa</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Sauvegardes]]></category>
		<category><![CDATA[list backup]]></category>
		<category><![CDATA[référentiel]]></category>
		<category><![CDATA[rman]]></category>
		<category><![CDATA[sauvegarde]]></category>

		<guid isPermaLink="false">http://www.startupmount.com/?p=196</guid>
		<description><![CDATA[RMAN (Recovery Manager) est l&#8217;outil d&#8217;Oracle pour la sauvegarde des bases de données, il est donc dommage (pour ne pas employer d&#8217;autre terme) d&#8217;utiliser un autre utilitaire que celui-ci pour sauvegarder les données Oracle. RMAN permet de sauvegarder des données à froid comme à chaud en toute sécurité. Les sauvegardes peuvent être FULL, différentielles ou cumulatives [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>RMAN (Recovery Manager) est l&#8217;outil d&#8217;Oracle pour la sauvegarde des bases de données, il est donc dommage (pour ne pas employer d&#8217;autre terme) d&#8217;utiliser un autre utilitaire que celui-ci pour sauvegarder les données Oracle.</p>
<p>RMAN permet de sauvegarder des données à froid comme à chaud en toute sécurité. Les sauvegardes peuvent être FULL, différentielles ou cumulatives et sont basées sur un référentiel nommé REPOSITORY qui peut se trouver dans les fichiers de dontrole d&#8217;une database ou qui peut être externalisé dans une instance prévue à cet effet (REPOSITORY CATALOG ou &laquo;&nbsp;catalogue de récupération&nbsp;&raquo;).<span id="more-196"></span></p>
<p><img title="Lire la suite…" src="../wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /><span style="text-decoration: underline;">0 &#8211; Utilisation de RMAN avec les fichiers de contrôles</span></p>
<p>Si vous utilisez les fichiers de controle comme référentiel RMAN, il est encore plus critique de ne pas les perdres, le multiplexage sur plusieurs disques et/ou plusieurs fileSystem est une obligation pour s&#8217;assurer de pouvoir restaurer une sauvegarde !</p>
<p>Les données conservées dans un fichier de contrôle ne sont pas éternelles et sont fixées par le paramètre d&#8217;init de l&#8217;instance CONTROL_FILE_RECORD_KEEP_TIME. La valeur par défaut de ce paramètre est 7 (une semaine), dans le cadre de l&#8217;utilisation de RMAN, je vous conseille de porter ce chiffre à 15 voire 30 !</p>
<p><span style="text-decoration: underline;">1 &#8211; Utilisation de RMAN avec un catalogue de récupération </span>(recommandé)<span style="text-decoration: underline;"><br />
</span></p>
<p><span style="text-decoration: underline;">1.1 Introduction</span></p>
<p>La méthode de connexion d&#8217;un client RMAN sur la catalogue de récupération (instance de base de données dédiée à stoquer les informations RMAN dans une databse plustot que dans les fichiers de controles) est la suivante :</p>
<p>&gt; rman TARGET &lt;user_db&gt;/&lt;pass_bd&gt;@&lt;alias_db&gt; CATALOG &lt;user_cat&gt;/&lt;pass_cat&gt;@&lt;alias_cat&gt;</p>
<p>Il faut bien différencier dans cette commande le TARGET qui concerne les informations sur la base de données à sauvegarde ou à restaurer du CATALOG qui indique la chaine de connexion au catalogue de récupération.</p>
<p><span style="text-decoration: underline;">1.2 Création du catalogue</span></p>
<p>L&#8217;opération consiste, dans l&#8217;instance de base de données prévue à cet effet, à créer un tablespace et un user pour rman, puis, d&#8217;éffectuer un grant particulier au user rman:</p>
<pre># ORACLE_SID=rmancat
# sqlplus / as sysdba
SQL&gt; create tablespace rman_ts datafile '/data/rman/ts/ts01.dbf' size 50M next 10M unlimited;
Tablespace Created
SQL&gt; create user rman identified by rmanpass default tablespace rman_ts;
SQL&gt; grant connect, resource, recovery_catalog to rman;
SQL&gt; exit</pre>
<p>Et voilà : le grant RECOVERY_CATALOG suffit à indiquer que l&#8217;utilisateur rman a le droit d&#8217;interroger et d&#8217;interragir avec Oracle pour toute opération de sauvegarde / restauration.</p>
<p><span style="text-decoration: underline;">1.3 Utilisation du catalogue</span></p>
<p>A chaque nouvelle base de données à sauvegarder par rman, il faut informer rman qu&#8217;il doit l&#8217;inscrire au préalablement dans le catalogue (fichier de controle ou catalogue de récupération). Ceci se fait par la commande</p>
<p>RMAN&gt; register database;</p>
<p>Un DBID est affecté par rman au référentiel afin de différencier toutes les databases qui peuvent provenir de différents hosts et donc avoir les mêmes dbdid locaux ou dbname. Toutes les informations nécessaires aux futures sauvegardes / restaurations sont égallement créées (fichiers à sauvegarder, emplacements des journaux, &#8230;)</p>
<p><span style="text-decoration: underline;">1.4 Consultation du catalogue</span></p>
<p>1.4.1 Commande REPORT</p>
<p>La commande rman REPORT permet d&#8217;obtenir des informations sur l&#8217;état des sauvegardes, par exemple :</p>
<p>report schema : quelle est la structure de la base de données ?</p>
<p>report need backup : quels sont les fichiers qui nécessitent une sauvegarde ?</p>
<p>report need backup incremental 3 : même question pour les incrémentales de niveau 3</p>
<p>report need backup days 3 : même question pour les fichiers non sauvegardés depuis 3 jours</p>
<p>report obsolete : quels sont les fichiers qui peuvent être éffacés (conformément à la politique de sauvegarde)?</p>
<p>report unrecoverables : quels sont les fichiers introuvables et non restaurables ?</p>
<p>&#8230;</p>
<p>1.4.2 Commande LIST</p>
<p>La commande rman LIST permet d&#8217;obtenir des détails sur des sauvegardes ou certains éléments d&#8217;une sauvegarde, par exemple :</p>
<p>list backup; (liste de toutes les sauvegardes)</p>
<p>list backupset; (liste de tous les backupsets)</p>
<p>list backupset of datafile &#8216;/data/mabase/tablespaces/data/data01.dbf&#8217;; (liste de tous les backupsets de ce fichier)</p>
<p>etc&#8230;</p>
<p><span style="text-decoration: underline;">Note 1 :</span> Le détail des commandes de consultation du catalogue seront plus profondément approfondies dans l&#8217;aspect sauvegarde / restauration des bases de données à l&#8217;aide de rman et n&#8217;ont pas vocation à être étudiée dans cet article qui a pour unique but d&#8217;attirer l&#8217;attention du DBA sur la qualité du référentiel RMAN.</p>
<p><span style="text-decoration: underline;">Note 2 :</span> N&#8217; oubliez pas que, si vous perdez le recovery_catalog, vous ne pourrez plus restaurer aucune de vos sauvegardes de sera plus restaurable, il est donc primordial de le sauvegarder régulièrement. Le poids du catalogue étant très léger, vous n&#8217;aurez aucun problème à réaliser une sauvegarde complète journalière de celle-ci à froid, hors période de sauvegardes de vos autres databases.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmount.com/articles/rman-presentation-et-referentiel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

