Optimiser la performance de MySQL avec eBPF
MySQL est l'un des systèmes de gestion de bases de données les plus utilisés au monde. Que ce soit pour une petite application ou un système d'entreprise à grande échelle, comprendre les performances de MySQL est essentiel. Identifier les requêtes lentes et analyser leur impact peut grandement améliorer l’efficacité globale du système. C'est ici qu’eBPF intervient comme un outil puissant pour tracer et analyser l’exécution des requêtes SQL.
Qu'est-ce que bpftrace ?
Bpftrace est un langage de haut niveau qui nous permet d’écrire des programmes eBPF. À la différence du C, il est beaucoup plus facile à exécuter ce qui permet un gain de temps conséquent. Pour comprendre ce qui suit, nous devons voir certaines bases. Dans le contexte de bpftrace, un probe est un point d’attache qui permet de lier du code lors de l’appel d’un évènement. Dans notre cas, lorsqu’un processus va interagir avec mysql, nous allons afficher un message grâce au probe que nous allons déployer. Un uprobe fait référence à un probe attaché à un évènement dans le noyau utilisateur qui trace l’entrée dans une fonction spécifique. Quant au uretprobe, c’est un peu le même principe sauf qu’il trace les sorties ou les retours de fonction. Les maps quant à elles sont une structure de données qui permet d’enregistrer des informations lors de l’exécution d’un programme. Les programmes exécutés par bpftrace ont généralement une extension .bt.
Tracer les requêtes MySQL avec eBPF
Nous allons exécuter un script qui permet de tracer chaque commande sql du système et d’afficher un message lorsqu’on interagit avec le système de gestion de base de données, en l’occurrence mysql.
uprobe:/usr/sbin/mysqld:dispatch_command
{
@start_times[tid] = nsecs;
printf("Commande mysql exécutée par le processus : PID %d\n", pid);
}
uretprobe:/usr/sbin/mysqld:dispatch_command
{
$start = @start_times[tid];
$delta = (nsecs - $start) / 1000000;
printf("Latence: %u ms\n", $delta);
delete(@start_times[tid]);
}
Analyse du code
D’abord, un uprobe est attaché à dispatch_command, permettant d'enregistrer l’heure de début d’une requête et d'afficher son contenu. Ensuite, un uretprobe capture l’heure de fin de la requête pour calculer sa latence. Une BPF map stocke les temps d’exécution, et chaque entrée est supprimée après usage pour éviter de surcharger la mémoire. En sauvegardant ce script sous slq.bt et en l'exécutant avec sudo bpftrace trace sql.bt
, lorsqu'on exécute une commande sql dans l'environnement de mysql, on obtient un résultat comme ceci :
Pourquoi utiliser eBPF pour MySQL ?
Contrairement aux mécanismes intégrés de MySQL comme slow_query_log, eBPF réduit la surcharge d’observation. De plus, cela facilite l’optimisation des index (filtres, jointures etc...) et des schémas(tables etc...) de base de données.
Conclusion
eBPF offre une approche non intrusive et efficace pour analyser la performance des requêtes MySQL en production. Grâce à bpftrace, il est possible de capturer et d’analyser les requêtes sans modifier MySQL.
Sources
eunomia « Using eBPF to Trace MySQL Queries - eunomia »- https://eunomia.dev/en/tutorials/40-mysql/
The New Stack «P99Conf: How eBPF Could Make Faster Database Systems - The New Stack» - https://thenewstack.io/p99conf-how-ebpf-could-make-faster-database-systems/
Commentaires