lundi 20 avril 2009

Oracle rachète SUN

En janvier 2008, SUN rachetait MySQL AB pour 1 milliard de $. Eh bien, aujourd'hui Oracle a annoncé sur  son site avoir accepté de racheter SUN pour 7 milliards de dollars. Il va falloir à nouveau s'interroger sur les conséquences, bonnes comme mauvaises, que cela pourra avoir pour les utilisateurs de MySQL.
Blogged with the Flock Browser

dimanche 19 avril 2009

Perl 5.10 optimise le moteur d'expressions régulières

Une des nouvelles fonctionnalités de la 5.10 est l'utilisation d'algorithmes tels que Aho-Corasick et Trie (prefix tree) dans le moteur d'expressions régulières. Ainsi la recherche d'alternatives comme le pattern alt1|alt2|alt3|alt4|altN aura une complexité en 0(1) et non plus en 0(N) avec N le nombre d'alternatives. Pour s'en convaincre, rien de mieux qu'un benchmarck entre les versions 5.8 et 5.10. Pour cela j'ai écrit un petit bout de code que vous pouvez récupérer ici.
J'utilise le module Regexp::Trie de Dan Kogai qui permet d'optimiser la recherche d'alternatives ayant un suffixe (ou une partie) en commun

Les résultats obtenus sont les suivants :

a -> sans utilisation du module Regexp::Trie
b -> avec utilisation du module Regexp::Trie

Perl 5.8 :

perl bench_with_tries.pl
Rate a b
a 552/s -- -98%
b 26050/s 4620% --


Perl 5.10 :

perl bench_with_tries.pl
Rate a b
a 20177/s -- -65%
b 57777/s 186% --


On voit bien qu'en version 5.8 l'utilisation du module de Dan Kogai permet de multiplier par plus de 40 les performances, contrairement en 5.10 où les performances de base sont déjà satisfaisantes avec plus de 20 000 exécutions par seconde. Cependant, il est toujours utile d'utiliser ce module en 5.10 puisqu'on obtient près de 3 fois plus de performance.
Blogged with the Flock Browser

mardi 24 mars 2009

Vive le strip binaire !

Je pense que nous sommes nombreux à utiliser MySQL Sandbox qui est un outil très utile pour pouvoir par exemple tester rapidement une version particulière de MySQL, installer plusieurs versions sur le même serveur, configurer une réplication multi-slaves en quelques commandes etc...
Cependant, cela nécessite de récupérer une archive binaire pour chaque version que vous voulez utiliser, ce qui peut consommer rapidement pas mal d'espace !

Par exemple, j'ai récupéré la version 5.0.67 qui, sous forme d'archive, occupe 113Mo et une fois décompressée près de 398Mo ! Il était donc temps que je prenne quelques initiatives :-)

du -sh mysql-5.0.67-linux-i686.tar.gz
113M mysql-5.0.67-linux-i686.tar.gz

tar xzf mysql-5.0.67-linux-i686.tar.gz
du -sh mysql-5.0.67-linux-i686
398M mysql-5.0.67-linux-i686

Je commence par supprimer les répertoires qui me seront inutiles

rm -rf docs/ sql-bench/ mysql-test/ tests/ man/

Ceci me permet d'économiser 45Mo. Ensuite je strippe les binaires et les bibliothèques

