Comment détecter les scripts qui font trop d'écritures dans votre base de donnée WordPress

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 &#038; et &amp; 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 !

Comment détecter les scripts qui font trop d'écritures dans votre base de donnée WordPress

Après un import dans Excel et la création d’un tableau croisé dynamique, j’ai identifié les 2 fautifs :

Comment détecter les scripts qui font trop d'écritures dans votre base de donnée WordPress #2

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 :

Comment détecter les scripts qui font trop d'écritures dans votre base de donnée WordPress #3

Coté SQL il y a un très léger gain, mais vraiment modeste :

Comment détecter les scripts qui font trop d'écritures dans votre base de donnée WordPress #4

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.

votes
Noter cet article
S’abonner
Notifier de
guest
Commentaires
Inline Feedbacks
View all comments