Pourquoi une grosse requête bloque MySql ?

Eléphanteau du PHP | 33 Messages

25 oct. 2009, 12:22

Bonjour,

J'ai une petite question destinée aux experts, je cherche à savoir pourquoi une grosse requête bloque mon serveur MySql.

Le contexte : Il s'agit d'un gros site fonctionnant sur 2 serveurs (1 pour Apache et 1 pour MySql) qui sont identiques (8 x 2,4 Ghz, 8 Go de RAM, DD SSD, interfacé en 2 Gbps).

Le problème : Si on exécute, à partir du Apache, une grosse requête retournant plusieurs milliards d'enregistrements qui met 1 H à s'exécuter on arrive rapidement à un "too many connexion" pour les autres visiteurs le temps que la requête finisse de s'exécuter.

Mes hypothèses :
- Le serveur n'exécute qu'1 requête à la fois et les autres sont mises en attente, dans un fonctionnement normal ça serait transparent mais là ça bloquerait : Ce n'est pas ça car après observation des process à des instants t en fonctionnement normal il y a bien plusieurs requête qui s'execute parallèlement.

- Les connexions à la bdd misent en attente qui font aboutir au "too many connexion" concerne des requêtes portant sur la même table que la grosse requête et donc attendent le unlock de la table : Après calcule ce n'est pas possible, la table concernée est beaucoup trop peu utilisée pour arriver aussi rapidement au max connexion.

- Une des phases de traitement de la requête (ex : le "sending data") bloque temporairement la parallélisation des requêtes ?

Le but : Ma logique de fonctionnement serait que même si une requête lourde bloque quelque chose, ça ne doit être qu'1 processus et/ou 1 seul CPU mais pas le serveur MySql au complet qui indirectement bloque tout le site.

A ce stade j'avoue que ça dépasse mes compétences donc je voudrais savoir si quelqu'un serait inspirer pour m'expliquer là où ça bloque ?

Merci d'avance

ViPHP
ViPHP | 4039 Messages

25 oct. 2009, 12:36

C'est un peu lourd pour ne faire tourner qu'un seul serveur MySQL.. Mysql n'est pas parallélisé donc c'est pas en augmentant le nombre de cpu's qu'une requête va s'exécuter plus rapidement.

On à eu une discussion la-dessus, ou on à mentionné les proxy Mysql, ce qui est une bonne technique d'utilisation de mysql sur une machine multi-cpu:
post306107.html?hilit=proxy%20mysql#p306107
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

ViPHP
fab
ViPHP | 2657 Messages

25 oct. 2009, 15:08

Si tu regardes aux heures de pointes ton serveur et plus particulièrement le status mysql ( dans phpmyadmin tu peux y accéder ) tu vas pouvoir te rendre compte que toutes les requêtes ne s'exécutent pas en même temps. Des requêtes par exemple UPDATE s'effectue une par une bloquant toutes les autres en provoquant le STATUS "locked" alors que tu peux exécuter des dizaines de SELECT en même temps, il faut aussi optimiser ça :)
Seul l'intelligent a le pouvoir de se trouver con
try { work(); } catch(FlemmeExeption $e) { sleep(84600); }

Eléphanteau du PHP | 33 Messages

25 oct. 2009, 21:43

C'est un peu lourd pour ne faire tourner qu'un seul serveur MySQL.. Mysql n'est pas parallélisé donc c'est pas en augmentant le nombre de cpu's qu'une requête va s'exécuter plus rapidement.

On à eu une discussion la-dessus, ou on à mentionné les proxy Mysql, ce qui est une bonne technique d'utilisation de mysql sur une machine multi-cpu:
post306107.html?hilit=proxy%20mysql#p306107
MySql n'est pas parallélisé à quel niveau ? Car j'ai bien plusieurs requêtes qui peuvent s'exécuter en même temps en fonctionnement normal et l'ensemble des CPU est bien chargé uniformément et non pas 1 seul qui est à 100%.

Ce qui me gêne le plus ce n'est pas tellement la vitesse d'exécution de cette grosse requête mais qu'elle arrive à bloquer le serveur en fait.

Eléphanteau du PHP | 33 Messages

25 oct. 2009, 21:48

Si tu regardes aux heures de pointes ton serveur et plus particulièrement le status mysql ( dans phpmyadmin tu peux y accéder ) tu vas pouvoir te rendre compte que toutes les requêtes ne s'exécutent pas en même temps. Des requêtes par exemple UPDATE s'effectue une par une bloquant toutes les autres en provoquant le STATUS "locked" alors que tu peux exécuter des dizaines de SELECT en même temps, il faut aussi optimiser ça :)
Je suis d'accord avec toi, cependant cette grosse requête qui bloque le serveur est un SELECT et il n'y a jamais d'UPDATE ni de DELETE sur cette table sur le front office.

ViPHP
fab
ViPHP | 2657 Messages

26 oct. 2009, 05:16

Tu aurais pas fait une requète récursive? Ou des jointures un peu bizarres? Ce genre de cas m'est arrivé il y a pas longtemps avec des jointures en OR dans le WHERE ( donc sur un SELECT )
Seul l'intelligent a le pouvoir de se trouver con
try { work(); } catch(FlemmeExeption $e) { sleep(84600); }

ViPHP
ViPHP | 4039 Messages

26 oct. 2009, 12:00

MySql n'est pas parallélisé à quel niveau ?
Une requête ne pourra être exécuté que sur 1 cœur.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.