{"id":633,"date":"2013-12-02T14:23:44","date_gmt":"2013-12-02T12:23:44","guid":{"rendered":"http:\/\/gcolpart.evolix.net\/blog21\/?p=633"},"modified":"2013-12-02T14:35:20","modified_gmt":"2013-12-02T12:35:20","slug":"bug-mysql-cache-innodb-nom-base-table-avec-tiret","status":"publish","type":"post","link":"https:\/\/gcolpart.evolix.net\/blog21\/bug-mysql-cache-innodb-nom-base-table-avec-tiret\/","title":{"rendered":"Bug MySQL : pas de cache avec des tables InnoDB et un nom de base\/table foo-bar"},"content":{"rendered":"<p>L&#8217;\u00e9quipe <a href=\"http:\/\/www.evolix.fr\/\">Evolix<\/a> a r\u00e9cemment d\u00e9couvert un <a href=\"http:\/\/bugs.mysql.com\/bug.php?id=64821\">bug assez incroyable<\/a>&nbsp;: les versions 5.1 \u00e0 5.6.8 de <a href=\"http:\/\/www.mysql.com\/\">MySQL<\/a> ne g\u00e8rent pas le <em>Query Cache<\/em> (un m\u00e9canisme essentiel) sur les tables <em>InnoDB<\/em> si le nom de la table ou base contient un caract\u00e8re particulier, notamment le tiret (<strong>&#8211;<\/strong>)&nbsp;!! Ce n&#8217;est pas une v\u00e9ritable d\u00e9couverte car <a href=\"http:\/\/dev.mysql.com\/doc\/relnotes\/mysql\/5.6\/en\/news-5-6-9.html\">le bug a \u00e9t\u00e9 corrig\u00e9 pour la version 5.6.9 en d\u00e9cembre 2012<\/a>, mais il a \u00e9t\u00e9 peu \u00ab&nbsp;m\u00e9diatis\u00e9&nbsp;\u00bb et surtout il impacte de nombreuses distributions Linux. Concr\u00e8tement si vous avez Debian (Squeeze\/Wheezy\/Testing\/Sid) ou Ubuntu (toutes les versions depuis 4 ans) et vous utilisez le paquet <a href=\"http:\/\/packages.debian.org\/mysql-server\">mysql-server<\/a>, toutes vos bases ou tables nomm\u00e9es <strong>foo-bar<\/strong> sont impact\u00e9es. Toutes vos requ\u00eates sens\u00e9es \u00eatre servies par le cache MySQL ne le sont pas, et il en d\u00e9coule des probl\u00e8mes de performance (parfois tr\u00e8s significatifs). Au passage, pour v\u00e9rifier qu&#8217;une requ\u00eate MySQL utilise bien le <em>Query Cache<\/em>, vous pouvez observer le compteur de hits via <em><strong>show status like &#8216;Qcache_hits&#8217; <\/strong><\/em> (parfois difficile sur des serveurs en production, mais vous avez bien s\u00fbr des serveurs de pr\u00e9production ;-).<\/p>\n<p>Mise en \u00e9vidence du bug avec un nom de base <em>foo-bar<\/em> :<\/p>\n<pre>\r\nmysql> create database `foo-bar`;\r\nmysql> create table `foo-bar`.baz (a int) engine=InnoDB;\r\nmysql> insert into `foo-bar`.baz values (1);\r\nmysql> select * from `foo-bar`.baz;\r\nmysql> show status like 'Qcache_hits';\r\n+---------------+--------+\r\n| Variable_name | Value  |\r\n+---------------+--------+\r\n| Qcache_hits   | 42     |\r\n+---------------+--------+\r\nmysql> select * from baz;\r\nmysql> show status like 'Qcache_hits';\r\n+---------------+--------+\r\n| Variable_name | Value  |\r\n+---------------+--------+\r\n| Qcache_hits   | 42     |\r\n+---------------+--------+\r\n<\/pre>\n<p>Mise en \u00e9vidence du bug avec un nom de table <em>baz-qux<\/em> :<\/p>\n<pre>\r\nmysql> create database foobar;\r\nmysql> create table foobar.`baz-qux` (a int) engine=InnoDB;\r\nmysql> insert into foobar.`baz-qux` values (1);\r\nmysql> select * from foobar.`baz-qux`;\r\nmysql> show status like 'Qcache_hits';\r\n+---------------+--------+\r\n| Variable_name | Value  |\r\n+---------------+--------+\r\n| Qcache_hits   | 42     |\r\n+---------------+--------+\r\nmysql> select * from foobar.`baz-qux`;\r\nmysql> show status like 'Qcache_hits';\r\n+---------------+--------+\r\n| Variable_name | Value  |\r\n+---------------+--------+\r\n| Qcache_hits   | 42     |\r\n+---------------+--------+\r\n<\/pre>\n<p>Si vous n&#8217;\u00eates pas encore parti en courant v\u00e9rifier le nom de vos bases et tables MySQL\/MariaDB, je vais vous expliquer comment ce bug a \u00e9t\u00e9 d\u00e9couvert et pourquoi cela illustre bien le travail d&#8217;<a href=\"http:\/\/www.evolix.fr\/serv\/infogerance.html\">infog\u00e9rance d&#8217;Evolix<\/a>. En effet, un abonnement \u00e0 l&#8217;infog\u00e9rance est une sorte d&#8217;assurance : outre les op\u00e9rations visibles (surveillance 24\/24, veille technologique, mises-\u00e0-jour, support technique), c&#8217;est aussi la garantie que l&#8217;on mettra tout en \u0153uvre si il vous arrive un incident. Pendant plusieurs mois\/ann\u00e9es vous n&#8217;aurez peut-\u00eatre pas d&#8217;incident s\u00e9rieux (et tant mieux pour tout le monde), mais un jour vous aurez besoin d&#8217;une attention de plusieurs heures voire plusieurs jours. C&#8217;est ce qui est arriv\u00e9 ces derni\u00e8res semaines avec ce bug MySQL : un client d&#8217;Evolix a signal\u00e9 une lenteur sur certaines pages d&#8217;un site d&#8217;e-commerce suite \u00e0 une migration de serveurs. Apr\u00e8s pas mal d&#8217;analyses, nous n&#8217;\u00e9tions pas convaincus, la lenteur s&#8217;expliquait par des milliers de requ\u00eates SQL faites sur chaque page, et surtout cette lenteur \u00e9tait \u00e9galement pr\u00e9sente sur l&#8217;ancien serveur. N\u00e9anmoins, nous avons fini par d\u00e9couvrir que sur un tr\u00e8s vieux serveur en Debian Lenny, les pages \u00e9taient moins lentes. Apr\u00e8s de nombreux tests (passage en SSD, utilisation de TMPFS pour \u00e9liminer les I\/O disque, tests sur diff\u00e9rents serveurs dont un ultra puissant, <em>strace<\/em> des process, etc.), nous avons mis en \u00e9vidence que l&#8217;ex\u00e9cution des milliers de requ\u00eates SQL \u00e9taient tout simplement plus rapides sur le tr\u00e8s vieux serveur en Debian Lenny. Ce constat \u00e9tait un peu effrayant pour nous, et presque tout l&#8217;\u00e9quipe s&#8217;est mis sur ce probl\u00e8me. On a identifi\u00e9 que les requ\u00eates n&#8217;utilisaient pas le <em>Query Cache<\/em>, et l&#8217;on a donc relu toute la documentation concernant le cache MySQL&#8230; mais rien \u00e0 faire, des requ\u00eates SQL simples n&#8217;\u00e9taient toujours pas mises en cache. M\u00eame r\u00e9sultats avec MySQL 5.1\/5.5 ou MariaDB 5.5. Puis l&#8217;on a d\u00e9couvert ce <a href=\"http:\/\/bugs.mysql.com\/bug.php?id=64821\">fameux bug<\/a> : la base concern\u00e9e ayant un tiret dans son nom, on l&#8217;a f\u00e9brilement renomm\u00e9e et <strong>*bingo*<\/strong> les requ\u00eates sont d\u00e9sormais cach\u00e9es !<\/p>\n<p>En attendant une <a href=\"http:\/\/bugs.debian.org\/731076\">\u00e9ventuelle correction du bug par Debian<\/a>, nous conseillons de renommer vos bases et tables impact\u00e9es. Au passage, le tiret (<strong>&#8211;<\/strong>) est un caract\u00e8re particulier pour MySQL et il est pr\u00e9f\u00e9rable de prendre l&#8217;habitude d&#8217;utiliser l&#8217;underscore (<strong>_<\/strong>) dans le nom de vos bases et tables.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\/<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,72],"tags":[],"class_list":["post-633","post","type-post","status-publish","format-standard","hentry","category-evolix","category-french"],"_links":{"self":[{"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/posts\/633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/comments?post=633"}],"version-history":[{"count":17,"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/posts\/633\/revisions"}],"predecessor-version":[{"id":652,"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/posts\/633\/revisions\/652"}],"wp:attachment":[{"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/media?parent=633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/categories?post=633"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gcolpart.evolix.net\/blog21\/wp-json\/wp\/v2\/tags?post=633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}