Tous les plugins WordPress ne sont pas optimisés (loin de là meme) et si vous avez un site à fort trafic ou un hébergement d’entrée de gamme, votre site WordPress peut devenir très lent, voire carrément meme planter si l’une de vos extensions est trop gourmande en écriture. On vous explique dans cet article comment identifier le fautif.
Des performances WordPress dégradées par des sauvegardes automatiques en base de donnée toutes les secondes
L’un de mes sites a un trafic d’environ 1,5 millions de pages vues par mois et malheureusement je traine encore dessus du code fait main datant de 2009. Si j’ai réussi à mettre presque tous mes bidouillages sous forme de plugins ou de fichier séparés, il n’est pas rare qu’en ouvrant un fichier je pousse un cri d’effroi en réalisant que j’avais codé une fonction avec les pieds.
Très récemment j’ai été alerté par un collègue que l’un de mes plugins déclenchait des sauvegardes en base de données toute les secondes via le hook save_post
et par ricochet des appels API vers un service externe. Seulement comment trouver le ou les fautifs de cette surcharge ?
Après quelques minutes de recherches manuelles infructueuses, je me suis dit que je gagnerais beaucoup de temps avec quelques lignes de code.
La création, la mise à jour et la suppression de meta données déclenchent le hook save_post
Comme le nombre de nouveaux articles publiés sur ce site par jour est assez modeste, la seule raison de déclencher le hook save_post
était de créer, modifier ou supprimer des meta données rangées dans la table wp_postmeta
via les fonctions update_post_meta
et delete_post_meta
Après un petit tour sur la documentation WordPress, j’ai fini par trouver les 3 actions que je pouvais hooker pour savoir exactement ce qu’il se passait en base de donnée :
added_post_meta
updated_post_meta
- et
deleted_post_meta
Etant trop feignant pour coder un vrai plugin, je me suis contenté de créer un petit fichier nommé functions-log-metadata.php
inclus depuis le fichier functions.php
de mon thème en y ajoutant via la ligne suivante :
include ('functions-log-metadata.php');
Code PHP pour logger tous les déclenchement d’écriture de meta données dans WordPress
Voici le contenu du fichier en question :
<?php
add_action( 'added_post_meta', 'creerunblog_after_post_meta_add', 10, 4 );
function creerunblog_after_post_meta_add( $meta_id, $post_id, $meta_key, $meta_value ){
cub_log_metadata( $post_id, $meta_key, $meta_value , "add");
}
add_action( 'updated_post_meta', creerunblog_after_post_meta_update', 10, 4 );
function creerunblog_after_post_meta_update( $meta_id, $post_id, $meta_key, $meta_value ){
cub_log_metadata( $post_id, $meta_key, $meta_value , "update");
}
add_action( 'deleted_post_meta', 'creerunblog_deleted_post_meta', 10, 4 );
function creerunblog_deleted_post_meta( $deleted_meta_ids, $post_id, $meta_key, $only_delete_these_meta_values ){
cub_log_metadata( $post_id, $meta_key, $meta_value , "delete");
}
Le code ci-dessus est assez simple : il déclenche une action de log en transmettant l’ID du post concerné, des méta données (le nom du champs et sa nouvelle valeur) ainsi que le type d’action déclenché (ajout, modification ou suppression).
La fonction de log est tout aussi simple :
function cub_log_metadata($post_id, $meta_key, $meta_value , $action){
$log = get_home_path() . "log_meta_data.csv";
$new_line = date("d/m/Y H:i:s").";".$post_id . ";" . get_post_type($post_id) . ";" . str_replace(";"," ",get_the_title($post_id)) . ";" . $meta_key . ";" . $meta_value . ";" . $action . "\n";
file_put_contents($log, $new_line, FILE_APPEND);
}
Toujours aussi flemmard, je n’ai pas rajouté de système de création ou controle de l’existence d’un fichier de log et je me suis contenté de créer manuellement un fichier log_meta_data.csv
à la racine de mon serveur. Pensez bien à lui donner les bons droits en écriture évidemment.
Dans ce log j’ai ajouté le titre de chaque post concerné en prenant bien soin de remplacer les ;
qui pourraient s’y glisser. En effet WordPress a la fâcheuse habitude d’y coller de temps en temps des &
et &
pour certains espaces.
Analyse du log des écritures de métadonnées
Au bout de 48 heures j’ai arrêté de logger toutes les écritures en supprimant la ligne d’insertion dans functions.php et je me suis lancé dans l’analyse du log.
250 095 écritures et 20 Mo de log ce n’est pas très rassurant !
Après un import dans Excel et la création d’un tableau croisé dynamique, j’ai identifié les 2 fautifs :
Les deux plugins qui écrivent en permanence en base sont :
- WP Post Views permet de savoir approximativement combien de fois une page a été affichée
- et Social Warfare qui est l’un des plugins les plus populaires pour installer des boutons de partages sociaux
J’ai désactivé le premier des deux plugins, responsable de plus 50% des écritures avec l’espoir de voir les performances globales du serveurs s’améliorer. A ma grand surprise … ça n’a quasiment rien changé sur mon serveur dédié d’entrée de gamme :
Coté SQL il y a un très léger gain, mais vraiment modeste :
Tout ça pour ça ! Je vais donc continuer de creuser et bricoler en dur quelque-chose de similaire avec update_option
qui a un hook et get_option
qui n’en a pas…
Si vous avez des questions ou remarques, n’hésitez pas à me les laisser dans les commentaires.