lundi 3 mai 2010

MySQL Cluster impose des limites aux méta-données

Lorsque vous mettez en place une configuration MySQL Cluster, ayez à l'esprit que celui-ci impose par défaut des limites aux méta-données. Vous ne pourrez donc pas créer autant de tables, d'index, de colonnes que vous le désirez sans modifier sa configuration. Il est possible de le faire plus tard, mais cela nécessitera d'effectuer un rolling restart (un redémarrage de l'ensemble des composants du cluster).
Voici les quelques paramètres qu'il faudra modifier selon les besoins de votre cluster (les valeurs par défaut sont indiquées entre parenthèses) :

- MaxNoOfAttributes fixe le nombre maximum de colonnes pouvant être créées au total dans l'ensemble des tables stockées (1000)
- MaxNoOfOrderedIndexes fixe le nombre maximum d'index ordonnés (128)
- MaxNoOfUniqueHashIndexes, comme le précédent mais pour les index uniques (64)
- MaxNoOfTables fixe le nombre maximum de tables (128)

Vous pourrez donc modifier la section [NDBD DEFAULT] de votre fichier de configuration ndb_mgmd.cnf et y ajouter la configuration suivante par exemple :

MaxNoOfAttributes=10000
MaxNoOfOrderedIndexes=3000
MaxNoOfUniqueHashIndexes=1500
MaxNoOfTables=1000

Pour plus d'information, vous pouvez visiter la documentation en ligne à l'adresse http://dev.mysql.com/doc/mysql-cluster-excerpt/5.1/en/mysql-cluster-mgm-definition.html

Vous ne pourrez pas dire que vous n'avez pas été prévenu :)

vendredi 26 mars 2010

2 bases exemple pour MySQL

Sur le site de MySQL vous pouvez télécharger les bases sakila et world afin de vous familiariser avec le SGBD.
Pour installer ces 2 bases sur votre serveur sous Ubuntu, suivez la procédure suivante :

sudo wget -c http://downloads.mysql.com/docs/sakila-db.tar.gz
sudo tar Ozvxf sakila-db.tar.gz sakila-db/sakila-schema.sql|sudo mysql --defaults-file=/etc/mysql/debian.cnf
sudo tar Ozvxf sakila-db.tar.gz sakila-db/sakila-data.sql|sudo mysql --defaults-file=/etc/mysql/debian.cnf sakila

sudo wget http://downloads.mysql.com/docs/world.sql.gz
sudo mysql --defaults-file=/etc/mysql/debian.cnf -e 'CREATE DATABASE world'
sudo zcat world.sql.gz|sudo mysql --defaults-file=/etc/mysql/debian.cnf world

Voila vos 2 bases sont créées et prêtes à être utilisées :

sudo mysql --defaults-file=/etc/mysql/debian.cnf
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 46
Server version: 5.1.37-1ubuntu5.1 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SELECT count(*) TABLES, table_schema,
-> concat(round(sum(table_rows)/1000000,2),'M') rows,
-> concat(round(sum(data_length)/(1024*1024),2),'M') DATA,
-> concat(round(sum(index_length)/(1024*1024),2),'M') idx,
-> concat(round(sum(data_length+index_length)/(1024*1024),2),'M') total_size,
-> round(sum(index_length)/sum(data_length),2) idxfrac
-> FROM information_schema.TABLES
-> WHERE table_schema IN ('sakila','world')
-> GROUP BY table_schema;
+--------+--------------------+-------+--------+-------+------------+---------+
| TABLES | table_schema | rows | DATA | idx | total_size | idxfrac |
+--------+--------------------+-------+--------+-------+------------+---------+
| 23 | sakila | 0.05M | 4.10M | 2.52M | 6.62M | 0.62 |
| 3 | world | 0.01M | 0.36M | 0.07M | 0.43M | 0.19 |
+--------+--------------------+-------+--------+-------+------------+---------+
2 rows in set (0,03 sec)

mysql> exit
Bye

Pour en savoir plus sur ces 2 bases vous pouvez vous rendre sur le site web de MySQL aux adresses http://dev.mysql.com/doc/sakila/en/sakila.html et http://dev.mysql.com/doc/world-setup/en/world-setup.html

A vous de jouer !

jeudi 18 février 2010

MySQL Cluster 7.1

La version 7.1 du moteur de stockage NDB n'est pas encore sortie mais on peut déjà savoir quelles seront les prochaines nouveautés non garanties pour le moment :

- Deux nouveaux connecteurs JAVA

ClusterJ et ClusterJPA permettent d'accéder au cluster MySQL sans utiliser de serveur MySQL (ni JDBC) ou pour le second de passer ou non par un serveur MySQL si la requête exécutée peut être améliorée par l'optimiseur MySQL.

Cette base permet d'accéder à des informations tel que la mémoire utilisée (table memoryusage), le statut des noeuds (table nodes), etc... nécessitant auparavant l'utilisation des commandes ALL DUMP {CODE}

- Une nouvelle base de données nommé ndbinfo

Cette base permet d'accéder à des informations tel que la mémoire utilisée (table memoryusage), le statut des noeuds (table nodes), etc... nécessitant auparavant l'utilisation des commandes ALL DUMP {CODE}

- Le support natif des valeurs par défaut des colonnes

Les valeurs par défaut des colonnes sont à présent stockées dans le noyau NDB et non par le serveur MySQL. Ceci permet au serveur MySQL de ne plus avoir à transférer ces données aux noeuds et donc potentiellement d'accélérer les requêtes d'insertions