strip bin/* lib/* 2>/dev/null

Et encore 242 Mo d'économisé !

Enfin, je supprime les binaires qui me seront inutiles

rm -f *debug* *test* *ndb*

Cette dernière étape me récupère encore 20Mo. A la fin de cette série d'actions, l'archive décompressée n'occupe plus que 68 Mo soit près de 6 fois moins que la taille de départ.

La question que vous devez vous poser est la suivante : que fait la commande strip ?

elle supprime tous les symbols et numéros de lignes des binaires et bibliothèques, qui peuvent être utiliseés lorsque vous debuggez vos programmes, ce qui n'est pas mon cas.
Blogged with the Flock Browser
Lire la suite...

jeudi 12 mars 2009

Défaillance du Query Cache de MySQL

Il arrive que le Query Cache ne fonctionne pas :-(

J'ai par exemple était confronté à un problème concernant le Query Cache lorsque j'ai voulu optimiser certaines requêtes effectuées sur un serveur. En fait, l'optimiseur de MySQL, en version 4.1.11, ne faisait pas le bon choix d'index selon certains cas, et scinder la requête en 2 sous requêtes unifiées ensuite permettait d'obtenir de meilleurs performances. Attention, ce n'est pas toujours le cas !
En exécutant plusieurs fois les 2 requêtes unitairement le Query Cache fonctionnait correctement comme vous pouvez le voir au temps d'exécution qui était > 2 s.

mysql> SELECT idancetre,max(idmess) mxd FROM messages USE INDEX (idx_tst3) WHERE idancetre not in (1021576,0) AND avalider=0 AND idmess>1021576 GROUP BY idancetre ORDER BY mxd DESC LIMIT 5;
+-----------+---------+
| idancetre | mxd |
+-----------+---------+
| 1993983 | 1995071 |
| 1994149 | 1995069 |
| 1995061 | 1995061 |
| 1994957 | 1995059 |
| 1994250 | 1995058 |
+-----------+---------+
5 rows in set (0.00 sec)


mysql> SELECT idmess,idmess FROM messages WHERE idancetre=0 AND avalider=0 AND idmess>1021576 GROUP BY idmess ORDER BY idmess DESC LIMIT 5;
+---------+---------+
| idmess | idmess |
+---------+---------+
| 1169825 | 1169825 |
| 1169813 | 1169813 |
| 1169795 | 1169795 |
| 1169758 | 1169758 |
| 1169756 | 1169756 |
+---------+---------+
5 rows in set (0.00 sec)


Par contre, la requête UNION composée des 2 requêtes précédentes n'était jamais stockée dans le Query Cache :

mysql> (SELECT idancetre,max(idmess) mxd FROM messages USE INDEX (idx_tst3) WHERE idancetre not in (1021576,0) AND avalider=0 AND idmess>1021576 GROUP BY idancetre ORDER BY mxd DESC LIMIT 5) UNION (SELECT idmess,idmess FROM messages WHERE idancetre=0 AND avalider=0 AND idmess>1021576 GROUP BY idmess ORDER BY idmess DESC LIMIT 5);
+-----------+---------+
| idancetre | mxd |
+-----------+---------+
| 1993983 | 1995071 |
| 1994149 | 1995069 |
| 1995061 | 1995061 |
| 1994957 | 1995059 |
| 1994250 | 1995058 |
| 1169825 | 1169825 |
| 1169813 | 1169813 |
| 1169795 | 1169795 |
| 1169758 | 1169758 |
| 1169756 | 1169756 |
+-----------+---------+
10 rows in set (2.55 sec)


Vous le comprendrez bien, dans ce cas là, il est préférable d'exécuter les 2 requêtes de façon distincte et d'effectuer l'UNION côté applicatif plutôt qu'en une seule et même requête. En fait, dans cette version c'était dû à un BUG référencé chez MySQL et corrigé en 4.1.17, 5.0.17 et 5.1.4

SELECT queries that began with an opening parenthesis were not being placed in the query cache. (Bug#14652)


En 5.0.67, qui contient le bugfix, ce n'est pas la même chose :

mysql> (SELECT idancetre,max(idmess) mxd FROM messages USE INDEX (idx_tst3) WHERE idancetre not in (1021576,0) AND avalider=0 AND idmess>1021576 GROUP BY idancetre ORDER BY mxd DESC LIMIT 5) UNION ALL (SELECT idmess,idmess FROM messages WHERE idancetre=0 AND avalider=0 AND idmess>1021576 GROUP BY idmess ORDER BY idmess DESC LIMIT 5);
+-----------+---------+
| idancetre | mxd |
+-----------+---------+
| 1993983 | 1995071 |
| 1994149 | 1995069 |
| 1995061 | 1995061 |
| 1994957 | 1995059 |
| 1994250 | 1995058 |
| 1169825 | 1169825 |
| 1169813 | 1169813 |
| 1169795 | 1169795 |
| 1169758 | 1169758 |
| 1169756 | 1169756 |
+-----------+---------+
10 rows in set (0.00 sec)


Il est donc très important de vérifier les changement apportés par les versions mineures qui suivent la version que vous utilisez pour savoir quels bugs ont été corrigés, et lesquels peuvent vous concerner.

Blogged with the Flock Browser
Lire la suite...

L'art de blogguer sous Blogger

Nous sommes plusieurs à utiliser ce template sous Blogger et je dois dire que je le trouve assez professionnel :-)
Cependant, je n'appréciais pas plusieurs choses :
- la largeur par défaut
- les coins arrondis
- l'impossibilité d'afficher un résumé des posts sur la page d'accueil

J'ai donc du modifier le template pour pouvoir satisfaire tout ce dont j'ai besoin d'un blog et que Blogger ne m'offre pas par défaut !

En prérequis, il faut bien sûr que vous vous connectiez sur votre dashboard en allant sur https://www.blogger.com/start. Ensuite, vous vous rendez dans la section Layout du blog que vous voulez modifier, puis dans Edit HTML.
Il ne vous reste plus qu'à cocher la case dans la partie Edit Template.

Modifier la largeur par défaut

Recherchez Page Structure dans la zone d'édition car les modifications à faire se trouvent dans les css qui suivent. Il suffit ensuite d'augmenter la valeur du paramètre width pour les IDs outer-wrapper, main-wrap1, main-wrap2, main et les classes main, Blog :

#outer-wrapper {
width:930px;
....
}
#main-wrap1 {
width:680px;
...
}
#main-wrap2 {
width:100%;
...
}
#main {
width:655px;
...
}
.main .widget {
width: 668px;
...
}

.main .Blog {
width: 684px;
...
}

Supprimer les coins arrondis

Le fait de modifier la largeur par défaut nécessite de modifier les images de fond utilisées pour affichée des coins arrondis. J'ai donc préféré supprimer ces coins en retirant les images de fond http://www1.blogblog.com/rounders2/corners_main_bot.gif et http://www1.blogblog.com/rounders2/corners_main_top.gif pour les IDs main-wrap1 et main-wrap2.

Afficher le résumé de certains posts sur la page d'accueil

Pour pouvoir résoudre cette problématique je me suis inspiré des posts http://help.blogger.com/bin/answer.py?hl=en&answer=42215 et http://coderstalk.blogspot.com/2008/06/how-to-create-expandable-post-summaries.html#step-01.
La démarche est assez simple une fois qu'elle est bien cernée. Il faut suivre les étapes suivantes :

- rechercher la balise <div class='post-header-line-1'/> et ajouter le code suivant à la suite :

<style>
<b:if cond='data:blog.pageType == &quot;item&quot;'>
span.fullpost{display:inline;}
<b:else/>
span.fullpost{display:none;}
</b:if>
</style>


- rechercher la balise <div class='post-footer'> et ajouter le code suivant avant cette balise :

<b:if cond='data:blog.pageType != &quot;item&quot;'>
<b:if cond='data:post.labels'>
<b:loop values='data:post.labels' var='label'>
<b:if cond='data:label.name == &quot;more&quot;'>
<a expr:href='data:post.url'><b>Lire la suite...</b></a>
</b:if>
</b:loop>
</b:if>
</b:if>


- se rendre sur le dashboard
- cliquer sur l'option Settings de votre blog
- choisir l'onglet Formatting
- renseigner la partie Post Template avec :

<span class="fullpost">
</span>


Vous pouvez maintenant rédiger ou modifier vos anciens posts pour n'en afficher qu'un résumé sur la page d'accueil en respectant les 2 règles suivantes :

- Mettez la partie que vous voulez voir apparaître sur la page principale en dehors de la balise <span class=fullpost>
- Ajoutez le label more à votre post

Comme Rien ne vaut mieux qu'un petit exemple, voici un exemple de post que vous pouvez utiliser :

salut à tous, ce post n'est qu'un exemple parmis d'autres.
Je voudrais vous en dire plus mais<span class="fullpost">, en fait je n'ai pas grand chose à dire :-)</span>

Bien sûr vous n'oublierez pas d'ajouter le label more à ce post comme indiqué dans la méthode.
Blogged with the Flock Browser
Lire la suite...