Bonjour/Bonsoir,
nous avons une galerie piwigo qui comporte actuellement 97539 photos. Lorsqu'il y a ajout de photos via la fonction de synchronisation ( upload ftp -> synchro ), le site devient inaccessible et on note énormément de requêtes lentes avec des “Copying to tmp table” si on regarde SHOW FULL PROCESSLIST.
En lisant la doc de MySQL, on se rend compte que l'utilisation de SELECT DISTINCT ou de GROUP BY provoque presque à coup sûr l'utilisation de tables temporaires : http://dev.mysql.com/doc/refman/5.1/en/ … ation.html
Il est possible de faire quelques optimisation, mais pour cela, il faut utiliser des indexes supplémentaires et construire correctement les requêtes pour que les indexes soient utilisés : http://dev.mysql.com/doc/refman/5.1/en/ … ation.html
http://stackoverflow.com/questions/1971 … or-sorting
Cependant, plutôt que de faire tout le temps des "SELECT DISTINCT" pour récupérer des id uniques, ne serait-il pas plus intéressant de récupérer la liste complète des id, puis de faire le uniq en PHP avec array_keys(array_flip($array)) ou array_unique($array) ou en utilisant in_array() : http://php.net/manual/fr/function.array-unique.php
http://wiki.planetoid.info/index.php/PH … ed.29_data
Voici un extrait des requêtes lentes qui se répètent en grand nombre :
# Time: 141013 16:36:33
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 18.833075 Lock_time: 0.146129 Rows_sent: 0 Rows_examined: 0
use websalsazur3;
SET timestamp=1413210993;
UPDATE piwigo_images
SET rotation = '0'
WHERE id = '22725';
# Time: 141013 16:40:21
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 12.123109 Lock_time: 0.000218 Rows_sent: 0 Rows_examined: 194810
SET timestamp=1413211221;
SELECT DISTINCT(id)
FROM piwigo_images INNER JOIN piwigo_image_category ON id=image_id
WHERE category_id NOT IN (0)
AND level>8;
# Time: 141013 16:40:32
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 19.588614 Lock_time: 0.000210 Rows_sent: 0 Rows_examined: 194810
SET timestamp=1413211232;
SELECT DISTINCT(id)
FROM piwigo_images INNER JOIN piwigo_image_category ON id=image_id
WHERE category_id NOT IN (0)
AND level>8;
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 20.968846 Lock_time: 0.000254 Rows_sent: 0 Rows_examined: 194810
SET timestamp=1413211232;
SELECT DISTINCT(id)
FROM piwigo_images INNER JOIN piwigo_image_category ON id=image_id
WHERE category_id NOT IN (0)
AND level>8;
# Time: 141013 16:40:34
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 21.700114 Lock_time: 0.000058 Rows_sent: 0 Rows_examined: 194810
SET timestamp=1413211234;
SELECT DISTINCT(id)
FROM piwigo_images INNER JOIN piwigo_image_category ON id=image_id
WHERE category_id NOT IN (0)
AND level>8;
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 19.407053 Lock_time: 0.000258 Rows_sent: 0 Rows_examined: 194810
SET timestamp=1413211234;
SELECT DISTINCT(id)
FROM piwigo_images INNER JOIN piwigo_image_category ON id=image_id
WHERE category_id NOT IN (0)
AND level>8;
# Time: 141013 16:41:09
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 50.896551 Lock_time: 16.330154 Rows_sent: 0 Rows_examined: 194810
SET timestamp=1413211269;
SELECT DISTINCT(id)
FROM piwigo_images INNER JOIN piwigo_image_category ON id=image_id
WHERE category_id NOT IN (0)
AND level>8;
# Time: 141013 16:41:23
# User@Host: xxxxxxxx[xxxxxxxx] @ [xx.xx.xx.xx]
# Query_time: 48.804988 Lock_time: 0.030872 Rows_sent: 514 Rows_examined: 196352
SET timestamp=1413211283;
SELECT c.id AS cat_id, id_uppercat,
MAX(date_available) AS date_last, COUNT(date_available) AS nb_images
FROM piwigo_categories as c
LEFT JOIN piwigo_image_category AS ic ON ic.category_id = c.id
LEFT JOIN piwigo_images AS i
ON ic.image_id = i.id
AND i.level<=8
GROUP BY c.id;
Version de Piwigo: 2.7.0 normalement ( à confirmer )
Version de PHP: ???
Version de MySQL: 5.1.x
URL Piwigo: http://www.websalsazur.com/piwigo2/index.php
Dernière modification par fabricefacorat (2014-10-14 00:35:00)
Hors ligne
Concernant MySQL, cela correspond à un MySQL "dédié" chez OVH : http://www.ovh.com/fr/hebergement-web/options-sql.xml
Plusieurs modifications ont été faites dans le my.cnf pour essayer d'optimiser les requêtes : le serveur comporte 512Mo de RAM, et la base fait 27Mo, et la table piwigo_images 22Mo.
Extraits du my.cnf :
tmp_table_size=64M
max_heap_table_size=64M
key_buffer_size = 128M
table_cache = 512
sort_buffer_size = 32M
read_buffer_size = 2M
read_rnd_buffer_size = 16M
join_buffer_size = 8M;
max_join_size = 8M
max_seeks_for_key = 2M
myisam_max_sort_file_size = 1M
Dernière modification par fabricefacorat (2014-10-14 00:49:29)
Hors ligne
Bonjour
Merci de confirmer la version de Piwigo car des optimisation ont été faites en 2.7
Hors ligne
Après confirmation, les tests ont été effectués hier sur la version 2.7.1.
Il semblerait qu'en 2.6.x, on était allé jusqu'à 300 000 photos sans problèmes majeurs ( même si des crashs existaient ). Je vais voir pour refaire des tests en version 2.6.x avec 90000 photos, et aussi des tests avec une autre BD MySQL sur un serveur physique
Hors ligne
Voici le test effectué avec Piwigo 2.6.3 avec un import de l'année 2012 ( +/- 100 000 photos en total prévus à la fin) :
- avec la base vide on peut faire des imports de +/- 20 000 photos en une fois
sans plantage avec un temps de réponse d'une vingtaines de secondes
- Après environ +/- 60 000 photos importés, ça passe mais plantages réguliers => obliger de diviser par deux le nombres de photos importés ( par paquets de 10 000)
- Plus la base grossie plus il faut réduire la taille des imports et le site devient inaccessible durant un temps important
Au final le comportement observé en 2.6.3 est pratiquement le même qu'avec la version 2.7.x
Hors ligne
On note des corruptions de tables après les imports, notamment de la table piwigo_images, mais aussi des tables temporaires piwigo_images_*
cf fichier en capture d'écran.
Cela arrive même après avoir réinitialisé la base de donnée
Hors ligne
la maj lance un REPAIR de chaque table
essayez de le faire aussi sur ce stables
Hors ligne
On a fait les REPAIR, mais ensuite quand on upload moins d'images, on a le site qui reste inaccessible longtemps avec MySQL qui fait énormément de "Copying to temp table" à cause de SELECT DISTINCT/GROUP BY
Hors ligne
notre maitre mysql va passer
Hors ligne
Quelqu'un pourrait-il me donner le nom des fichiers du code source où je dois regarder lorsqu'une synchro de répertoire est faite ?
je voudrais vérifier la manière dont les INSERT sont fait ( est-ce que mass_inserts() est appelé ? ) et voir si j'améliore la situation en ajoutant des LOCK TABLE
Hors ligne
vous avez http://piwigo.org/dev/browser/trunk/adm … ad.inc.php http://piwigo.org/dev/browser/trunk/adm … direct.php etc
Hors ligne
functions_upload.inc.php ne semble géré que l'upload via un formulaire ( car d'après le commentaire add_uploaded_file() stocke l'image dans une structure de dossier précise avec prepare_directory() ).
Ce que je cherche, c'est la fonction qui sert lorsque l'on synchronise un dossier et une hiérarchie complète ( upload de plusieurs fichiers via FTP, puis -> admin -> synchronize )
Hors ligne
Bon, j'ai trouvé mon bonheur : http://piwigo.org/dev/browser/trunk/adm … update.php
J'ai regardé le code, et l'ajout est vraiment optimisé pour une vitesse maximale ... mais par contre ne semble pas résistant à des mises à jours simultanées et pourrait laisser la base dans un état inconsistent.
Corrigez moi si je me trompe :
1. vous mettez à jour les catégories à partir de l'arborescence à synchroniser ainsi que les utilisateurs et leurs permissions
2. Ensuite vous ajoutez les images
3. puis vous mettez à jour les catégories des images
A chaque fois, vous générez vous même vos id en partant du dernier id dans la base. Mais si quelqu'un ajoute une image entre le moment où vous récupérez l'id et le moment où vous faites l'INSERT en base, vous risquez un duplicate id sur la primary key ... Pour moi, entre le moment où vous faites pwg_db_nextval('id', xxxx_TABLE) et après avoir appelé mass_inserts(xxxx_TABLE,...,...), vous devriez faire un LOCK TABLES xxxx WRITE/UNLOCK TABLES pour éviter d'avoir des problèmes ...
Enfin mass_inserts() ( et mass_updates() ) prennent en compte max_allowed_packet ( 1Go par défaut ) pour ne pas envoyer un INSERT trop gros, mais ils ne prennent pas en compte bulk_insert_buffer_size ( 8Mo par défaut ) : http://dev.mysql.com/doc/refman/5.1/en/ … uffer_size
or cela pourrait expliquer les corruptions de tables et autres problèmes que l'on rencontre vu le nombre très important de photos synchronisées d'un coup. Je serait même d'avis de limiter arbitrairement le nombre de valeurs insérés à la fois à une valeur comme 100 ou 1000 ( à tester ) ( en gros par paquet de 1000 INSERT ou 1000 (val,val,val,... ) )
Hors ligne
Ha oui, et vu comment la base MySQL semble exploser face à la charge, je serai d'avis de mettre un sleep d'x seconde entre chaque vague d'INSERT.
Hors ligne
"vous" Piwigo appartient à la communauté à Pierrick, moi, vous ... du fait de votre message et donc contribution Piwigo est désormais un peu votre aussi :)
je re notifie Pierrick
Hors ligne