Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
700 lines (584 sloc) 21.8 KB
<?xml version="1.0" encoding="UTF-8"?>
<!-- Dernière modification
le $Date$
par $Author$
révision $Revision$ -->
<sect1 id="monitoring">
<title>Surveillance</title>
<indexterm><primary>Surveiller &slony1;</primary></indexterm>
<para>
Comme prélude à la discussion, il est intéressant de pointer que comme
le corps de des fonctionnalités &slony1; est implanté via des fonctions
stockées dans la base de données et via les tables comprises dans le
schéma &slony1;, la majorité de la surveillance peut se faire en
exécutant des requêtes sur les tables du schéma pour chaque base de
données du cluster.
</para>
<para>
Voici une liste des tables contenant une information particulièrement
intéressante d'un point de vue surveillance et diagnostique.
</para>
<glosslist>
<glossentry>
<glossterm><envar>sl_status</envar></glossterm>
<glossdef>
<para>
Cette vue est à coup sûr la plus utile pour surveiller l'activité
de la réplication. Elle regarde les événements du n&oelig;ud local
et vérifie à quelle vitesse ils sont confirmés sur les autres
n&oelig;uds.
</para>
<para>
Cette vue est principalement utile sur le n&oelig;ud origine
(le <quote>maître</quote>) car c'est seulement sur ce n&oelig;ud que
les événements nécessitent du travail. Les événements générés sur les
autres n&oelig;uds sont généralements des événements de synchronisation
qui ne réclame pas de travail de réplication. Ce sont pratiquement des
opérations vides.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slconfirm;</glossterm>
<glossdef>
<para>
Contient les confirmations des événements de réplication&nbsp;; ceci
peut ensuite être utilisé pour inférer les événements traités et
surtout ceux qui <emphasis>ne sont pas encore</emphasis> traités.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slevent;</glossterm>
<glossdef>
<para>
Contient des informations sur les événements de réplication traités
sur le n&oelig;ud local.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&sllog1; et &sllog2;</glossterm>
<glossdef>
<para>
Ces tables contiennent des données réplicables. Sur un n&oelig;ud
origine, node, cela représente la <quote>queue</quote> des données
qui ne sont pas nécessairement répliquées partout. En examinant cette
table, vous pouvez examiner le détail des données réplicables.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slnode;</glossterm>
<glossdef>
<para>
La liste des n&oelig;uds du cluster.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slpath;</glossterm>
<glossdef>
<para>
Cette table contient les informations de connexion. Elle indique comment
les processus slon peuvent se connecter aux n&oelig;uds distants, que
ce soit pour accéder aux événements ou pour réclamer les données
réplicables.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&sllisten;</glossterm>
<glossdef>
<para>
Cette configuration indique comment les n&oelig;uds écoutent les
événements en provenance des autres n&oelig;uds. Généralement,
cette table est peuplée automatiquement&nbsp;; vous pouvez
détecter des problèmes de configuration si cette table est
<quote>sous-peuplée</quote>.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slregistry;</glossterm>
<glossdef>
<para>
Une table de configuration qui peut être utilisée pour stocker
différentes données à l'exécution. Actuellement seulement utilisée
pour férer la bascule entre les deux tables de log.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slseqlog;</glossterm>
<glossdef>
<para>
Contient la <quote>dernière valeur</quote> des séquences répliquées.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slset;</glossterm>
<glossdef>
<para>
Contient la définition des ensembles de réplication. C'est le mécanisme
utilisé pour grouper les tables et séquences réplicables.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slsetsync;</glossterm>
<glossdef>
<para>
Contient des informations sur l'état de la synchronisation pour chaque
ensemble de réplication, ceci incluant les données des images de
transaction.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&slsubscribe;</glossterm>
<glossdef>
<para>
Indique quels abonnements sont effectifs pour chaque ensemble de
réplication.
</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>&sltable;</glossterm>
<glossdef>
<para>
Contient la liste des tables en cours de réplication.
</para>
</glossdef>
</glossentry>
</glosslist>
<sect2 id="testslonystate">
<title>test_slony_state</title>
<indexterm><primary>script test_slony_state pour tester l'état de la réplication</primary></indexterm>
<para>
Ce script indispensable réalise différentes sortes d'analyse de l'état d'un
cluster &slony1;. Les <xref linkend="bestpractices"/> de &slony1; recommendent
l'exécution de ces scripts fréquemment (toutes les heures est une bonne idée)
pour découvrir les problèmes aussi rapidement que possible.
</para>
<para>
Vous pouvez spécifier les arguments en incluant <option>database</option>,
<option>host</option>, <option>user</option>,
<option>cluster</option>, <option>password</option> et
<option>port</option> pour vous connecter à un n&oelig;ud du cluster. Vous
pouvez aussi indiquer une commande <option>mailprog</option> (qui doit être
un équivalent de l'application <productname>Unix</productname>
<application>mailx</application>) et un destinataire des messages.
</para>
<para>
Autrement, vous pouvez spécifier les paramètres de connexion à la base de
données via les variables d'environnement utilisées par
<application>libpq</application>, <emphasis>c'est-à-dire</emphasis> en
utilisant <envar>PGPORT</envar>, <envar>PGDATABASE</envar>,
<envar>PGUSER</envar>, <envar>PGSERVICE</envar> et ainsi de suite.
</para>
<para>
Le script parcourt <xref linkend="table.sl-path"/> pour trouver tous les
n&oelig;uds du cluster et les DSN pour lui permettre de se connecter à
chacun d'entre eux.
</para>
<para>
Pour chaque n&oelig;, the script examine l'état de différents éléments,
dont&nbsp;:
</para>
<itemizedlist>
<listitem>
<para>
Vérification de <xref linkend="table.sl-listen"/> sur certains
problèmes <quote>analytiquement déterminables</quote>. Il liste
les chemins non couverts.
</para>
</listitem>
<listitem>
<para>
Rapport des événements par n&oelig;ud d'origine.
</para>
<para>
Si un n&oelig;ud n'a pas soumis d'événements depuis un moment, cela suggère
un problème.
</para>
</listitem>
<listitem>
<para>
Résumé de l'<quote>âge</quote> de la table <xref linkend="table.sl-confirm"/>
</para>
<para>
Si un des n&oelig;uds du cluster ne s'est pas manifesté récemment, cela fait que
tables comme &sllog1;, &sllog2; et &slseqlog; ne sont plus nettoyées.
</para>
</listitem>
<listitem>
<para>
Résumé des transactions longues
</para>
<para>
Ceci fonctionne seulement si le collecteur de statistiques est configuré
pour récupérer les requêtes en cours d'exécution, option contrôlée par
le paramètre <option>stats_command_string</option> du fichier
<filename>postgresql.conf</filename>.
</para>
<para>
Si vous avez des applications qui maintiennent anormalement des connexions
ouvertes, le script les trouvera.
</para>
<para>
Si vous avez des applications qui maintiennent anormalement des connexions
ouvertes, cela aura des effets néfastes comme ceux <link
linkend="longtxnsareevil">décrits dans la FAQ</link>.
</para>
</listitem>
</itemizedlist>
<para>
Le script réalise un travail de diagnostique se basant sur les paramètres
du script&nbsp;; si vous n'aimez pas les valeurs par défaut, n'hésitez pas
à les modifier&nbsp;!
</para>
<note>
<para>
Notez qu'il existe deux versions, une utilisant le module Perl
<quote>classic</quote> <filename>Pg.pm</filename> pour accéder aux bases de
données &postgres; et une, dont le nom contient <filename>dbi</filename>,
qui utilise la nouvelle interface <function> DBI</function> de Perl.
Il sera plus facile de trouver des packages pour<function>DBI</function>.
</para>
</note>
</sect2>
<sect2>
<title>Tester la replication avec &nagios;</title>
<indexterm><primary>&nagios; pour surveiller la réplication</primary></indexterm>
<para>
Le script <command>psql_replication_check.pl</command>, qui se trouve dans le
répertoire <filename>tools</filename>, regroupe les meilleures tentatives de
de tests utilisables par le système de surveillance <ulink
url="http://www.nagios.org/">&nagios;</ulink>.
</para>
<para>
Un script antérieur, nommé <filename>test_slony_replication.pl</filename>,
utilisait une approche <quote>intelligente</quote>&nbsp;: un <quote>script de
test</quote> est exécuté périodiquement et se déploie à travers les
configurations &slony1; pour trouver l'origine et les abonnés, injecte un
changement et observe sa propagation à travers le système. Il présentait deux
problèmes&nbsp;:
</para>
<itemizedlist>
<listitem>
<para>
En cas de problème de connectique impactant le n&oelig;ud qui jouait ce
test, c'est l'ensemble de réplication qui semblait détruite. De plus,
cette stratégie de surveillance est très fragile et dépend de nombreuses
conditions d'erreurs.
</para>
</listitem>
<listitem>
<para>
&nagios; n'a pas la possibilité de profiter de l'
<quote>intelligence</quote> d'une exploration automatique d'un ensemble
de n&oelig;uds. Vous devez mettre en place des règles de surveillance
&nagios; pour chaque n&oelig;ud.
</para>
</listitem>
</itemizedlist>
<para>
Le nouveau script, <command>psql_replication_check.pl</command>, utilise une
approche minimaliste qui suppose que le système est un système en ligne
recevant un <quote>trafic</quote> régulier, et vous permet de définir une vue
spécifique pour le test de réplication appelée
<envar>replication_status</envar> qui doit contenir des mises à jour
régulières. Cette vue regarde simplement la dernière
<quote>transaction</quote> sur le n&oelig;ud, et liste son horodatage, son
âge ainsi que quelques informations sur l'application qui peuvent être
utiles.
</para>
<itemizedlist>
<listitem>
<para>
Pour un système d'inventaire, cela pourrait être le numéro de l'ordre
effectué le plus récemment.
</para>
</listitem>
<listitem>
<para>
Pour un serveur de nom de domaines, cela peut être le nom du dernier
domaine créé.
</para>
</listitem>
</itemizedlist>
<para>
Une instance du script doit être exécutée sur chaque n&oelig;ud
surveillé&nbsp;; c'est ainsi que &nagios; fonctionne.
</para>
</sect2>
<sect2 id="slonymrtg">
<title>Surveiller &slony1; avec MRTG</title>
<indexterm><primary>Utiliser MRTG pour surveiller la réplication</primary></indexterm>
<para>
Un utilisateur a expliqué sur la liste de discussion de &slony1; comment
configurer <ulink url="http://people.ee.ethz.ch/~oetiker/webtools/mrtg/">
<application>MRTG</application></ulink> (acronyme de «&nbsp;Multi Router
Traffic Grapher&nbsp;») pour surveiller une réplication &slony1;.
</para>
<para>
[...] puisque j'utilise <application>MRTG</application> pour visualiser les
données depuis plusieurs serveurs, j'utilise SNMP
(<application>net-snmp</application> pour être exact). Pour un serveur de
bases de données, j'ai ajouté la ligne suivante à la configuration de
<application>snmpd</application>&nbsp;:
</para>
<programlisting>
exec replicationLagTime /cvs/scripts/snmpReplicationLagTime.sh 2
</programlisting>
<para>
avec <filename>/cvs/scripts/snmpReplicationLagTime.sh</filename> contenant
ceci&nbsp;:
</para>
<programlisting>
#!/bin/bash
/home/pgdba/work/bin/psql -U pgdba -h 127.0.0.1 -p 5800 -d _DBNAME_ -qAt -c
"select cast(extract(epoch from st_lag_time) as int8) FROM _irr.sl_status
WHERE st_received = $1"
</programlisting>
<para>
Ensuite, dans la configuration de mrtg, j'ai ajouté la cible suivante&nbsp;:
</para>
<programlisting>
Target[db_replication_lagtime]:extOutput.3&amp;extOutput.3:public at db::30:::
MaxBytes[db_replication_lagtime]: 400000000
Title[db_replication_lagtime]: db: replication lag time
PageTop[db_replication_lagtime]: &lt;H1&gt;db: replication lag time&lt;/H1&gt;
Options[db_replication_lagtime]: gauge,nopercent,growright
</programlisting>
<para>
De son coté, Ismail Yenigul propose une méthode pour surveiller
&slony1; en utilisant <application>MRTG</application> sans installer
<application>SNMPD</application>.
</para>
<para>
Voici sa configuration MRTG&nbsp;:
</para>
<programlisting>
Target[db_replication_lagtime]:`/bin/snmpReplicationLagTime.sh 2`
MaxBytes[db_replication_lagtime]: 400000000
Title[db_replication_lagtime]: db: replication lag time
PageTop[db_replication_lagtime]: &lt;H1&gt;db: replication lag time&lt;/H1&gt;
Options[db_replication_lagtime]: gauge,nopercent,growright
</programlisting>
<para>
Et voici sa version modifiée du script&nbsp;:
</para>
<programlisting>
# cat /bin/snmpReplicationLagTime.sh
#!/bin/bash
output=`/usr/bin/psql -U slony -h 192.168.1.1 -d endersysecm -qAt -c
"select cast(extract(epoch from st_lag_time) as int8) FROM _mycluster.sl_status WHERE st_received = $1"`
echo $output
echo $output
echo
echo
# end of script#
</programlisting>
<note>
<para>
MRTG attend quatre lignes en provenance du script. Puisque le script n'en
fournit que deux, la sortie doit être prolongée de deux lignes.
</para>
</note>
<para>
Autrement, Ismail Yenigul indique comment il a géré la surveillance de Slony
en utilisant <application>MRTG</application> sans installer
<application>SNMPD</application>.
</para>
<para>
Voici la configuration de mrtg&nbsp;:
</para>
<programlisting>
Target[db_replication_lagtime]:`/bin/snmpReplicationLagTime.sh 2`
MaxBytes[db_replication_lagtime]: 400000000
Title[db_replication_lagtime]: db: replication lag time
PageTop[db_replication_lagtime]: &lt;H1&gt;db: replication lag time&lt;/H1&gt;
Options[db_replication_lagtime]: gauge,nopercent,growright
</programlisting>
<para>
et voici une version modifiée du script&nbsp;:
</para>
<programlisting>
# cat /bin/snmpReplicationLagTime.sh
#!/bin/bash
output=`/usr/bin/psql -U slony -h 192.168.1.1 -d endersysecm -qAt -c
"select cast(extract(epoch from st_lag_time) as int8) FROM _mycluster.sl_status WHERE st_received = $1"`
echo $output
echo $output
echo
echo
# end of script#
</programlisting>
<note>
<para>
MRTG attend quatre lignes du script et comme il n'y a que deux lignes
fournies, l'affichage doit se voir ajouter quatre lignes.
</para>
</note>
</sect2>
<sect2 id="search-logs">
<title><command>search-logs.sh</command></title>
<indexterm><primary>chercher dans les journaux applicatifs &slony1; avec search-logs.sh</primary></indexterm>
<para>
Ce script est construit pour chercher dans les journaux applicatifs &slony1;,
à un emplacement donné (<envar>LOGHOME</envar>), en se basant à la fois
sur les conventions de nommage utilisées par les systèmes <xref
linkend="launchclusters"/> et <xref linkend="slonwatchdog"/> lors du
démarrage des processus &lslon;.
</para>
<para>
Si des erreurs sont trouvées, elles sont listées pour chaque fichier et
transmises par courriel à un utilisateur spécifié
(<envar>LOGRECIPIENT</envar>)&nbsp;; si aucun courriel n'est spécifié, le
résultat est affiché sur la sortie standard.
</para>
<para>
<envar>LOGTIMESTAMP</envar> permet de rechercher à partir de cette (plutôt
sur la dernière heure).
</para>
<para>
Un administrateur peut exécuter ce script une fois par heure pour surveiller
les problèmes de réplication.
</para>
</sect2>
<sect2 id="wikigen">
<title>Produire un rapport de surveillance au format MediaWiki</title>
<indexterm><primary>générer la documentation Wiki d'un cluster</primary></indexterm>
<para>
Le script <filename>mkmediawiki.pl </filename>, situé dans
<filename>tools</filename>, peut être utilisé pour générer un rapport de
surveillance du cluster compatible avec le populaire logiciel <ulink
url="http://www.mediawiki.org/">MediaWiki</ulink>. Notons que l'option
<option>--categories</option> permet à l'utilisateur de préciser un ensemble
de catégories (séparées par une virgule) qui seront associées aux résultats.
Si vous avez passer l'option <option>--categories=slony1</option> à une série
de clusters &slony1;, cela entraînera la création d'une page catégorie
répertoriant l'ensemble des clusters &slony1;.
</para>
<para>
On pourra utiliser le commande ainsi&nbsp;:
</para>
<screen>
~/logtail.en> mvs login -d mywiki.example.info -u "Chris Browne" -p `cat ~/.wikipass` -w wiki/index.php
Doing login with host: logtail and lang: en
~/logtail.en> perl $SLONYHOME/tools/mkmediawiki.pl --host localhost --database slonyregress1 --cluster slony_regress1 --categories=Slony-I > Slony_replication.wiki
~/logtail.en> mvs commit -m "More sophisticated generated Slony-I cluster docs" Slony_replication.wiki
Doing commit Slony_replication.wiki with host: logtail and lang: en
</screen>
<para>
Notons que <command>mvs</command> est un client Mediawiki écrit en Perl&nbsp;;
sur <ulink url="http://www.debian.org/">Debian GNU/Linux</ulink>, le paquet
associé est nommé <application>libwww-mediawiki-client-perl</application>&nbsp;;
d'autres systèmes disposent probablement d'une version packagée sous un nom
similaire.
</para>
</sect2>
<sect2>
<title>Analyse d'un SYNC</title>
<para>
Ce qui suit est un extrait du log &lslon; (version 2.0) pour le n&oelig;ud
#2 dans une exécution de <quote>test1</quote> à partir de <xref linkend="testbed"/>.
</para>
<screen>
DEBUG2 remoteWorkerThread_1: SYNC 19 processing
INFO about to monitor_subscriber_query - pulling big actionid list 134885072
INFO remoteWorkerThread_1: syncing set 1 with 4 table(s) from provider 1
DEBUG2 ssy_action_list length: 0
DEBUG2 remoteWorkerThread_1: current local log_status is 0
DEBUG2 remoteWorkerThread_1_1: current remote log_status = 0
DEBUG1 remoteHelperThread_1_1: 0.028 seconds delay for first row
DEBUG1 remoteHelperThread_1_1: 0.978 seconds until close cursor
INFO remoteHelperThread_1_1: inserts=144 updates=1084 deletes=0
INFO remoteWorkerThread_1: sync_helper timing: pqexec (s/count)- provider 0.063/6 - subscriber 0.000/6
INFO remoteWorkerThread_1: sync_helper timing: large tuples 0.315/288
DEBUG2 remoteWorkerThread_1: cleanup
INFO remoteWorkerThread_1: SYNC 19 done in 1.272 seconds
INFO remoteWorkerThread_1: SYNC 19 sync_event timing: pqexec (s/count)- provider 0.001/1 - subscriber 0.004/1 - IUD 0.972/248
</screen>
<para>
Voici quelques notes pour interpréter cet affichage&nbsp;:
</para>
<itemizedlist>
<listitem>
<para>
Notez la ligne qui indique
<screen>inserts=144 updates=1084 deletes=0</screen>
</para>
<para>
Ceci indique le nombre de lignes touchées par ce SYNC.
</para>
</listitem>
<listitem>
<para>
Notez la ligne qui indique
<screen>0.028 seconds delay for first row</screen>
</para>
<para>
Ceci indique le temps que <screen>LOG cursor</screen> a pris pour
traiter la première ligne de données. Habituellement, ceci prend du
temps si le SYNC est important et nécessite un tri d'un ensemble
de résultats.
</para>
</listitem>
<listitem>
<para>
Notez la ligne qui indique
<screen>0.978 seconds until close cursor</screen>
</para>
<para>
Ceci indique la durée du traitement par le fournisseur.
</para>
</listitem>
<listitem>
<para>sync_helper timing: large tuples 0.315/288</para>
<para>
Cet élément séparé est le nombre de grosses lignes
(<emphasis>c'est-à-dire</emphasis> dont la taille dépasse la valeur du
paramètre de configuration <xref linkend="slon-config-max-rowsize"/>).
Ces lignes ont été traités individuellement.
</para>
</listitem>
<listitem>
<para><screen>SYNC 19 done in 1.272 seconds</screen></para>
<para>
Ceci indique qe le traitement a pris au total 1.272 secondes pour cet
ensemble de SYNC.
</para>
</listitem>
<listitem>
<para>
<screen>SYNC 19 sync_event timing: pqexec (s/count)- provider 0.001/1 - subscriber 0.004/0 - IUD 0.972/248</screen>
</para>
<para>
Ceci enregistre une information sur le nombre de requêtes lancées sur les
fournisseurs et abonnés dans la fonction <function>sync_event()</function>
ainsi que le temps pris pour cela.
</para>
<para>
Notez que 248 ne correspond pas aux nombres d'INSERT/UPDATE/DELETE
décrits précédemment car ces requêtes sont groupées pour être soumises
via un seul appel à <function>pqexec()</function> sur le fournisseur.
</para>
</listitem>
<listitem>
<para>
<screen>sync_helper timing: pqexec (s/count)- provider 0.063/6 - subscriber 0.000/6</screen>
</para>
<para>
Ceci enregistre l'information du nombre de requêtes exécutées sur les
fournisseurs et les abonnés dans la fonction <function>sync_helper()</function>,
ainsi que le temps pris pour cela.
</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>