[TSFA] 201011 MySQL Audit

Transcription

[TSFA] 201011 MySQL Audit
MySQL Rapport
d'intervention
OUAT
ENTERTAINMENT
DRAFT
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
1 / 38
CONFIDENTIAL
MySQL® Services
1 novembre 2010
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
2 / 38
CONFIDENTIAL
Table des matières
1.1 Contexte .................................................................................................................................... 5
2 Informations administratives............................................................................................................. 6
2.1 Client .........................................................................................................................................6
2.2 Équipe ....................................................................................................................................... 6
3 Préconisations....................................................................................................................................7
3.1 Version MySQL >= 5.1.46 Innodb plugin 1.0.7........................................................................ 7
3.2 Configuration InnoDB.............................................................................................................. 8
Dimension des Redo-log ............................................................................................................ 8
Dimension du Buffer Pool ......................................................................................................... 9
ACID .......................................................................................................................................... 9
3.3 max_connections....................................................................................................................... 9
3.4 Flush method............................................................................................................................10
3.5 Système configuration ............................................................................................................ 10
3.6 Index en double .......................................................................................................................10
3.7 Index non discriminants........................................................................................................... 11
Optimisation requêtes :..............................................................................................................11
3.8 Partitionnement ....................................................................................................................... 12
3.9 Scalabilité.................................................................................................................................13
Scalabilité en écriture/lecture....................................................................................................13
Scalabilité en lecture uniquement............................................................................................. 13
4 Sauvegarde/ Restauration................................................................................................................ 14
4.1 Mysqldump.............................................................................................................................. 14
4.2 Import – Export .......................................................................................................................15
4.3 Innodbhotbackup..................................................................................................................... 15
5 Architecture HA et continuité du service.........................................................................................15
MySQL réplication : asynchrone ............................................................................................ 16
5.1 MySQL Cluster ....................................................................................................................... 17
Tableau récapitulatif .................................................................................................................18
5.2 Bench et chargement de la base de données............................................................................ 18
5.3 Procédure , maintenance préventive........................................................................................ 19
6 Bonnes pratiques de développement............................................................................................... 19
EVITER LIKE %xx% sur de grosses tables............................................................................. 20
Eviter NULL ............................................................................................................................ 20
et les SELECT * (si possible).................................................................................................. 21
Eviter la fonction rand() dans les requête MySQL ................................................................ 21
Type de champs.........................................................................................................................21
Utiliser latin1 au lieu de utf8 ....................................................................................................22
Convertir blob et texte en varbinary et varchar ........................................................................22
Pagination et LIMIT N,M......................................................................................................... 24
Sous requêtes avec IN .............................................................................................................. 25
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
3 / 38
CONFIDENTIAL
Sous requêtes avec NOT IN..................................................................................................... 25
Index non utilisés...................................................................................................................... 26
Index manquants....................................................................................................................... 26
Index sur une partie d'un champ ............................................................................................. 27
Forcer l'ordre des jointures........................................................................................................28
Optimisation des ORDER BY.................................................................................................. 28
Optimisation des GROUP BY ..................................................................................................28
Transformer les sous requêtes en jointure :...............................................................................30
6.1 Réplication, liens utiles............................................................................................................31
7 Plan d'action.....................................................................................................................................33
8 Annexes........................................................................................................................................... 33
8.1 Plan stockage........................................................................................................................... 33
8.2 Multi instances......................................................................................................................... 35
8.3 Métrologie et montée en charge..............................................................................................35
8.4 Monitoring............................................................................................................................... 37
Bench avec Mysqlslap.............................................................................................................. 37
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
4 / 38
CONFIDENTIAL
1.1
Contexte
La mission d'expertise consiste à auditer l'installation, l'optimisation, tunning et
l'architecture HA utilisés.
L'audit a conduit à l'identification de plusieurs point à améliorer. Nous pouvons résumer les
plus critiques par ordre d'importance :
1. La mise en place d'un serveur en stand by est recommandé pour la continuité du service en
cas de crash du serveur MYSQL suite à une panne matérielles ou autres.
2. Un upgrade MySQL vers une version plus récente (>=5.1.47) ou au moins vers InnoDB
plugin 1.0.7 est préconisé.
3. Les paramètres les plus critiques de configuration du serveur MySQL/InnoDB ont été
discuté.
4. Attention, le ré-démarrage du serveur peut prendre un certains temps (jusqu'à 20mn et plus).
Voir redo-log
5. Une installation de MySQL avec ubuntu a été effectué. Elle n'est pas recommandées. Elle
est en retard de presque 2 ans (20 mois ) de plus elle n'a pas le plugin Innodb stable.
6. Une autre installation à partir du site MySQL a été réalisé et configuré pour Innodb plugin.
7. La sauvegarde a été optimisé
8. La maintenance préventive est à mettre en place
9. Certaines structures et index et requêtes sont à optimiser
10. La gestion des transactions est recommandé pour l'intégrité de la base.
11. La scalabilité est un des points fort bien discuté pour l'évolutivité de l'application
12. Pour la HA : la réplication est une solution qui a plus d'avantage par rapport à DRDB
13. Une optimisation après coup sur mesure de la production ou du contexte proche de la
production est recommandé.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
5 / 38
CONFIDENTIAL
2
Informations administratives
2.1Client
Client
Nom du projet
Adresse
OUAT ENTERTAINMENT
197, rue de Bordeaux 16 000 Angoulême FRANC
2.2 Équipe
Nom
Compagnie
Fabrice
PASSAQUAY
OUAT
ENTERTA
INMENT
Zemrag Omar
ORACLE /
MySQL
Position
téléphone
Courriel
05 45 38 40 15
fpassaquay@ouat+33
e.com
0177132703
Solution
Architecte
33 6734842 62
[email protected]
Note: Toutes recommandations fournis dans le présent rapport sont uniquement basées sur notre expérience générale . Nous vous
conseillons de faire des tests avant toutes mise en pratique des recommandations sur un système de production.
Garder en mémoire de faire une sauvegarde complète avant l'implémentation des changements préconisés.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
6 / 38
CONFIDENTIAL
3
Préconisations
3.1
Version MySQL >= 5.1.46 Innodb plugin
1.0.7
Recommandation : Nous vous recommandons d'installer >= MySQL 5.1.46 Innodb plugin
1.0.7
Gain : Les performance passe à plus de 10 – 300% entre InnoDB 5.0 avec Innodb plugin
1.0.7 (>MySQL 5.1.46)
Procédure upgrade avec mysqldump :
1. sauvegarder vos données et vos binaires
sauvegarde logique des bases de données et des users avec mysqldump
stoper le serveurs mysql et sauvegardez à froid tous les repértoires de données et les fichiers
de configuration (autant dire q'une sauvegarde globale est souhaité)
Maintenant on une sauvegarde physique (servira pour un retour plus rapide) et une
sauvegarde logique des données uniquement (qui servira pour l'upgrade aussi)
2. Installer le serveur MySQL 5.1.55 du serveur mysql
wget du fichier .tar.gz
tar -xzvf fichier .tar.gz
suivre les étapes du fichier INSTALL
configurer correctement le fichier my.cnf :
Pour le multi instances : paramètres my.cnf à modifier
basedir
= /usr/local/mysql # binaire
datadir
= /var/lib/mysql # données
pid-file
= /var/run/mysqld/mysqld.pid
socket
= /var/run/mysqld/mysqld.sock
port
= 3306
plus 2 variables d'environnement à mettre à jour pour travailler sur chaque instance
MySQL_HOME= /var/lib/mysql
PATH=usr/local/mysql:$PATH
3. redémarrer le serveur MYSQL
utiliser le script mysql.server pour démarrer et stoper le service en mettant à jour :
basedir=/usr/local/mysql
datadir=/var/lib/mysql
vérifier que le plugin est installé : show plugins;
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
7 / 38
CONFIDENTIAL
4.
5.
6.
7.
importer le dump logique
tester quelques opérations
ouvrez le service sur dev et tester le
ensuite ouvrer le service prod et vérifier le avant de l'ouvrir à grande échelle
Configuration Innodb plugin
[mysqld]
ignore-builtin-innodb
pluginload=innodb=ha_innodb_plugin.so;innodb_trx=ha_innodb_plugin.so;innodb_locks=ha_innodb_plugi
n.so;innodb_lock_waits=ha_innodb_plugin.so;innodb_cmp=ha_innodb_plugin.so;innodb_cmp_reset=
ha_innodb_plugin.so;innodb_cmpmem=ha_innodb_plugin.so;innodb_cmpmem_reset=ha_innodb_plugin.
so
innodb_file_format=barracuda
innodb_file_per_table=1
Autres options lié à Innodb plugin à tester
innodb_thread_concurrency=32
innodb_io_capacity=200
# InnoDB with the patch to use multiple background IO threads
innodb_read_io_threads=4
innodb_write_io_threads=4
Gain : Les performance vont jusqu'à 35% plus que 5.1 avec Innodb plugin 1.0.7
Abstract : MySQL a été amélioré afin de profiter de la puissance des nouvelles
architectures. La scalabilité et la performance s'en trouvent grandement amélioré. La
version 5.1 apporte une nouvelle architecture basé sur les plugins. Les plugins permettent de
charger ou décharger des librairies partagées dans une instance MySQL en cours
d'exécution. Pour ajouter ou supprimer une fonctionnalité, faire un upgarde d'un moteur, on
n'a plus besoin de compiler ou d'arrêter l'instance MySQL. Il suffit de charger ou décharger
dynamiquement les plugins concernés. http://dev.mysql.com/doc/refman/5.1/en/pluginapi.html
InnoDB plugin est une nouvelle version du moteur InnoDB qu'on peut utiliser à partir de la
version MySQL 5.1.46. InnoDB 5.0 limite le nombre d'IO/s sur checkpoint a 100 IO/s de
16K ce qui nous amène à une écriture possible de 16x100=1600K/s. Théoriquement on peut
aller jusqu'à 1600K/s. La version 5.1.46 en Innodb plugin n' a pas de limitation des IO sa
capacité est donc limité uniquement par les capacités de votre infrastructure en entrée sortie
(disques).
http://www.innodb.com/products/innodb_plugin/features/
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
8 / 38
CONFIDENTIAL
3.2
Configuration InnoDB
Dimension des Redo-log
Afin d'absorber les fortes charges en écritures et réduire le temps du restart du serveur
MySQL, nous vous conseillons de choisir une valeur qui donne les performances
satisfaisante sans alourdir de trop le ré-démarrage. Bencher le pour trouver la valeur
optimale pour votre cas. Notre retour d'expérience donne une valeur généralement optimale
pour 512M : 1G peut être trop haute ( à diviser par deux.)
innodb_log_file_size=512M
Note très importante : la taille des logs transactionnels influence le temps d'arrêt ou de
redémarrage après crash.
Attention pour modifier la taille des Redo log :
stopper le serveur
Avant de re-démarrer le serveur déplacer (et ne les supprimer que si tout va bien) les
ib_log* base arrêtée pour appliquer un changement de taille.
Re-démarrer le serveur MySQL
Pour les esclave cette taille peut être encore augmenté
Abstract : Il représente la taille des journaux innodb dans un groupe (2 par défaut) on
recommande 25%-100% du buffer pool size.
Dimension du Buffer Pool
Afin d'absorber les fortes charges en lecture nous vous conseillons jusqu'à 80% de la RAM
d'un serveur dédié. Le plus le mieux :
innodb_buffer_pool_size=12 G
ACID
innodb_flush_log_at_trx_commit=1
Abstract : Pour plus de performances en écriture nous pouvons relâcher cette contrainte en
paramétrant la valeur a 2. Les fsync assurant l'écriture physique par désactivation des caches
ne seront exécutés que sur checkpoint et non plus lors de chaque COMMIT de transaction.
Dans cette hypothèse au maximum 1 seconde d'écritures peuvent être perdu lors d'un arrêt
brutal de la machine. Sur les esclaves réservé aux lectures cette valeur peut être relâché.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
9 / 38
CONFIDENTIAL
3.3
max_connections
mysql> show status like '%used%';
+--------------------------------+-------+
| Variable_name
| Value |
+--------------------------------+-------+
| Max_used_connections
| 517
|
+--------------------------------+-------+
6 rows in set (0.00 sec)
Nous vous préconisons une valeur <900 vers une valeur que le
serveur peut supporter. Cette valeur peut être benché : de 100 à 600
au maxi peut être une bonne valeur.
3.4
Flush method
Généralement, on peut optimiser les IO avec cette option
innodb_flush_method=O_DIRECT
3.5
Système configuration
IO scheduler deadline
Utiliser le IO scheduler deadline (ou noop) plutôt que celui par défaut (cfq)
# vim /boot/grub/menu.lst
# kopt = [...] elevator=deadline
# update-grub
# reboot
Désactiver l'enregistrement du temps d'accès aux fichiers pour ext3
Dansl le fichier /etc/fstab, ajouter noatime aux options de montage.
Exemple :
/dev/sda1/
ext3
defaults,errors=remount-ro,noatime 0
Désactiver la mise en swap automatique après plus de 40% de mémoire vive
utilisée :
Dans le fichier /etc/sysctl.conf ,Ajouter/Modifier la ligne :
sys.vm.swappiness = 0
Il est possible d'appliquer à chaud cette modification avec la commande :
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
10 / 38
CONFIDENTIAL
# sysctl -p
3.6
Hardware
CPU
Pour une instance préférer la CPU la plus puissante surtout pour les slaves en stand by
Disques
Plus de disques vous donne plus d’options
Eclater les données sur plusieurs disques afin d’augmenter les débits
Nous recommandons l'utilisation du RAID10 avec des contrôleurs multi-canaux et une
batterie de cache (BBU). Cependant le SAN constitue aussi une bonne solution.
RAM
Nous recommandons le plus de RAM possible pour couvrir la volumétrie active si possible
100% si non on au moins 25% du « working set » qui dépend de l'applicatif.
3.7
Index en double
Priorité: moyenne
Recommandation : supprimer les index en double : INDEX(A,B) et INDEX(A)
INDEX(A) est inutile.
Gain : + de performance
Abstract : Pour accelérer ses recherche MySQL, peut utiliser un préfix (une sous partie
gauche ) d'un index. Conséquence : lorsque un champ indexé INDEX(A) fait partie d'un
préfixe gauche d'un autre index INDEX(A,B) celui ci (INDEX(A)) est inutile. Or un index
en double consomme inutilement des ressources. A chaque mise à jour de la table, on doit
mettre à jour des index en double.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
11 / 38
CONFIDENTIAL
3.8
Index non discriminants
Recommandation : supprimer les index non discriminants et non utilisé
Abstract : Les index doivent avoir une cardinalitée (Cardinality) forte (un index sur la
civilité M, MME, MLLE ne sert absolument à rien) par contre un index sur un code regate
est beaucoup plus discriminant.
La commande ci-dessous permet de lister les index d'une table :
mysql> SHOW INDEX FROM matable
ATTENTION : un index avec une cardinalité faible peut être intéressant s'il est très sélectif
sur une partie des données par exemple une table contenant des données actives (quelques
centaines) et des données archives (quelques millions) peut avoir un index sur un booleen
indiquant archive ou actif
Note : une cardinalité faible peut être intéressante dans le cas ou il est placé en second d'un
index composite (composé de plusieurs champs) : KEY (`nom`,`CIVILITE`)
Optimisation requêtes :
Eviter les focntion sur les clause where
exemmple : monchamp & 1= 0
ou
FROM_UNIXTIME( p.creation_date,'%Y-%m-%d') > DATE_SUB( '2010-10-27',
INTERVAL 1 DAY)
SELECT^M
FROM_UNIXTIME(p.creation_date,'%Y/%m/%d %a') date,^M
count(c.app_user_id) as counter,^M
count(p.id)-count(c.app_user_id) as counter_bad^M
FROM^M
profiles p^M
LEFT JOIN channels_app_users c ON c.app_user_id = p.id^M
WHERE^M
FROM_UNIXTIME( p.creation_date,'%Y-%m-%d') > DATE_SUB( '2010-10-27',
INTERVAL 1 DAY)^M
/* AND p.status != 1 AND p.status != 129 */^M
GROUP BY date^M
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
12 / 38
CONFIDENTIAL
ORDER BY date ASC;
3.9
Partitionnement
Recommandation : Utiliser le partitionning sur les grosses tables
Abstract : L’une des fonctions les plus intéressantes de MySQL 5.1 est son support du
partitionnement horizontal des données, à la fois pour les tables et les index. Les principales
formes de partitionnement sont supportées par les principaux moteurs de stockage de
MySQL :
Le partitionnement procure un certain nombre d’avantages :
De meilleures performances – lors des opérations de balayage, l’optimiseur MySQL sait
quelles sont les partitions contenant les données qui satisferont telle ou telle requête et
n’accédera qu’à ces partitions lors de l’exécution de la requête. Par exemple, une table d’un
million de lignes peut être divisée par plage en dix partitions différentes de façon que
chacune d’entre elles contienne 100 000 lignes. Si une requête n’a besoin que des données
d’une seule de ces partitions et qu’une opération de balayage de la table s’avère nécessaire,
le système n’accédera qu’à 100 000 lignes au lieu d’un million. MySQL vérifiant
évidemment plus vite 100 000 lignes qu’un million, la requête sera donc achevée bien plus
tôt.
• Une gestion des données simplifiée – le partitionnement permet aux DBA de mieux
contrôler la façon dont les données sont gérées au sein de la base de données. En créant
intelligemment des partitions, un DBA peut simplifier l’exécution de certaines opérations
sur les données. Il peut par exemple supprimer certaines partitions d’une table partitionnée
et laisser les autres intactes (plutôt que d’élaborer une opération de suppression en masse
dans la table, génératrice de fragmentation) .
Note : garder à l'esprit que le partitionning est nouveau dans MySQL 5.1. Il convient de le
tester avec soins avant mise en production. Certaines fonctions évolués ne sont pas encore
disponible. Par exemple, on ne peut pas ajouter une partition type range au milieu des
partitions. On ne peut pas restaurer une partition supprimé sauf à passer par des insert
classiques.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
13 / 38
CONFIDENTIAL
3.10 Scalabilité
Scalabilité en écriture/lecture
Pour scaller les écriture on utilise le partitionnement fonctionnel. Il s'agit de partager les
données de manière horizontale. Le principe consiste à identifier des données indépendantes
les unes des autres de manière à pouvoir les séparer sur une base de données dédiée. En cas
de montée en charge on peut dédier à cette base de données une instance MySQL sur le
même serveur hôte ou sur un autre hôte dédié. De cette manière on peut scaller chaque base
de données de manière efficace et économique. On s'adapte de manière plus fine et plus
flexible à chaque type de données. De plus la fiabilité et la performance se trouvent amélioré
(un crash d'une base pas d'effet sur les autres bases, les cash sont plus stable)
les stats peuvent être dirigé sur une autre instance (même en MyISAM)
Les tables liés aux objets à l'exception de my_objects peuvent être dédié à une instance
Remarque : Cacher les données objets lié à un user sur une web serveur est recommandé.
On peut dédier une instance à chaque type d'usage exemple : les utilisateur qui s'enregistre
pour la première fois et qui font des recherches. Cela nécessite plus d'effort au niveau du
désign en fonction des possibilités de l'applicatif.
Scalabilité en lecture uniquement
Généralement, on rencontre en premier, un besoin en scalabilité en lecture. La réplication
MySQL en asynchrone native a été largement déployé pour répondre à ce besoin.
La scalabilité en lecture est facile avec MySQL il suffit d'ajouter des esclaves
Read
Appli
scalabilite
Lecture
Write
7
7 11
12
12
replication
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
14 / 38
CONFIDENTIA
Les écritures et les lectures qui ne tolère aucun décalage ne peuvent pas être scallées.
4
Sauvegarde/ Restauration
4.1
Mysqldump
L'option --single-transaction sur toutes les bases permet de prendre une image cohérente de
la base et pénalise moins le serveur MySQL
mysqldump -uroot -p'xxxxxxxxx' -h"126.X.Y.Z"
blob
--add-drop-database > dump.Sql
--single-transaction
--all-databases --hex-
avec la réplication :
mysqldump -uroot -p'xxxxxxxxx' -h"126.X.Y.Z" --single-transaction --master-data=2 --flushlogs --triggers --routines --all-databases --hex-blob
--add-drop-database > dump.Sql
master-data pour générer la synchronisation avec les log-bin
flush-logs crée un nouveau fichier bin log
Avec Innodb, utiliser single-transaction
Gain : données intègres, sauvegardes non blocantes
Remarque avec MyISAM utiliser lock-all-tables : compte tenu de la nom utilisation des
transactions, pour garder l'intégrité de la base il faut locker toutes les tables
Impact: Attention le service se dégrade(InnoDB) voir indisponible (MyISAM) pendant la
sauvegarde.
Le cache du serveur a été modifié pour la sauvegardes (On peut éventuellement le
réchauffer après la sauvegrade)
La restauration des données se fait par un client mysql
mysql -uroot -p'xxxxxxxxx' <dump.sql
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
15 / 38
CONFIDENTIA
4.2
Import – Export
La commande LOAD DATA INFILE lit les lignes dans un fichier texte et les insère à très grande vitesse.
Pour plus d'informations sur l'efficacité des commandes INSERT comparativement à LOAD DATA INFILE
et pour accélérer les commandes LOAD DATA INFILE, voyez Section 7.2.14, « Vitesse des requêtes
INSERT ».
Vous pouvez aussi charger des fichiers de données en utilisant l'utilitaire mysqlimport; Il
opère en envoyant la commande LOAD DATA INFILE au serveur. L'option --local fait
que mysqlimport lit les fichiers de données chez le client. Vous pouvez spécifier l'option
--compress pour avoir de meilleurs performances avec les connexions lentes si le client
et le serveur supportent le protocole compressé. See Section 8.10, « mysqlimport, importer
des données depuis des fichiers texte ».
Pour la commande LOAD DATA INFILE sur des fichiers du serveur, vous devez avoir le
droit de FILE sur le serveur. See Section 5.5.3, « Droits fournis par MySQL ».
Utiliser LOCAL est plus lent que de laisser le serveur accéder directement aux fichiers, car le
contenu du fichier doit être envoyé via le réseau au serveur. D'un autre coté, vous n'aurez pas
besoin de droits de FILE pour faire un chargement local.
Depuis MySQL 3.23.49 et MySQL 4.0.2 (4.0.13 sur Windows), LOCAL fonctionne
uniquement si votre serveur et votre client ont été configuré pour. Par exemple, si mysqld a
été lancé avec --local-infile=0, LOCAL ne fonctionnera pas. See Section 5.4.4,
« Problèmes de sécurité avec LOAD DATA LOCAL »
4.3
Innodbhotbackup
Innodbhotbackup peut être plus rapide qu'une alimentation par requête replace ou load data
http://www.innodb.com/products/hot-backup/order/
5
Architecture HA et continuité du service
Généralement, on rencontre en premier, un besoin de HA en lecture. La réplication MySQL
en asynchrone native a été largement déployé pour répondre à ce besoin. Dans des cas ou on
souhaite la haute disponibilité à moindre cout avec un risque de perte de données cette
solution a aussi été utilisé en master-master, actif-passif (dual master). Pour les applications
OLTP classiques qui ne tolèrent aucun décalage ni perte de données nous recommandons
DRBD/HeartBeat.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
16 / 38
CONFIDENTIA
•
•
•
•
•
Le principaux avantage de la réplication / DRDB :
Facilité de prise en main et très utilisé dans le web.
Esclave peut être utilisé : pour les lecture, reporting, pour les réorganisations, les upgrades,
les sauvegardes en ligne, les upgarde, l'exploitation est facilité ...
Certaine erreur humaines ou corruptions de données ne seront pas propagé à l'esclave ( ex:
dd sur un file système du master n'affectera pas l'esclave)
En cas de fail-over Il n'est pas nécessaire de faire un recover avec InnoDB
performance et scalabilité en lecture plus facile
Un des inconvénients /DRDB : volume de données (data seulement) en double, risque de
perte ou décalage de données avec de la vidéo en ligne
Remarque : Notez que DRDB que est une autre solution open source très utilisé avec
MySQL est supporté par ORACLE/MySQL.
MySQL réplication : asynchrone
VIP s1
Write
Read
Actif
Passif
m1
m2
Avantages
Facile à configurer et à utiliser
Inconvénients
Fail-over manuel ou passage
par heartbeat
Réplication natives depuis MySQL 3.23 Latence et perte de donnée possible
Indépendant du moteur
Nécessite un monitoring
Slave peut être promu maitre facilement
Fail-over rapide
Slave peut être utilisé en lecture
Slave peut être optimisé pour la lecture
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
17 / 38
CONFIDENTIA
Peut être utilisé pour le disaster recovery
(réplication géographique)
Possibilité de maintenance en ligne en
dual master : réorganisation en ligne,
suavegarde en ligne, upgrade en ligne, ...
On peut ajouter de répliquants très
facilement
Enormément de fonctionnalité avancée
( filtrer les bases de données, réplication
semi-synchrones, ...)
Moins sujet à la propagation des
corruption (bug en maj seulement)
5.1
MySQL Cluster
MySQL Cluster est la vraie solution de haute disponibilité, scalable en lecture et en écriture.
MySQL Cluster est excellent en forte concurrence sur beaucoup de transaction courtes.
C'est très utilisé dans les télécoms. Elle permet de faire des upgrade en ligne, ...
Cependant MySQL Cluster présente quelques limitations qui peuvent être contourné soit
nativement (réécritures des requêtes complexes) soit en utilisant un moteur adapté (comme
le moteur InnoDB) en parallèle au sein du même serveur ou sur un serveur dédié
En séparant le reporting du transactionnel on peut dédier le transactionnel au Cluster .
Avantages
Scalable horizontalement et
verticalement automatiquement
Inconvénients
Configuration complexe
Load balancing natif et automatique
Nécessite de revoir certaines jointures complexes
Le cout est plus élevé
Nécessite un réseau performant
Volumétrie des données doit être maitrisé
Foregin Key non géré
Nécessite au moins 3 machines
Upgrade en ligne
Sauvegarde en ligne
SAN non obligatoire
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
18 / 38
CONFIDENTIA
Tableau récapitulatif
Archi Existants
Perte de donnée
Durée fail-over
MySQL
Cluster
Non
Non
<1s
Réplication
Oui
Oui*
30s à 1h**
DRBD
NON
Non
30s à 30mn
SAN/heartbeat
NON
Non
30s à 30mn
*Les données perdu dépend de l'application et du hardware
**Avec perte de données, le temps de bascule dépend du réseau et du décalage entre le
slave et le maitre
5.2
Procédure , maintenance préventive
Pour répondre rapidement aux requêtes utilisateurs, les SGBD font des mise à jours sans
effectuer un ordonnancement complet des tables. Les données sont éparpillés.
La réorganisation permet de supprimer les trous éventuels , réordonne la table et les index et
met à jour les statistiques (nécessaire à l'optimiseur).
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
19 / 38
CONFIDENTIA
Nous vous recommandons de réorganiser régulièrement les tables au moins une fois par
semaine surtout pour les tables qui bougent très souvent suite aux update, delete, ...
Soit avec un client mysql :
mysql:root:dbtest> optimize table matable;
+----------------+----------+----------+----------+
| Table
| Op
| Msg_type | Msg_text |
+----------------+----------+----------+----------+
| dbtest.matable | optimize | status
| OK
|
+----------------+----------+----------+----------+
1 row in set (0.00 sec)
mysql:root:dbtest>
Soit avec le programme mysqlcheck
mysqlcheck dbtest matable -o
dbtest.matable
OK
Impact: cette action lock les tables et risque de dégrader fortement les performances voir
un arrêt du service. A lancer lorsque le serveur est en ligne et peux ou pas du tout sollicité
par les applicatifs.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
20 / 38
CONFIDENTIA
6
Bonnes pratiques de développement
Type de champs
Utiliser les types les plus petits possibles.
■ http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html
■ Privilégier les dates en format TIMESTAMP
■ Passage des champs contenant des valeurs statiques en Enum ou en set
http://dev.mysql.com/doc/refman/5.0/en/set.html
http://dev.mysql.com/doc/refman/5.0/en/enum.html
Analyse la structure optimale de la table pour une requête donnée
minimum/maximum de la longueur et de la valeur
compte de la valeur NULL et des valeurs zéro et vides
valeur moyenne et écart type
Suggère le type optimal du champ
mysql> SELECT name,population FROM city
-> WHERE population > 250000
-> PROCEDURE ANALYSE(8, 256) \G
************* 1. row ******************
Field_name: world.city.Name
Min_value: Aba
Max_value: +skemen
Min_length: 3
Max_length: 30
Empties_or_zeros: 0
Nulls: 0
Avg_value_or_avg_length: 8.3807
Std: NULL
Optimal_fieldtype: VARCHAR(30) NOT NULL
************* 2. row ******************
Field_name: world.city.Population
Min_value: 250121
Max_value: 10500000
Min_length: 6
Max_length: 8
Empties_or_zeros: 0
Nulls: 0
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
21 / 38
CONFIDENTIA
Avg_value_or_avg_length: 802699.3768
Std: 1155068.8492
Optimal_fieldtype: MEDIUMINT(8) UNSIGNED NOT NULL
Types courants de la colonne :
Nom : CHAR(35) NOT NULL
Population : INTEGER NOT NULL
Utiliser latin1 au lieu de utf8
Il est plus performant de mettre les bases en latin1. utf8 peut potentiellement prendre 3 fois
plus de place selon les cas.
Convertir blob et texte en varbinary et varchar
Toute requête sur un champ blob et texte qui requière des tables temporaires se feront sur
disque d'où la dégradation des performances.
a-Enlever les type blob et les type text dans la selection
b-Les transformer en varchar maxi 65535 par table : 65535 doit etre partagé sur toutes les
colonnes d'une table et depend du caracter set. Pour utf8 le max est de 21844
Type
Stockage requis*
Longueur max. (en caract.)
CHAR
Taille de colonne max.
255
VARCHAR
Taille de la valeur + 1-2 octets
65 535**
TINYTEXT
Taille de la valeur + 1 octet
255
TEXT
Taille de la valeur + 2 octets
65 535
MEDIUMTEXT
Taille de la valeur + 3 octets
16 777 215
LONGTEXT
Taille de la valeur22+/ 438octets
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
4 294 967 295
CONFIDENTIA
* La taille de chaque caractère dépend du jeu de caractères.
** La taille max. dépend du varchar de tous les type de colonnes de la table .
La requête sur les metadata pour generer les champ de type blob et texte
select TABLE_NAME,TABLE_SCHEMA,COLUMN_NAME,DATA_TYPE from columns
WHERE (DATA_TYPE like '%text%' or DATA_TYPE like '%blob%') and
TABLE_SCHEMA NOT IN ('mysql','information_schema')
order by 1;
Exemple :
SELECT SQL_NO_CACHE a.*,(CASE a.tri_manuel WHEN 999
THEN (recherche.pertinence + (a.tri_auto / 25))
ELSE (recherche.pertinence * (25 + (1/a.tri_manuel))) END ) as
popularite_pertinence ,
recherche.* FROM (SELECT count(*) nb_resultats ,
SUM(CASE mcp.id_mot_cle WHEN 33453 THEN mcp.poids / 1.65
WHEN 86180 THEN mcp.poids / 2.72
WHEN 319 THEN mcp.poids / 4.48 WHEN 1720 THEN mcp.poids /
7.39
WHEN 14262 THEN mcp.poids / 12.18 ELSE mcp.poids /
EXP(5*0.5) END)
pertinence,p.id_type_page,p.id_page_type
FROM rech__mot_cle_page mcp,rech__page p
WHERE p.id_page = mcp.id_page AND mcp.id_mot_cle IN
(33453,86180,319,1720,14262)
AND p.id_page = mcp.id_page
GROUP BY p.id_page
HAVING pertinence>=250
ORDER BY nb_resultats DESC )
as recherche , articles_enligne a, types_articles ta
Cette requête crée des tables temporaires
mysql> select max(length( ref_alt)), max(length(libelle)),
max(length(description)), max(length(specs_FR)),
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
23 / 38
CONFIDENTIA
max(length(specs_EN)), max(length(specs_IT)),
max(length(points_forts)), max(length(visu_galerie))
from marchand.articles_enligne
-> \G
*************************** 1. row
***************************
max(length( ref_alt)): 41
max(length(libelle)): 57
max(length(description)): 2033
max(length(specs_FR)): 6564
max(length(specs_EN)): 6564
max(length(specs_IT)): 6564
max(length(points_forts)): 488
max(length(visu_galerie)): 244
1 row in set (0.08 sec)
ces champs fde marchand.articles_enligne peuvent être mis en
varchar :
ref_alt → v archar(50) ...
analyse
EVITER LIKE %xx% sur de grosses tables
SELECT sql_no_cache expression_lisible as mot
FROM rech__historique
WHERE expression_lisible IS NOT NULL
AND expression_saisie LIKE '%tomtom%'
Eviter NULL
Déclarer les champs des tables avec NOT NULL par défaut sauf si la valeur NULL a un sens
pour votre application.
et les SELECT * (si possible)
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
24 / 38
CONFIDENTIA
Eviter la fonction rand() dans les requête MySQL
Exemple d'algo pour random : pré-génerer d'avance des valeurs aléatoires et les utiliser
−
−
−
−
ajouter une colonne indexée appelé « aleatoire » alimenté de manière aléatoire
utiliser order by aleatoire au lieu de order by rand()
une fois une ligne seléctionnée mettez la à jour par une autre valeur aléatoire
mettez périodiquement les valeurs aléatoires quand c'est nécessaire
Une autre technique ;
−
−
−
−
SELECT MAX(rowid) AS maxrowid FROM t1 LIMIT 1; (INNODB)
Excécuter random() function en php pour retourner une valeur X entre 0 et MAX(rowid)
SELECT col FROM t1 WHERE rowid >=X
Si 0 lignes retourné changer de direction dans le WHERE
Exemple :
select sql_no_cache tmp.* FROM
(SELECT expression_saisie FROM rech__historique WHERE auto=0
AND id_TA_dominant=18 ORDER BY
popularite_manuelle DESC,popularite_auto DESC
LIMIT 0,20)
as tmp
ORDER BY RAND() LIMIT 0,10
;
Pagination et LIMIT N,M
Priorité: haute
Recommandation : Nous vous recommandons d'éviter les requêtes avec 2 paramètres
LIMIT N,M. Privilégier LIMIT M avec 1 seul paramètre (sans OFFSET)
Abstract : Afin de limiter le nombre d'enregistrement retourné, il est possible d'utiliser la
clause LIMIT. Il faut faire très attention si on utilise la clause LIMIT avec 2 paramètres
(LIMIT X, Y) avec X numéro de la première occurrence à retourner, Y nombre
d'occurrences à retourner car le select * from matable LIMIT 10000,20 va nécessiter à mysql
de parcourir 10020 enregistrement et pas 20 comme on pourrait le penser. Il faut donc
privilégier l'utilisation de LIMIT avec un seul paramètre.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
25 / 38
CONFIDENTIA
Note : Attention à l'ordre dans le limit
Le limit s'effectue sur la dernière requête et pas sur l'ensemble des requetes
Trouver une technique de pagination sans OFFSET exemple :
Page suivante :
WHERE id < 200 /* dernier */
ORDER BY id DESC LIMIT $taille_page /* Plus d'offset */
Page Prec :
WHERE id > 190 /* dernier */
ORDER BY id DESC LIMIT $taille_page /* Plus d'offset */
Sous requêtes avec IN
Priorité: haute
Recommandation : Réécrire les requêtes lentes de type :
SELECT col FROM t1
WHERE id_col IN (SELECT id_col2 FROM t2 WHERE condition);
En :
SELECT col FROM t1, t2
WHERE t1.id_col = t2.id_col AND condition;
Abstract : Les jointures sont généralement plus rapide par rapport aux sous-requêtes. Les
sous requêtes ont été ajouté à MySQL depuis MySQL 5.0. Elles font encore l'objet
d'optimisation dans les prochaines versions MySQL.
Sous requêtes avec NOT IN
Priorité: moyenne
Recommandation : Réécrire les requêtes lentes de type :
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
26 / 38
CONFIDENTIA
SELECT t1.* FROM t1
WHERE t1.i NOT IN
(SELECT i FROM t2 WHERE condition)
En :
SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.i = t2.i AND condition
WHERE t2.i IS NULL
Abstract : Les jointures sont généralement plus rapide par rapport aux sous-requêtes. Les
sous requêtes ont été ajouté à MySQL depuis MySQL 5.0. Elles font encore l'objet
d'optimisation dans les prochaines versions MySQL.
Index non utilisés
Priorité: haute
Recommandation : Supprimez un index non utilisé même s'il est sélectif.
Abstract : Si aucune requêtes n'utilise l'index, il alourdit les mise à jour pour rien. On ne
peut pas savoir actuellement ,si un index est utilisé ou non sauf si on connait toutes les
requêtes utilisateurs.
Le moniteur (avec le Query anlayser) et le log général permettent de recenser toutes les
requêtes. Attention c'est consommateur de ressources, à utiliser avec beaucoup de
précaution. Ils (Log général et QUAN) dégradent les performances.
Index manquants
Priorité: haute
Recommandation : Ajouter des index quand c'est possible pour des requêtes lentes
Abstract : Certaine requêtes lentes peuvent être accélérer par l'ajout d'un index. Cela
nécessite d'analyser le plan d' exécution des requêtes :
Exemple :
mysql:> explain select * from t1 where i=1;
+----+-------------+-------+------+---------------+------+--------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref
| rows | Extra
|
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
27 / 38
CONFIDENTIA
+----+-------------+-------+------+---------------+------+--------+------+------+-------------+
| 1 | SIMPLE
| t1
| ALL | NULL
| NULL | NULL
| NULL
|
600000 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
Cette requête fait un ballayage de toute la table ( 600000 lignes)
En ajoutant un index
mysql:> ALTER TABLE t1 ADD INDEX (i);
on ne balaie plus que 2 lignes en utilisant l'index sur i
mysql> explain select * from t1 where i=1;
+----+-------------+-------+------+---------------+------+--------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref
| rows | Extra |
+----+-------------+-------+------+---------------+------+--------+-------+------+-------+
| 1 | SIMPLE
| t1
| ref | i
| i
| 4
|
const |
2 |
|
+----+-------------+-------+------+---------------+------+--------+-------+------+-------+
1 row in set (0.00 sec)
Impact: refonte appli
Delai : Durée de création de table (demande 2h)
Index sur une partie d'un champ
Priorité: moyenne
Recommandation : Créer un index sur une partie du champ discriminante
– Indexer les n premiers caractères d'un champs de type texte
Exemple si les 20 premiers caractères sont discriminants ajouter un index sur 20 char
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
28 / 38
CONFIDENTIA
mysql:> ALTER TABLE t1 ADD INDEX (monchamp(20));
Abstract :
Objectifs
– Minimiser la taille de l'index
– Ces n caractères doivent être suffisamment discriminants
– CREATE INDEX pref_index ON ma_table(col_text(30));
L'index est d'autant plus performante qu'il est en plus petit.(mais suffisamment discriminant)
Forcer l'ordre des jointures
Quelquefois l' optimiseur fait un choix plus lent :
SELECT STRAIGHT_JOIN colx FROM A,B WHERE
A.COL1=B.COL2
Couverture d'une requete par un index
 SELECT qte WHERE id=27
–Index sur (id,qte) utilise l'index et évite d'aller lire sur la table
Optimisation des ORDER BY



Couvrir par un index si possible
SELECT qte FROM art WHERE id=27 ORDER BY type
–Index sur (id,type) utilise l'index et évite de faire un tri en passant
par une table temporaire
En mémoire il utilise le buffer sort_buffer_size
Utiliser LIMIT si possible
Optimisation des GROUP BY
•Utilisez SQL_BIG_RESULT si les données à regouper sont volumineuse
(évite de créer une table temporaire mais utilise filesort)
•SELECT Fonction Agragation(B) FROM TBL GROUP BY A
Indexer sur (A,B)
•Ajouter ORDER BY NULL si vous n'avez pas besoin d' ordre MySQL trie
par défaut les GROUP BY
Exemple :
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
29 / 38
CONFIDENTIA
mysql> explain select SUM( (TR.quantity * ( TR.price * TR.currencyRate ) )
- ( TR.drm * TR.currencyRate ) ) AS FromBegin, TP.* FROM t_producteur
TP LEFT JOIN tRoyalties TR ON TR.idProducer = TP.id_producteur where
TP.accountManager=66 GROUP BY TP.producteur order by TP.producteur\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: TP
type: ref
possible_keys: accountManager
key: accountManager
key_len: 5
ref: const
rows: 62
Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: TR
type: ref
possible_keys: idProducer,idx_p
key: idx_p
key_len: 2
ref: TP.id_producteur
rows: 765
Extra:
2 rows in set (0.00 sec)
Eviter les tables temporaire (Using temporary+Using filesort)+ et trie en
ajoutant un index :
KEY `accountManager_2` (`accountManager`,`producteur`)
mysql> alter table t_producteur add index
accountManager_2(`accountManager`,`producteur`);
Query OK, 2871 rows affected (0.36 sec)
Records: 2871 Duplicates: 0 Warnings: 0
mysql> explain select SUM( (TR.quantity * ( TR.price * TR.currencyRate ) )
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
30 / 38
CONFIDENTIA
- ( TR.drm * TR.currencyRate ) ) AS FromBegin, TP.* FROM t_producteur
TP LEFT JOIN tRoyalties TR ON TR.idProducer = TP.id_producteur where
TP.accountManager=66 GROUP BY TP.producteur order by TP.producteur\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: TP
type: ref
possible_keys: accountManager,accountManager_2
key: accountManager_2
key_len: 5
ref: const
rows: 64
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: TR
type: ref
possible_keys: idProducer
key: idProducer
key_len: 4
ref: TP.id_producteur
rows: 313185
Extra:
2 rows in set (0.00 sec)
Transformer les sous requêtes en jointure :
Mysql> explain select idSong FROM tSongHistory WHERE idSong
IN (SELECT id_song FROM t_song WHERE id_album = '20210' AND
dateStart = '2009-02-27')\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: tSongHistory
type: index
possible_keys: NULL
key: unique_idSong_dateStart
key_len: 7
ref: NULL
rows: 365677
Extra: Using where; Using index
*************************** 2. row ***************************
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
31 / 38
CONFIDENTIA
id: 2
select_type: DEPENDENT SUBQUERY
table: t_song
type: unique_subquery
possible_keys: PRIMARY,id_album
key: PRIMARY
key_len: 4
ref: func
rows: 1
Extra: Using where
2 rows in set (0.01 sec)
Ici la requête va scanner 365677 lignes
avec Jointure scan d'une seule ligne
mysql> explain select idSong FROM tSongHistory a, t_song b
WHERE id_album = '20210' AND dateStart = '2009-02-27' AND
a.idSong=b.id_Song\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: b
type: ref
possible_keys: PRIMARY,id_album
key: id_album
key_len: 4
ref: const
rows: 1
Extra: Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: a
type: eq_ref
possible_keys: unique_idSong_dateStart
key: unique_idSong_dateStart
key_len: 7
ref: b.id_song,const
rows: 1
Extra: Using index
2 rows in set (0.00 sec)
•
•
6.1
Si possible remplacer IN par des requêtes avec UNION ALL
Eviter les fonctions et les expressions dans les clauses where
Réplication, liens utiles
http://dev.mysql.com/doc/refman/5.0/en/show-slave-status.html
http://dev.mysql.com/doc/refman/6.0/en/replication-semisync.html
http://forge.mysql.com/wiki/ReplicationFeatures/SemiSyncReplication
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
32 / 38
CONFIDENTIA
http://forge.mysql.com/wiki/ReplicationTeam
1. Note Importante :
Toutes recommandations fournis dans le présent rapport sont uniquement basées sur notre
expérience générale . Nous vous conseillons de faire des tests avant toutes mise en pratique
des recommandations sur un système de production.
Garder en mémoire de faire une sauvegarde complète avant l'implémentation des
changements préconisés.
Copyright © 1995-2010, Oracle Corporation and/or its affiliates
33 / 38
CONFIDENTIA
7
Plan d'action
Priorité
1
2
3
4
5
6
7
8
Description
Upgarde MySQL >=5.1.47
Stand By Continuite de service
Optimisation structure et requêtes
Mise en place des optimize
Monitoring à mettre en place évolutivité
HA en replication
Architecture en multi instance – multi
serveur
Tunning en situation de production en
cas de blocakage
Issues
Date prod
% compl
9
Nous sommes à votre disposition pour vous aider à mettre en place ce plan d'action.
8
Annexes
8.1
Plan stockage
Nous vous recommandons de mettre en place un plan de stockage normalisé. Il devra
séparer les log des data.
Volumes des données
/deploy/<instancename>/var/ (my.cnf,pid,.sock) bases, table spaces,
iblog*
/logbin/
/log/ (slowlog, errlog, ...)
/relaylog/
/tmp/
Les répertoires var, tmp, logbin, relaylog peuvent être mis sur des disques différents
On peut aussi utiliser SSD pour datadir : /var rapide en accès direct
et les HDD (moins couteux) pour les journaux en accès séquentiel
1) performance : la possibilité de configurer les composants d'une manière souple facilite
les optimisations. En parallélisant et en aiguillant chaque type d'entrée sortie au harware
adéquat. Les caches MySQL se trouve plus optimisées.
2) indépendance : Le plan de nommage permet d'installer, faire fonctionner, administrer, et
faire évoluer les serveurs MySQL indépendamment des OS : UNIX/Linux, ubuntu redhat,
…
3) évolutivité : le découpage doit être suffisamment souple pour éviter d'être remis en cause
à la suite d'upgrade applicatifs, versions, systèmes, ...
Volumes des binaires
/myq/v-<x.x.x>/ (binaires) (pointe sur les binaires)
/mysql-pro-gpl-5.1.23-pc-10-x86_64/
/dba/ (dba scripts : create user, create
database ...)
/expl/(backup,purges, reorg..)
/appli / (applications scripts)
/log
/tmp
/agentMySQL
Volumes des données
/deploy/<instancename>/var/ (my.cnf,pid,.sock) bases, table spaces,
iblog*
/logbin/
/log/ (slowlog, errlog, ...)
/relaylog/
/tmp/
Les répertoires var, tmp, logbin,relaylog peuvent être mis sur des disques différents
Volumes des sauvegardes
/backup/<instancename>/froid/
/chaud/
8.2
Multi instances
Nous préconisons du multi-instances :
Avantages multi instances:
 Indépendance des instances : flexibilité et fiablilité renforcé une application qui plante une