- Une nouvelle option (--nowait-nodes) pour les managers

Cette option permet de ne plus avoir besoin de démarrer plus d'un manager pour démarrer un cluster configuré avec plusieurs managers.

Pour suivre l'évolution de ces fonctionnalités n'hésitez pas à consulter la page dédiée.

Récupérez les dernières versions de MySQL Cluster 7.X

Nous avons déjà vu dans un billet précédent les nouveautés de la version 7.0 (ancienne 6.4 renommée).

Il est cependant important de pouvoir vérifier l'arrivée des nouvelles versions sur le dépot officiel, et pourquoi pas de les récupérer pour les tester. Pour cela voici les commandes que j'utilise :

- Pour vérifier l'arrivée de nouvelles versions, je m'appuie sur les dates de création des répertoires

export LANG=C
wget -O - -q ftp://ftp.mysql.com/pub/mysql/download/cluster_telco/|grep Directory|awk -FDirectory '!/old/ {print $1}'|perl -MDate::Manip -lne 'if(Date_Cmp(ParseDate($_),ParseDate("2010 Feb 15 21:27"))>0){print "Nouvelle version disponible !";exit}'

- Pour récupérer les nouvelles versions disponibles j'utilise l'alias mirror_mysql_cge que j'ai défini ainsi :

alias mirror_mysql_cge='(cd /var/www && wget -nH --cut-dirs 3 -rc -R "mysqlcom*" -A "*-7.*.gz" --exclude-directories=/pub/mysql/download/cluster_telco/old,/pub/mysql/download/cluster_telco/newbuilds,/pub/mysql/download/cluster_telco/*-6.*,/pub/mysql/download/cluster_telco/*/*-6.*,/pub/mysql/download/cluster_telco/evaluation* ftp://ftp.mysql.com/pub/mysql/download/cluster_telco/)'

A chaque récupération de nouvelles archives il est cependant obligatoire de modifier la date utilisée dans la commande wget pour repérer la dernière archive récupérée. Pour obtenir cette date, la commande suivante sera d'un grand secours :

export LANG=C
wget -O - -q ftp://ftp.mysql.com/pub/mysql/download/cluster_telco/|grep Directory|awk -FDirectory '!/old/ {if(index($1,":")){print $1}}'| tr '\n' , |sed 's/,$//'|perl -MDate::Manip -MMemoize -lne 'sub sortDate {(Date_Cmp(ParseDate($a),ParseDate($b)))} print [reverse sort sortDate split(",",$_)]->[0]'

Ainsi je retrouverai toutes les versions 7.X sous l'arborescence /var/www/cluster_telco

lundi 4 janvier 2010

Nouvelles fonctionnalités dans le partitionnement de MySQL 5.5

Etant donné que cela fait un long moment que je n'ai pas bloggé je vais tenter de me rattrapper un peu :)

Je me suis penché sur l'une des nouvelles fonctionnalités de MySQL 5.5 concernant le partitionnement multi-colonnes en mode RANGE sur des types qui ne sont plus limités à l'entier.

En effet, il est possible de partitionner une table t1 sur 2 colonnes comme suit :

CREATE TABLE t1 (
valeur TINYINT UNSIGNED NOT NULL,
quand DATE NOT NULL,
libelle varchar(120)
)
PARTITION BY RANGE COLUMNS(valeur,quand) (
PARTITION p0 VALUES LESS THAN (10,'2006-10-02'),
PARTITION p1 VALUES LESS THAN (10,'2008-04-12'),
PARTITION p2 VALUES LESS THAN (100,MAXVALUE),
PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE)
);

Cependant l'algorithme qui répartit les données sur les différentes partitions créées n'est pas si intuitif que cela. Ainsi, j'imaginais dans un premier temps que l'enregistrement (100,'2005-10-02') ne pouvait se retrouver dans la partition p2 car 100 n'est pas inférieur à 100 ! En effet, je pensais que l'opérator LESS THAN sur un couple sous entendait que pour qu'un enregistrement (valeur,quand,libelle) appartienne à la partition p0 il fallait que valeur<10 et quand<'2006-10-02'.
Or ce n'est pas le cas, la preuve :

mysql> SELECT IF(10<10,'TRUE','FALSE'),IF('2005-10-02'<'2006-10-02','TRUE','FALSE'),IF((10,'2005-10-02')<(10,'2006-10-02'),'TRUE','FALSE')\G
*************************** 1. row ***************************
                              IF(10<10,'TRUE','FALSE'): FALSE
          IF('2005-10-02'<'2006-10-02','TRUE','FALSE'): TRUE
IF((10,'2005-10-02')<(10,'2006-10-02'),'TRUE','FALSE'): TRUE

Il faut dire qu'entre la documentation officielle qui a été corrigée (BUG 49875) suite à mon premier BUG 49861, et l'article de Giuseppe Maxia qui affirmait que si toutes les premières valeurs des listes de colonnes assignées aux partitions étaient différentes alors le partitionnement était identique au partitionnement sur cette seule colonne (corrigé depuis) j'ai un peu perdu la tête...

Cependant, cette histoire a bien fait de débuter puisqu'elle a débouché sur la correction de la documentation officielle, la correction d'un article avancé sur les nouveautés de la 5.5 concernant le partitionnement et sur la remise en cause des mots clés LESS THAN dans ce type de partitionnement avec une proposition de remplacement par NO GREATER THAN ou RANGE BOUNDED BY.

Nous verrons bien ce qu'il se passera dans les semaines à venir.