instance n'affecte pas les autres
 Mutualisation plusieurs applications peuvent cohabiter
 Upgardes facilitées
 Retoure en arrière plus simple
 admin os sur une seule machine au lieux de plusieurs cout en licence moins élévé
 Implémentation du partitionning fonctionnel et du sharding possible sans avoir à
acheter d'autres machines,
Inconvénient
nécessite un investissement initial pour mettre en place une configuration d'un
environnement multi-instance
8.3
Métrologie et montée en charge
Pour mesurer la montée en charge nous vous recommandé l'outil Jmeter. C' est un outil qui
permet de valider le bon fonctionnement d’une application dans son contexte.
Il est développé par la Fondation Apache, en tant que sous projet Jakarta.
JMeter permet :
1. la concurrence des requêtes de tests durant le tir de charge ou bien d’avoir des paliers de
tests en termes d’utilisateurs virtuels.
2. d’avoir des robots injecteurs pour simuler la charge tout en la répartissant sur plusieurs
machines injecteurs (et ainsi éviter que le goulot d’étranglement soit le poste de test).
On peut tester :
* Les temps de réponses d’une application web, en fonction du nombre d’utilisateurs
virtuels
* Les écarts de temps de réponse en fonction de paliers d’utilisateurs
* Les différences de comportements d’une même application sur deux (ou plus)
environnements d’exécution différents (par exemple cluster ou non, configuration 1 /
configuration 2, etc)
* La robustesse d’une application (à partir de quand la solution s’interrompt brutalement
(crash) ?…)
* Le fonctionnellement une application de manière automatique (tests de non régression,
de validité fonctionnelle, etc)
* Superviser une application (soit via une sorte de ‘ping’, soit par des éléments plus
complexes).
8.4
Monitoring
Pramètre
OK
ALETE
CRITIQUE DOWN
en %
100 *( max_connections – threads_connected )/
max_connections
en %
<50 et >20
<=20
<50 et >20
<=20
created_disk_tmp_tables*100/created_tmp_tables,
>10
>40
Slow_Queries /(Com_select +
Qcache_hits+Com_insert+Com_update+Com_delete+
Com_replace)
>10
50
espace disque dispo en pourcentage pour chaque
partition data, logbin, relaylog, backup
<50
<20
0
io wait (vmstat mpstat)
>10
>40
>100
cpu
>50
>80
>100
vmstat si so
>0
>0
100 *( max_connections – Max_used_connections
max_connections
)/
Nous vous conseillons d'utiliser MySQL Monitor.
Bench avec Mysqlslap
Mysqlslap est fournis avec mysql 5.1. Voici un exemple de bench innodb
#!bin/sh
list="2 4 8 16 32"
quer=100000
quer=10000
for i in $list
do
mysqlslap --user=root -plaposte --auto-generate-sql \
--concurrency=$i --number-of-queries=$quer \
--number-char-cols=4 --number-int-cols=7 --engine=innodb \
--auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed iterations=2
done
--mysql-user=root run

Documents pareils